Hi Graham, hi list,
here are a few patches for perl-ldap 0.31
Three of them fix a few glitches / omissions in perl-ldap 031
* perl-ldap-0.31-LDIF.pod.patch
- fix indenting in net::LDAP::LDIF.pod
- document a few options more
* perl-ldap-0.31-ldapsearch.patch
- make ldapsearch work again with option -L
- let Net::LDAP do the conversion of parameters to option -s
* perl-ldap-0.31supportedFeatures.patch
- add the attribute supportedFeatures to the default list of
attributes for the root_dse() method in Net::LDAP
- add method supported_feature() to Net::LDAP::RootDSE
Both changes allow to query a server that are advertised using
the supportedFeatures attribute (e.g. support for + to get all
operational attributes).
At least two LDPA server (OpenLDAP and Novell eDirectory)
support the supportedFeature attribute in the root DSE.
The remaining two add more features
* perl-ldap-0.31-sortLDIF.patch
- add option sort to the constructor of Net::LDAP::LDIF
to allow sorting of attribute names in entries so that
objectclass gets sorted before all other attributes and
the other attributes get sorted alphabetically.
IIRC having objectclass sorted first in an LDIF entry
is something everybody suggests as being the "most"
standards compliant form of an LDIF entry
And having the other attributes sorted alphabetically
minimizes the length of diffs and makes manual comparison
easier.
* perl-ldap-0.31-Util.patch
- add functions to escape / unescape strings to be used
in string represantations of ldap filters (RFC2254).
- add functions to escape / unescape strings to be used in
DN values (RFC 2252).
Although these functions are quite trivial I think they
should be part of the standard perl-ldap package.
Otherwise everybody would be forced to reinvent
the wheel himself.
Escpecially the function to escape a value to be used in a DN
allows creating DNs by concatenating strings.
(no need to set up a DN structure for canonical_dn() ;-))
I hope you find these patches as useful as I do and
I am looking forward to seeing them in the CVS and/or
the next release of perl-ldap.
Yours
Peter
--
Peter Marschall
eMail: [EMAIL PROTECTED]
# patch to fix indenting / extend documentation
# created by Peter Marschall <[EMAIL PROTECTED]>
--- lib/Net/LDAP/LDIF.pod
+++ lib/Net/LDAP/LDIF.pod Mon Jan 12 18:14:16 2004
@@ -87,11 +87,17 @@
C<Net::LDAP::LDIF> will warn with an appropriate message if C<-w> is
in effect. The method that was called will return C<undef>.
+=back
+
=item change =E<gt> 1
Write entry changes to the LDIF file instead of the entries itself.
I.e. write LDAP operations acting on the entries to the file instead of the entries contents.
+=item lowercase =E<gt> 1
+
+Convert attribute names to lowercase when writing.
+
=item version =E<gt> '1'
Set the LDIF version to write to the resulting LDIF file.
@@ -100,13 +106,13 @@
The default is I<undef> meaning no version information is written to the LDIF file.
-=back
+=item wrap =E<gt> 78
-=back
+Number of columns where output line wrapping shall occur.
-=item change =E<gt> 1
+Default is 78. Setting it to 40 or lower inhibits wrapping.
-Write out LDIF change records instead of plain entries.
+=back
=back
# patch to have (un)escaping functions for filter and DN values
# created by Peter Marschall <[EMAIL PROTECTED]>
--- lib/Net/LDAP/Util.pm 2003-05-20 17:03:15.000000000 +0200
+++ lib/Net/LDAP/Util.pm 2004-01-14 16:13:15.000000000 +0100
@@ -41,7 +41,20 @@
ldap_error_desc
canonical_dn
ldap_explode_dn
+ escape_filter_value
+ unescape_filter_value
+ escape_dn_value
+ unescape_dn_value
);
+%EXPORT_TAGS = (
+ error => [ qw(ldap_error_name ldap_error_text ldap_error_desc) ],
+ filter => [ qw(escape_filter_value unescape_filter_value) ],
+ dn => [ qw(canonical_dn ldap_explode_dn
+ escape_dn_value unescape_dn_value) ],
+ escape => [ qw(escape_filter_value unescape_filter_value
+ escape_dn_value unescape_dn_value) ],
+);
+
$VERSION = "0.10";
=item ldap_error_name ( ERR )
@@ -397,14 +410,14 @@
Do not change attribute type names.
+=back
+
=item reverse
If TRUE, the RDN sequence is reversed.
=back
-=back
-
=cut
sub ldap_explode_dn($%) {
@@ -472,8 +485,119 @@
}
+=item escape_filter_value ( VALUES )
+
+Escapes the given B<VALUES> according to RFC 2254 so that they
+can be safely used in LDAP filters.
+
+Any control characters with an ACII code E<lt> 32 as well as the
+characters with special meaning in LDAP filters "*", "(", ")",
+and "\" the backslash are converted into the representation
+of a backslash followed by two hex digits representing the
+hexadecimal value of the character.
+
+Returns the converted list in list mode and the first element
+in scalar mode.
+
+=cut
+
+## convert a list of values into its LDAP filter encoding ##
+# Synopsis: @escaped = escape_filter_value(@values)
+sub escape_filter_value(@)
+{
+my @values = @_;
+
+ map { $_ =~ s/([\x00-\x1F\*\(\)\\])/"\\".unpack("H2",$1)/oge; } @values;
+
+ return(wantarray ? @values : $values[0]);
+}
+
+
+=item unescape_filter_value ( VALUES )
+
+Undoes the conversion done by B<escape_filter_value()>.
+
+Converts any sequences of a backslash followed by two hex digits
+into the corresponding character.
+
+Returns the converted list in list mode and the first element
+in scalar mode.
+
+=cut
+
+## convert a list of values from its LDAP filter encoding ##
+# Synopsis: @values = unescape_filter_value(@escaped)
+sub unescape_filter_value(@)
+{
+my @values = @_;
+
+ map { $_ =~ s/\\([0-9a-fA-F]{2})/pack("H2",$1)/oge; } @values;
+
+ return(wantarray ? @values : $values[0]);
+}
+
+
+=item escape_dn_value ( VALUES )
+
+Escapes the given B<VALUES> according to RFC 2253 so that they
+can be safely used in LDAP DNs.
+
+The characters ",", "+", """, "\", "E<lt>", "E<gt>", ";", "#", "="
+with a special meaning in RFC 2252 are preceeded by ba backslash.
+Control characters with an ASCII code E<lt> 32 are represented
+as \hexpair.
+Finally all leading and trailing spaces are converted to
+sequences of \20.
+
+Returns the converted list in list mode and the first element
+in scalar mode.
+
+=cut
+
+## convert a list of values into its DN encoding ##
+# Synopsis: @escaped = escape_dn_value(@values)
+sub escape_dn_value(@)
+{
+my @values = @_;
+
+ map { $_ =~ s/([\\",=+<>#;])/\\$1/og;
+ $_ =~ s/([\x00-\x1F])/"\\".unpack("H2",$1)/oge;
+ $_ =~ s/(^\s+|\s+$)/"\\20" x length($1)/oge; } @values;
+
+ return(wantarray ? @values : $values[0]);
+}
+
+
+=item unescape_dn_value ( VALUES )
+
+Undoes the conversion done by B<escape_dn_value()>.
+
+Any escape sequence starting with a baskslash - hexpair or
+special character - will be transformed back to the
+corresponding character.
+
+Returns the converted list in list mode and the first element
+in scalar mode.
+
+=cut
+
+## convert a list of values from its LDAP filter encoding ##
+# Synopsis: @values = unescape_dn_value(@escaped)
+sub unescape_dn_value($)
+{
+my @values = @_;
+
+ map { $_ =~ s/\\([\\",=+<>#;]|[0-9a-fA-F]{2})
+ /(length($1)==1) ? $1 : pack("H2",$1)
+ /ogex; } @values;
+
+ return(wantarray ? @values : $values[0]);
+}
+
+
=back
+
=head1 AUTHOR
Graham Barr E<lt>[EMAIL PROTECTED]<gt>
# make make root DSE aware of the supportedFeatures attribute
# when no attributes are given
# created by Peter Marschall <[EMAIL PROTECTED]>
--- lib/Net/LDAP.pm
+++ lib/Net/LDAP.pm 2004-01-07 10:06:52.000000000 +0100
@@ -889,6 +889,7 @@
altServer
supportedExtension
supportedControl
+ supportedFeatures
supportedSASLMechanisms
supportedLDAPVersion
)];
--- lib/Net/LDAP/RootDSE.pm
+++ lib/Net/LDAP/RootDSE.pm 2004-01-07 10:09:16.000000000 +0100
@@ -12,6 +12,7 @@
use strict;
+sub supported_feature { _supported_feature( @_, 'supportedFeatures' ) }
sub supported_extension { _supported_feature( @_, 'supportedExtension' ) }
sub supported_version { _supported_feature( @_, 'supportedLDAPVersion' ) }
sub supported_control { _supported_feature( @_, 'supportedControl' ) }
@@ -59,6 +60,11 @@
Returns true if the server supports all of the specified
extension OIDs
+=item supported_feature ( OID_LIST )
+
+Returns true if the server supports all of the specified
+feature OIDs
+
=item supported_version ( VERSION_LIST )
Returns true if the server supports all of the specified
# patch to fix ldapsearch
# created by Peter Marschall <[EMAIL PROTECTED]>
--- bin/ldapsearch
+++ bin/ldapsearch Mon Jan 12 19:07:29 2004
@@ -137,7 +137,7 @@
my @urls = ($initial->as_string);
-my $ldif = Net::LDAP::LDIF->new if $opt_L;
+my $ldif = Net::LDAP::LDIF->new('-', 'w') if $opt_L;
my $first_record = 1;
while (@urls) {
@@ -186,7 +186,6 @@
$searchargs{base} = $url->dn if $url->dn;
$searchargs{scope} = $opt_s if $opt_s;
$searchargs{scope} = $url->_scope if defined $url->_scope;
- $searchargs{scope} = $scopes{$searchargs{scope}} if $searchargs{scope};
$searchargs{deref} = $derefs{$opt_a} if $opt_a;
$searchargs{sizelimit} = $opt_z if $opt_z;
$searchargs{timelimit} = $opt_l if $opt_l;
# new option sort => 1 for Net::LDAP::LDIF to sort attribute names
# created by Peter Marschall <[EMAIL PROTECTED]>
--- lib/Net/LDAP/LDIF.pm
+++ lib/Net/LDAP/LDIF.pm 2004-01-10 18:42:01.000000000 +0100
@@ -52,6 +52,7 @@
$opt{'lowercase'} ||= 0;
$opt{'change'} ||= 0;
+ $opt{'sort'} ||= 0;
my $self = {
changetype => "modify",
@@ -305,10 +306,18 @@
}
}
+# helper function to compare attribute names (sort objectClass first)
+sub _cmpAttrs {
+ ($a =~ /^objectclass$/io)
+ ? -1 : (($b =~ /^objectclass$/io) ? 1 : ($a cmp $b));
+}
+
sub _write_attrs {
- my($entry,$wrap,$lower) = @_;
+ my($entry,$wrap,$lower,$sort) = @_;
+ my @attributes = $entry->attributes();
my $attr;
- foreach $attr ($entry->attributes) {
+ @attributes = sort _cmpAttrs @attributes if ($sort);
+ foreach $attr (@attributes) {
my $val = $entry->get_value($attr, asref => 1);
_write_attr($attr,$val,$wrap,$lower);
}
@@ -350,6 +359,7 @@
my $change = $self->{change};
my $wrap = int($self->{'wrap'});
my $lower = $self->{'lowercase'};
+ my $sort = $self->{'sort'};
local($\,$,); # output field and record separators
unless ($self->{'fh'}) {
@@ -386,7 +396,7 @@
next;
}
elsif ($type eq 'add') {
- _write_attrs($entry,$wrap,$lower);
+ _write_attrs($entry,$wrap,$lower,$sort);
next;
}
elsif ($type =~ /modr?dn/o) {
@@ -423,7 +433,7 @@
print "version: $self->{version}\n\n" if defined $self->{version};
}
_write_dn($entry->dn,$self->{'encode'},$wrap);
- _write_attrs($entry,$wrap,$lower);
+ _write_attrs($entry,$wrap,$lower,$sort);
}
}
--- lib/Net/LDAP/LDIF.pod
+++ LDIF.pod Mon Jan 12 18:18:01 2004
@@ -98,6 +98,11 @@
Convert attribute names to lowercase when writing.
+=item sort =E<gt> 1
+
+Sort attribute names when writing entries according to the rule:
+objectclass first then all other attributes alphabetically sorted
+
=item version =E<gt> '1'
Set the LDIF version to write to the resulting LDIF file.