From: Peter M. <pet...@ma...> - 2002-01-10 04:40:53
|
Hi, On Tuesday 08 January 2002 17:21, you wrote: > An interesting question. It would make parsing rather interesting. You = are > right that the RFC does not disallow this. Net::LDAP assumed that no > sensible person would do that (like many apps assume no sensible person > puts spacing in filenames :) Who says they are sensible (maybe they just forgot quoting/escaping ;-)) > If you can provide a schema (or subset of one) with this I will see wha= t I > can do. Of course, here it is for the single quotes and the undescores (line breaking manually done by me): attributeTypes: ( 2.16.840.1.113719.1.55.4.1.1 NAME 'newObjectSDSRights' DESC 'Standard Attribute' SYNTAX 2.16.840.1.113719.1.1.5.1.17 X-NDS_NAME 'New Object's DS Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) attributeTypes: ( 2.16.840.1.113719.1.56.4.1.1 NAME 'newObjectSFSRights' DESC 'Standard Attribute' SYNTAX 2.16.840.1.113719.1.1.5.1.15{64512} X-NDS_NAME 'New Object's FS Rights' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) attributeTypes: ( 2.16.840.1.113719.1.57.4.1.1 NAME 'setupScript' DESC 'Standard Attribute' SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 SINGLE-VAL= UE X-NDS_NAME 'Setup Script' X-NDS_NOT_SCHED_SYNC_IMMEDIATE '1' ) > > Last but not least, I have a very rough patch available that would al= low > > to parse such a schema. But I have to polish it a bitbefore I send i= t. > > Are you interested ? > Sure. Don't spend too much time polishing it before letting others test= it. > Just a correct patch is fine, it can be polished later. I warned you, it is very rough ;-) More a very dirty kludge than a patch. Its a unified diff againts perl-ldap 0.25 and atleast the part in LDAP.pm violates the RFC that defined the "vendorName" attribute in the roodDSE. The RFC vedorName must not be used to change the behaviour of applications. A better solution might be to defined a global ldap option "alternate_schema_parser". (the better parts of the code are shamelessly stolen from=20 other parts of perl-ldap ;-) --- lib/Net/LDAP.pm +++ lib/Net/LDAP.pm Wed Dec 26 20:46:03 2001 @@ -706,15 +706,18 @@ my %arg =3D @_; my $base; my $mesg; + my $vendor =3D 'unknown'; if (exists $arg{'dn'}) { $base =3D $arg{'dn'}; } else { - my $root =3D $self->root_dse( attrs =3D> ['subschemaSubentry'] ) + my $root =3D $self->root_dse( attrs =3D> ['subschemaSubentry', 'vend= orName'=20 ] ) or return undef; $base =3D $root->get_value('subschemaSubentry') || 'cn=3Dschema'; + # PM: look for attribute vendorName in rootDSE + $vendor =3D $root->get_value('vendorName') || 'unknown'; } $mesg =3D $self->search( @@ -733,9 +736,13 @@ )], ); + # PM: set Net::LDAP::schema option novellkludge if it is a Novell dire= ctory $mesg->code ? undef - : Net::LDAP::Schema->new($mesg->entry); + : (($vendor =3D~ /Novell/i) ? + Net::LDAP::Schema->new($mesg->entry, novellkludge=3D>1) : + Net::LDAP::Schema->new($mesg->entry) + ); } sub root_dse { --- lib/Net/LDAP/Schema.pm +++ lib/Net/LDAP/Schema.pm Wed Dec 26 20:59:24 2001 @@ -5,21 +5,71 @@ package Net::LDAP::Schema; use strict; -use vars qw($VERSION); +use vars qw($VERSION %schemaParams); $VERSION =3D "0.10"; +# PM: default schema parameters +%schemaParams =3D ( novellkludge =3D> 0 ); + +# +# PM: get options from argument list (stolen from Net::LDAP & simplified= ) +# +sub _options { + my %ret =3D @_; + my $once =3D 0; + for my $v (grep { /^-/ } keys %ret) { + require Carp; + $once++ or Carp::carp("deprecated use of leading - for options"); + $ret{substr($v,1)} =3D $ret{$v}; + } + + \%ret; +} + +# +# PM: get / set schema options +# +sub options +{ +my $schema =3D shift if (@_ && ref($_[0])); +my $params =3D &_options; + + if ($params) + { + while (my ($key,$value) =3D each(%$params)) + { + $schema->{params}->{$key} =3D $value if ($schema); + $schemaParams{$key} =3D $value; + } + } + + return $schema ? %{$schema->{params}} : %schemaParams; +} + + # # Get schema from the server (or read from LDIF) and parse it into # data structure +# PM: extended to accept hash of options after optional argument # sub new { my $self =3D shift; my $type =3D ref($self) || $self; my $schema =3D bless {}, $type; + my $arg =3D shift if (@_ % 2); + my $opts =3D &_options; + + # PM: set default options and optionally override them with given ones + $schema->{params} =3D { %schemaParams }; + while (my ($key,$value) =3D each(%$opts)) { + $schema->{params}->{$key} =3D $value; + } - return $schema unless @_; - return $schema->parse( shift ) ? $schema : undef; + if ($arg) { + return $schema->parse( $arg ) ? $schema : undef; + } + return $schema; } sub _error { @@ -38,7 +88,10 @@ return undef; } + # PM: save schema options before resetting schema and restore them=20 afterwards + my $params =3D $schema->{params}; %$schema =3D (); + $schema->{params} =3D $params; my $entry; if( ref $arg ) { @@ -484,6 +537,21 @@ my @tokens; pos($val) =3D 0; + if ($schema->{params}->{novellkludge}) + { + push @tokens, $+ + while $val =3D~ /\G\s*(?: + ([()]) + | + ([^"'\s()]+) + | + "(.*?)"(?=3D[\s)]) + | + '(.*?)'(?=3D[\s)]) + )\s*/xcg; + } + else + { push @tokens, $+ while $val =3D~ /\G\s*(?: ([()]) @@ -494,6 +562,7 @@ | '([^']*)' )\s*/xcg; + } die "Cannot parse [$val] ",substr($val,pos($val)) unless @tokens a= nd=20 pos($val) =3D=3D length($val); # remove () from start/end Yours Peter --=20 Peter Marschall | eMail: pet...@ma... Scheffelstra=DFe 15 | pet...@is... 97072 W=FCrzburg | Tel: 0931/14721 PGP: D7 FF 20 FE E6 6B 31 74 D1 10 88 E0 3C FE 28 35 |