Compare commits
6 Commits
8f39603f9f
...
c4d28c8a23
Author | SHA1 | Date | |
---|---|---|---|
c4d28c8a23 | |||
29c460fd4b | |||
3196b10aed | |||
f41b484dc4 | |||
855d7ae75c | |||
ffa8cdc826 |
@ -16,7 +16,6 @@ class Attribute implements \Countable, \ArrayAccess
|
||||
{
|
||||
// Attribute Name
|
||||
protected string $name;
|
||||
private int $counter = 0;
|
||||
|
||||
// Is this attribute an internal attribute
|
||||
protected(set) bool $is_internal = FALSE;
|
||||
|
@ -52,6 +52,7 @@ class Factory
|
||||
'supportedfeatures' => Schema\OID::class,
|
||||
'supportedldapversion' => Schema\Generic::class,
|
||||
'supportedsaslmechanisms' => Schema\Mechanisms::class,
|
||||
'usercertificate' => UserCertificate::class,
|
||||
'userpassword' => Password::class,
|
||||
];
|
||||
|
||||
|
52
app/Classes/LDAP/Attribute/UserCertificate.php
Normal file
52
app/Classes/LDAP/Attribute/UserCertificate.php
Normal file
@ -0,0 +1,52 @@
|
||||
<?php
|
||||
|
||||
namespace App\Classes\LDAP\Attribute;
|
||||
|
||||
use Carbon\Carbon;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
use App\Classes\LDAP\Attribute;
|
||||
use App\Traits\MD5Updates;
|
||||
|
||||
/**
|
||||
* Represents an attribute whose values is a binary user certificate
|
||||
*/
|
||||
final class UserCertificate extends Attribute
|
||||
{
|
||||
use MD5Updates;
|
||||
|
||||
private array $_object = [];
|
||||
|
||||
public function certificate(int $key=0): string
|
||||
{
|
||||
return sprintf("-----BEGIN CERTIFICATE-----\n%s\n-----END CERTIFICATE-----",
|
||||
join("\n",str_split(base64_encode(Arr::get($this->values_old,'binary.'.$key)),80))
|
||||
);
|
||||
}
|
||||
|
||||
public function cert_info(string $index,int $key=0): mixed
|
||||
{
|
||||
if (! array_key_exists($key,$this->_object))
|
||||
$this->_object[$key] = openssl_x509_parse(openssl_x509_read($this->certificate($key)));
|
||||
|
||||
|
||||
return Arr::get($this->_object[$key],$index);
|
||||
}
|
||||
|
||||
public function expires($key=0): Carbon
|
||||
{
|
||||
return Carbon::createFromTimestampUTC($this->cert_info('validTo_time_t',$key));
|
||||
}
|
||||
|
||||
public function render_item_old(string $dotkey): ?string
|
||||
{
|
||||
return join("\n",str_split(base64_encode(parent::render_item_old($dotkey)),80));
|
||||
}
|
||||
|
||||
public function subject($key=0): string
|
||||
{
|
||||
$subject = collect($this->cert_info('subject',$key))->reverse();
|
||||
|
||||
return $subject->map(fn($item,$key)=>sprintf("%s=%s",$key,$item))->join(',');
|
||||
}
|
||||
}
|
@ -236,7 +236,7 @@ class HomeController extends Controller
|
||||
$password = $o->getObject('userpassword');
|
||||
|
||||
$result = collect();
|
||||
foreach ($password as $key => $value) {
|
||||
foreach ($password->values->dot() as $key => $value) {
|
||||
$hash = $password->hash($value);
|
||||
$compare = Arr::get($request->password,$key);
|
||||
//Log::debug(sprintf('comparing [%s] with [%s] type [%s]',$value,$compare,$hash::id()),['object'=>$hash]);
|
||||
|
@ -389,7 +389,6 @@ class Entry extends Model
|
||||
fn($item)=>
|
||||
(! preg_match(sprintf('/^%s$/',self::TAG_NOTAG),$item))
|
||||
&& (! preg_match(sprintf('/^%s+$/',self::TAG_CHARS_LANG),$item))
|
||||
&& (! preg_match('/^binary$/',$item))
|
||||
)
|
||||
->count())
|
||||
)
|
||||
@ -428,9 +427,17 @@ class Entry extends Model
|
||||
*/
|
||||
public function getVisibleAttributes(?string $tag=NULL): Collection
|
||||
{
|
||||
return $this->objects
|
||||
->filter(fn($item)=>! $item->is_internal)
|
||||
->filter(fn($item)=>is_null($tag) || count($item->tagValues($tag)) > 0);
|
||||
static $cache = NULL;
|
||||
|
||||
if (is_null($cache)) {
|
||||
$ot = $this->getOtherTags();
|
||||
|
||||
$cache = $this->objects
|
||||
->filter(fn($item)=>! $item->is_internal)
|
||||
->filter(fn($item)=>is_null($tag) || $ot->has($item->name_lc) || count($item->tagValues($tag)) > 0);
|
||||
}
|
||||
|
||||
return $cache;
|
||||
}
|
||||
|
||||
public function hasAttribute(int|string $key): bool
|
||||
|
@ -7,6 +7,7 @@
|
||||
"require": {
|
||||
"ext-fileinfo": "*",
|
||||
"ext-ldap": "*",
|
||||
"ext-openssl": "*",
|
||||
"php": "^8.4",
|
||||
"directorytree/ldaprecord-laravel": "^3.0",
|
||||
"laravel/framework": "^11.9",
|
||||
|
@ -54,6 +54,7 @@
|
||||
1.3.6.1.4.1.42.2.27.8.5.1:passwordPolicyRequest
|
||||
1.3.6.1.4.1.42.2.27.9.5.2:GetEffectiveRights control::May be used to determine what operations a given user may perform on a specified entry.
|
||||
1.3.6.1.4.1.1466.101.119.1:Dynamic Directory Services Refresh Request:RFC 2589
|
||||
1.3.6.1.4.1.1466.115.121.1.25:"guide" syntax-name:RFC 4517
|
||||
1.3.6.1.4.1.1466.20036:LDAP_NOTICE_OF_DISCONNECTION
|
||||
1.3.6.1.4.1.1466.20037:Transport Layer Security Extension:RFC 2830:This operation provides for TLS establishment in an LDAP association and is defined in terms of an LDAP extended request.
|
||||
1.3.6.1.4.1.1466.29539.1:LDAP_CONTROL_ATTR_SIZELIMIT
|
||||
|
@ -17,19 +17,4 @@
|
||||
@yield('page_actions')
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('button[id=entry-edit]').on('click',function(item) {
|
||||
item.preventDefault();
|
||||
|
||||
if ($(this).hasClass('btn-dark'))
|
||||
return;
|
||||
|
||||
editmode();
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@append
|
||||
</div>
|
@ -0,0 +1,25 @@
|
||||
<!-- $o=UserCertificate::class -->
|
||||
<x-attribute.layout :edit="$edit ?? FALSE" :new="$new ?? FALSE" :o="$o" langtag="binary">
|
||||
@foreach($o->tagValuesOld('binary') as $key => $value)
|
||||
@if($edit)
|
||||
<input type="hidden" name="name={{ $o->name_lc }}[binary][]" value="{{ md5($value) }}">
|
||||
|
||||
<div class="input-group has-validation mb-3">
|
||||
<textarea class="form-control mb-1 font-monospace" rows="{{ count(explode("\n",$x=$o->certificate())) }}" style="overflow:hidden" disabled>{{ $x }}</textarea>
|
||||
|
||||
<div class="invalid-feedback pb-2">
|
||||
@if($e=$errors->get($o->name_lc.'.'.$langtag.'.'.$loop->index))
|
||||
{{ join('|',$e) }}
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
<div class="input-helper">
|
||||
@lang('Certificate Subject'): <strong>{{ $o->subject($loop->index) }}</strong><br/>
|
||||
{{ ($expire=$o->expires($loop->index))->isPast() ? __('Expired') : __('Expires') }}: <strong>{{ $expire->format(config('pla.datetime_format','Y-m-d H:i:s')) }}</strong>
|
||||
</div>
|
||||
|
||||
@else
|
||||
<span class="form-control mb-1"><pre class="m-0">{{ $o->render_item_old('binary.'.$key) }}</pre></span>
|
||||
@endif
|
||||
@endforeach
|
||||
</x-attribute.layout>
|
@ -1,16 +1,12 @@
|
||||
@use(App\Classes\LDAP\Attribute\Binary\JpegPhoto)
|
||||
@use(App\Classes\LDAP\Attribute\ObjectClass)
|
||||
@use(App\Classes\LDAP\Attribute\UserCertificate)
|
||||
@php($clone=FALSE)
|
||||
<span class="p-0 m-0">
|
||||
@if($o->is_rdn)
|
||||
<button class="btn btn-sm btn-outline-focus mt-3" disabled><i class="fas fa-fw fa-exchange"></i> @lang('Rename')</button>
|
||||
@elseif($edit && $o->can_addvalues)
|
||||
@switch(get_class($o))
|
||||
@case(JpegPhoto::class)
|
||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name_lc }}" disabled><i class="fas fa-fw fa-plus"></i> @lang('Upload JpegPhoto')</span>
|
||||
|
||||
@break
|
||||
|
||||
@case(ObjectClass::class)
|
||||
<span type="button" @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) data-bs-toggle="modal" data-bs-target="#new_objectclass-modal"><i class="fas fa-fw fa-plus"></i> @lang('Add Objectclass')</span>
|
||||
|
||||
@ -216,6 +212,36 @@
|
||||
@append
|
||||
@break
|
||||
|
||||
@case(JpegPhoto::class)
|
||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-upload" disabled><i class="fas fa-fw fa-file-arrow-up"></i> @lang('Upload JpegPhoto')</span>
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#{{ $o->name }}-upload.addable').click(function(e) {
|
||||
alert('Sorry, not implemented yet');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@append
|
||||
@break
|
||||
|
||||
@case(UserCertificate::class)
|
||||
<span @class(['btn','btn-sm','btn-outline-primary','mt-3','addable','d-none'=>(! $new)]) id="{{ $o->name }}-replace" disabled><i class="fas fa-fw fa-certificate"></i> @lang('Replace Certificate')</span>
|
||||
@section('page-scripts')
|
||||
<script type="text/javascript">
|
||||
$(document).ready(function() {
|
||||
$('#{{ $o->name }}-replace.addable').click(function(e) {
|
||||
alert('Sorry, not implemented yet');
|
||||
e.preventDefault();
|
||||
return false;
|
||||
});
|
||||
});
|
||||
</script>
|
||||
@append
|
||||
@break
|
||||
|
||||
<!-- All other attributes -->
|
||||
@default
|
||||
@php($clone=TRUE)
|
||||
|
@ -10,8 +10,6 @@
|
||||
@endsection
|
||||
|
||||
@section('main-content')
|
||||
<x-error/>
|
||||
|
||||
<div class="row">
|
||||
<div class="offset-1 col-10">
|
||||
<div class="main-card mb-3 card">
|
||||
@ -34,6 +32,7 @@
|
||||
<x-form.select
|
||||
id="objectclass"
|
||||
name="objectclass[{{ Entry::TAG_NOTAG }}][]"
|
||||
old="objectclass.{{ Entry::TAG_NOTAG }}"
|
||||
:label="__('Select a Structural ObjectClass...')"
|
||||
:options="($oc=$server->schema('objectclasses'))
|
||||
->filter(fn($item)=>$item->isStructural())
|
||||
|
@ -54,7 +54,7 @@
|
||||
|
||||
<div class="row">
|
||||
<div class="col">
|
||||
@if(($x=$o->getOtherTags())->count())
|
||||
@if(($x=$o->getOtherTags()->filter(fn($item)=>$item->diff(['binary'])->count()))->count())
|
||||
<div class="ms-4 mt-4 alert alert-danger p-2" style="max-width: 30em; font-size: 0.80em;">
|
||||
This entry has [<strong>{!! $x->flatten()->join('</strong>, <strong>') !!}</strong>] tags used by [<strong>{!! $x->keys()->join('</strong>, <strong>') !!}</strong>] that cant be managed by PLA. You can though manage those tags with an LDIF import.
|
||||
</div>
|
||||
@ -210,6 +210,15 @@
|
||||
}
|
||||
|
||||
$(document).ready(function() {
|
||||
$('button[id=entry-edit]').on('click',function(item) {
|
||||
item.preventDefault();
|
||||
|
||||
if ($(this).hasClass('btn-dark'))
|
||||
return;
|
||||
|
||||
editmode();
|
||||
});
|
||||
|
||||
$('#newattr').on('change',function(item) {
|
||||
$.ajax({
|
||||
type: 'POST',
|
||||
|
@ -7,12 +7,12 @@
|
||||
|
||||
<div class="modal-body">
|
||||
<table class="table table-bordered p-1">
|
||||
@foreach(($up=$o->getObject('userpassword'))->values as $key => $value)
|
||||
@foreach(($up=$o->getObject('userpassword'))->values->dot() as $dotkey => $value)
|
||||
<tr>
|
||||
<th>Check</th>
|
||||
<td>{{ $up->render_item_old($key) }}</td>
|
||||
<td>{{ $up->render_item_old($dotkey) }}</td>
|
||||
<td>
|
||||
<input type="password" style="width: 90%" name="password[{{$key}}]"> <i class="fas fa-fw fa-lock"></i>
|
||||
<input type="password" style="width: 90%" name="password[{{ $dotkey }}]"> <i class="fas fa-fw fa-lock"></i>
|
||||
<div class="invalid-feedback pb-2">
|
||||
@lang('Invalid Password')
|
||||
</div>
|
||||
|
@ -1,7 +1,6 @@
|
||||
|
||||
dn: cn=tech_staff,dc=example.com
|
||||
cn: tech_staff
|
||||
labeleduri: ldap:///ou=People,o=Simpsons?uid?one?(&(sn=Simpson)(|(uidNumber
|
||||
=1000)(uidNumber=1001)))
|
||||
labeleduri: ldap:///dc=example.com?uid?one?(|(cn=kerberos)(uidNumber=*))
|
||||
objectclass: nisMailAlias
|
||||
objectclass: labeledURIObject
|
||||
|
7
tests/server/openldap/schema/modify/00-config.ldif
Normal file
7
tests/server/openldap/schema/modify/00-config.ldif
Normal file
@ -0,0 +1,7 @@
|
||||
dn: olcDatabase={0}config,cn=config
|
||||
changetype: modify
|
||||
add: olcRootPW
|
||||
olcRootPW:: c2VjcmV0
|
||||
|
||||
add: olcRootDN
|
||||
olcRootDN: cn=config
|
25
tests/server/openldap/schema/modify/00-mapsize.ldif
Normal file
25
tests/server/openldap/schema/modify/00-mapsize.ldif
Normal file
@ -0,0 +1,25 @@
|
||||
dn: olcDatabase={3}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
||||
dn: olcDatabase={4}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
||||
dn: olcDatabase={5}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
||||
dn: olcDatabase={6}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
||||
dn: olcDatabase={7}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcDbMaxSize
|
||||
olcDbMaxSize: 1073741824
|
||||
|
4
tests/server/openldap/schema/modify/00-sizelimit.ldif
Normal file
4
tests/server/openldap/schema/modify/00-sizelimit.ldif
Normal file
@ -0,0 +1,4 @@
|
||||
dn: olcDatabase={4}mdb,cn=config
|
||||
changetype: modify
|
||||
add: olcSizeLimit
|
||||
olcSizeLimit: 2000
|
11
tests/server/openldap/schema/modify/40-dynlist-options.ldif
Normal file
11
tests/server/openldap/schema/modify/40-dynlist-options.ldif
Normal file
@ -0,0 +1,11 @@
|
||||
dn: olcOverlay=dynlist,olcDatabase={4}mdb,cn=config
|
||||
changetype: add
|
||||
objectClass: olcOverlayConfig
|
||||
objectClass: olcDynListConfig
|
||||
olcOverlay: dynlist
|
||||
olcDynListAttrSet: nisMailAlias labeledURI
|
||||
#olcDynListAttrSet: groupOfURLs memberURL memberOf
|
||||
#olcDynListAttrSet: groupOfURLs memberURL member+dgMemberOf
|
||||
#olcDynListAttrSet: groupOfURLs memberURL member
|
||||
#olcDynListAttrSet: groupOfURLs memberURL member
|
||||
#olcDynListAttrSet: groupOfURLs labeledURI member
|
Loading…
x
Reference in New Issue
Block a user