Server IP : 103.119.228.120 / Your IP : 3.135.193.193 Web Server : Apache System : Linux v8.techscape8.com 3.10.0-1160.119.1.el7.tuxcare.els2.x86_64 #1 SMP Mon Jul 15 12:09:18 UTC 2024 x86_64 User : nobody ( 99) PHP Version : 5.6.40 Disable Function : shell_exec,symlink,system,exec,proc_get_status,proc_nice,proc_terminate,define_syslog_variables,syslog,openlog,closelog,escapeshellcmd,passthru,ocinum cols,ini_alter,leak,listen,chgrp,apache_note,apache_setenv,debugger_on,debugger_off,ftp_exec,dl,dll,myshellexec,proc_open,socket_bind,proc_close,escapeshellarg,parse_ini_filepopen,fpassthru,exec,passthru,escapeshellarg,escapeshellcmd,proc_close,proc_open,ini_alter,popen,show_source,proc_nice,proc_terminate,proc_get_status,proc_close,pfsockopen,leak,apache_child_terminate,posix_kill,posix_mkfifo,posix_setpgid,posix_setsid,posix_setuid,dl,symlink,shell_exec,system,dl,passthru,escapeshellarg,escapeshellcmd,myshellexec,c99_buff_prepare,c99_sess_put,fpassthru,getdisfunc,fx29exec,fx29exec2,is_windows,disp_freespace,fx29sh_getupdate,fx29_buff_prepare,fx29_sess_put,fx29shexit,fx29fsearch,fx29ftpbrutecheck,fx29sh_tools,fx29sh_about,milw0rm,imagez,sh_name,myshellexec,checkproxyhost,dosyayicek,c99_buff_prepare,c99_sess_put,c99getsource,c99sh_getupdate,c99fsearch,c99shexit,view_perms,posix_getpwuid,posix_getgrgid,posix_kill,parse_perms,parsesort,view_perms_color,set_encoder_input,ls_setcheckboxall,ls_reverse_all,rsg_read,rsg_glob,selfURL,dispsecinfo,unix2DosTime,addFile,system,get_users,view_size,DirFiles,DirFilesWide,DirPrintHTMLHeaders,GetFilesTotal,GetTitles,GetTimeTotal,GetMatchesCount,GetFileMatchesCount,GetResultFiles,fs_copy_dir,fs_copy_obj,fs_move_dir,fs_move_obj,fs_rmdir,SearchText,getmicrotime MySQL : ON | cURL : ON | WGET : ON | Perl : ON | Python : ON | Sudo : ON | Pkexec : ON Directory : /usr/local/ssl/local/ssl/local/ssl/local/ssl/local/ssl/local/share/perl5/Net/LDAP/ |
Upload File : |
# Copyright (c) 1998-2004 Graham Barr <gbarr@pobox.com>. All rights reserved. # This program is free software; you can redistribute it and/or # modify it under the same terms as Perl itself. package Net::LDAP::Schema; use strict; our $VERSION = '0.9908'; # # Get schema from the server (or read from LDIF) and parse it into # data structure # sub new { my $self = shift; my $type = ref($self) || $self; my $schema = bless {}, $type; @_ ? $schema->parse(@_) : $schema; } sub _error { my $self = shift; $self->{error} = shift; return; } sub parse { my $schema = shift; my $arg = shift; unless (defined($arg)) { $schema->_error('Bad argument'); return undef; } %$schema = (); my $entry; if ( ref $arg ) { if (eval { $arg->isa('Net::LDAP::Entry') }) { $entry = $arg; } elsif (eval { $arg->isa('Net::LDAP::Search') }) { unless ($entry = $arg->entry) { $schema->_error('Bad Argument'); return undef; } } else { $schema->_error('Bad Argument'); return undef; } } elsif ( -f $arg ) { require Net::LDAP::LDIF; my $ldif = Net::LDAP::LDIF->new( $arg, 'r' ); $entry = $ldif->read(); unless ( $entry ) { $schema->_error("Cannot parse LDIF from file [$arg]"); return undef; } } else { $schema->_error("Can't load schema from [$arg]: $!"); return undef; } eval { local $SIG{__DIE__} = sub {}; _parse_schema( $schema, $entry ); }; if ($@) { $schema->_error($@); return undef; } return $schema; } # # Dump as LDIF # # XXX - We should really dump from the internal structure. That way we can # have methods to modify the schema and write a new one -- GMB sub dump { my $self = shift; my $fh = @_ ? shift : \*STDOUT; my $entry = $self->{entry} or return; require Net::LDAP::LDIF; Net::LDAP::LDIF->new($fh, 'w', wrap => 0)->write($entry); 1; } # # Given another Net::LDAP::Schema, merge the contents together. # XXX - todo # sub merge { my $self = shift; my $new = shift; # Go through structure of 'new', copying code to $self. Take some # parameters describing what to do in the event of a clash. } sub all_attributes { values %{shift->{at}} } sub all_objectclasses { values %{shift->{oc}} } sub all_syntaxes { values %{shift->{syn}} } sub all_matchingrules { values %{shift->{mr}} } sub all_matchingruleuses { values %{shift->{mru}} } sub all_ditstructurerules { values %{shift->{dts}} } sub all_ditcontentrules { values %{shift->{dtc}} } sub all_nameforms { values %{shift->{nfm}} } sub superclass { my $self = shift; my $oc = shift; my $elem = $self->objectclass( $oc ) or return scalar _error($self, 'Not an objectClass'); return @{$elem->{sup} || []}; } sub must { _must_or_may(@_, 'must') } sub may { _must_or_may(@_, 'may') } # # Return must or may attributes for this OC. # sub _must_or_may { my $self = shift; my $must_or_may = pop; my @oc = @_ or return; # # If called with an entry, get the OC names and continue # if (eval { $oc[0]->isa('Net::LDAP::Entry') }) { my $entry = $oc[0]; @oc = $entry->get_value( 'objectclass' ) or return; } my %res; my %done; while (@oc) { my $oc = shift @oc; $done{lc $oc}++ and next; my $elem = $self->objectclass( $oc ) or next; if (my $res = $elem->{$must_or_may}) { @res{ @$res } = (); # Add in, getting uniqueness } my $sup = $elem->{sup} or next; push @oc, @$sup; } my %unique = map { ($_, $_) } $self->attribute(keys %res); values %unique; } # # Given name or oid, return element or undef if not of appropriate type # sub _get { my $self = shift; my $type = pop(@_); my $hash = $self->{$type}; my $oid = $self->{oid}; my @elem = grep $_, map { my $elem = $hash->{lc $_}; ($elem or ($elem = $oid->{$_} and $elem->{type} eq $type)) ? $elem : undef; } @_; wantarray ? @elem : $elem[0]; } sub attribute { _get(@_, 'at') } sub objectclass { _get(@_, 'oc') } sub syntax { _get(@_, 'syn') } sub matchingrule { _get(@_, 'mr') } sub matchingruleuse { _get(@_, 'mru') } sub ditstructurerule { _get(@_, 'dts') } sub ditcontentrule { _get(@_, 'dtc') } sub nameform { _get(@_, 'nfm') } # # XXX - TODO - move long comments to POD and write up interface # # Data structure is: # # $schema (hash ref) # # The {oid} piece here is a little redundant since we control the other # top-level members. We promote the first listed name to be 'canonical' and # also make up a name for syntaxes (from the description). Thus we always # have a unique name. This avoids a lot of checking in the access routines. # # ->{oid}->{$oid}->{ # name => $canonical_name, (created for syn) # aliases => list of non. canon names # type => at/oc/syn # desc => description # must => list of can. names of mand. atts [if OC] # may => list of can. names of opt. atts [if OC] # syntax => can. name of syntax [if AT] # ... etc per oid details # # These next items are optimisations, to avoid always searching the OID # lists. Could be removed in theory. Each is a hash ref mapping # lowercase names to the hash stored in the oid structure # # ->{at} # ->{oc} # ->{syn} # ->{mr} # ->{mru} # ->{dts} # ->{dtc} # ->{nfm} # # # These items have no following arguments # my %flags = map { ($_, 1) } qw( single-value obsolete collective no-user-modification abstract structural auxiliary ); my %xat_flags = map { ($_, 1) } qw(indexed system-only); # # These items can have lists arguments # (name can too, but we treat it special) # my %listops = map { ($_, 1) } qw(must may sup); # # Map schema attribute names to internal names # my %type2attr = qw( at attributetypes xat extendedAttributeInfo oc objectclasses syn ldapsyntaxes mr matchingrules mru matchingruleuse dts ditstructurerules dtc ditcontentrules nfm nameforms ); # # Return ref to hash containing schema data - undef on failure # sub _parse_schema { my $schema = shift; my $entry = shift; return undef unless defined($entry); keys %type2attr; # reset iterator while (my($type, $attr) = each %type2attr) { my $vals = $entry->get_value($attr, asref => 1); my %names; $schema->{$type} = \%names; # Save reference to hash of names => element next unless $vals; # Just leave empty ref if nothing foreach my $val (@$vals) { # # The following statement takes care of defined attributes # that have no data associated with them. # next if $val eq ''; # # We assume that each value can be turned into an OID, a canonical # name and a 'schema_entry' which is a hash ref containing the items # present in the value. # my %schema_entry = ( type => $type, aliases => [] ); my @tokens; pos($val) = 0; push @tokens, $+ while $val =~ /\G\s*(?: ([()]) | ([^"'\s()]+) | "([^"]*)" | '((?:[^']+|'[^\s)])*)' )\s*/xcg; die "Cannot parse [$val] [", substr($val, pos($val)), "]" unless @tokens and pos($val) == length($val); # remove () from start/end shift @tokens if $tokens[0] eq '('; pop @tokens if $tokens[-1] eq ')'; # The first token is the OID my $oid = $schema_entry{oid} = shift @tokens; my $flags = ($type eq 'xat') ? \%xat_flags : \%flags; while (@tokens) { my $tag = lc shift @tokens; if (exists $flags->{$tag}) { $schema_entry{$tag} = 1; } elsif (@tokens) { if (($schema_entry{$tag} = shift @tokens) eq '(') { my @arr; $schema_entry{$tag} = \@arr; while (1) { my $tmp = shift @tokens; last if $tmp eq ')'; push @arr, $tmp unless $tmp eq '$'; # Drop of end of list ? die "Cannot parse [$val] {$tag}" unless @tokens; } } # Ensure items that can be lists are stored as array refs $schema_entry{$tag} = [ $schema_entry{$tag} ] if exists $listops{$tag} and !ref $schema_entry{$tag}; } else { die "Cannot parse [$val] {$tag}"; } } # # Extract the maximum length of a syntax # $schema_entry{max_length} = $1 if exists $schema_entry{syntax} and $schema_entry{syntax} =~ s/{(\d+)}//; # # Force a name if we don't have one # $schema_entry{name} = $schema_entry{oid} unless exists $schema_entry{name}; # # If we have multiple names, make the name be the first and demote the rest to aliases # if (ref $schema_entry{name}) { my $aliases; $schema_entry{name} = shift @{$aliases = $schema_entry{name}}; $schema_entry{aliases} = $aliases if @$aliases; } # # Store the elements by OID # $schema->{oid}->{$oid} = \%schema_entry unless $type eq 'xat'; # # We also index elements by name within each type # foreach my $name ( @{$schema_entry{aliases}}, $schema_entry{name} ) { my $lc_name = lc $name; $names{lc $name} = \%schema_entry; } } } # place extendedAttributeInfo into attribute types if (my $xat = $schema->{xat}) { foreach my $xat_ref (values %$xat) { my $oid = $schema->{oid}{$xat_ref->{oid}} ||= {}; while (my($k, $v) = each %$xat_ref) { $oid->{"x-$k"} = $v unless $k =~ /^(oid|type|name|aliases)$/; } } } $schema->{entry} = $entry; return $schema; } # # Get the syntax of an attribute # sub attribute_syntax { my $self = shift; my $attr = shift; my $syntax; while ($attr) { my $elem = $self->attribute( $attr ) or return undef; $syntax = $elem->{syntax} and return $self->syntax($syntax); $attr = ${$elem->{sup} || []}[0]; } return undef; } sub error { $_[0]->{error}; } # # Return base entry # sub entry { $_[0]->{entry}; } sub matchingrule_for_attribute { my $self = shift; my $attr = shift; my $matchtype = shift; my $attrtype = $self->attribute( $attr ); if (exists $attrtype->{$matchtype}) { return $attrtype->{$matchtype}; } elsif (exists $attrtype->{sup}) { # the assumption is that all superiors result in the same ruleset return $self->matchingrule_for_attribute( $attrtype->{sup}[0], $matchtype); } return undef; } 1;