diff --git a/lib/Net/LDAP/Util.pm b/lib/Net/LDAP/Util.pm index 0260d1a..a8c683c 100644 --- a/lib/Net/LDAP/Util.pm +++ b/lib/Net/LDAP/Util.pm @@ -427,28 +427,32 @@ sub ldap_explode_dn($%) { return undef unless defined $dn; return [] if $dn eq ''; + my $pair = qr/\\(?:[\\"+,;<> #=]|[0-9A-F]{2})/i; + my (@dn, %rdn); while ( $dn =~ /\G(?: \s* - ([a-zA-Z][-a-zA-Z0-9]*|(?:[Oo][Ii][Dd]\.)?\d+(?:\.\d+)*) + ((?i)[A-Z][-A-Z0-9]*|(?:oid\.)?\d+(?:\.\d+)*) # attribute type \s* = - \s* - ( - (?:[^\\",=+<>\#;]*[^\\",=+<>\#;\s]|\s*\\(?:[\\ ",=+<>#;]|[0-9a-fA-F]{2}))* + [ ]* + ( # attribute value + (?:(?:[^\x00 "\#+,;<>\\\x80-\xBF]|$pair) # string + (?:(?:[^\x00"+,;<>\\]|$pair)* + (?:[^\x00 "+,;<>\\]|$pair))?)? | - \#(?:[0-9a-fA-F]{2})+ + \#(?:[0-9a-fA-F]{2})+ # hex string | - "(?:[^\\"]+|\\(?:[\\",=+<>#;]|[0-9a-fA-F]{2}))*" + "(?:[^\\"]+|$pair)*" # "-quoted string, only for v2 ) - \s* - (?:([;,+])\s*(?=\S)|$) + [ ]* + (?:([;,+])\s*(?=\S)|$) # separator )\s*/gcx) { my($type,$val,$sep) = ($1,$2,$3); - $type =~ s/^oid\.(\d+(\.\d+)*)$/$1/i; #remove leading "oid." + $type =~ s/^oid\.//i; #remove leading "oid." if ( !$opt{casefold} || $opt{casefold} eq 'upper' ) { $type = uc $type; diff --git a/t/01canon_dn.t b/t/01canon_dn.t index 1d44c99..faad379 100644 --- a/t/01canon_dn.t +++ b/t/01canon_dn.t @@ -69,7 +69,9 @@ same OU = Sales+CN =J. Smith,O= Widget Inc.,C=US same OU="Sales"+CN=J. Smith,O=Widget Inc.,C=US diff OU="Sales+CN=J. Smith",O=Widget Inc.,C=US -bad cn=J.\20Smith\+ou=Sales,O=Widget\20Inc.,C=US +ref cn=J.\20Smith\+ou=Sales,O=Widget\20Inc.,C=US + +ref cn=Clerk #1\+ou=Sales,O=Widget\20Inc.,C=US ref CN=Babs Jensen,O=Widget Inc.,C=US same cn=Babs Jensen,o=Widget Inc.,c=US