in reply to Peculiar problem with Net::LDAPS and AD LDAP

I don't have the answer, but if you have Net::LDAP parse the text filter and convert it back to text again, with something like:

$f1 = Net::LDAP::Filter->new($goodFilter); $f1->print; $f2 = Net::LDAP::Filter->new($badFilter); $f2->print;

…maybe that'll make the difference more apparent. That's what Net::LDAP is doing under the hood.

Also, error 89 (as in the resultCode value of your message object) is actually a generic param error, not necessarily a filter error, although I agree that's first place to look if you can reproduce the problems on the same searches every time.

– Aaron
Preliminary operational tests were inconclusive. (The damn thing blew up.)

Replies are listed 'Best First'.
Re^2: Peculiar problem with Net::LDAPS and AD LDAP
by desertrat (Sexton) on Feb 19, 2021 at 18:41 UTC

    Thanks for the suggestion!

    That returns an error: Can't call method "print" on an undefined value for the 'bad' GUID .

    #!/usr/bin/perl use strict; use Net::LDAP::Filter; use MIME::Base64 qw(encode_base64 decode_base64); my $goodFilter = '(objectGUID = '.decode_base64('XrfAr5bivU61wz1WCgsxW +A==').')'; my $badFilter = '(objectGUID = '.decode_base64('6CncwjzJ/Umi4iIdB88efw +==').')'; print "Good filter:\n"; my $f1 = Net::LDAP::Filter->new($goodFilter); $f1->print; print "Bad filter:\n"; my $f2 = Net::LDAP::Filter->new($badFilter); $f2->print;

    Output:

    ./filtertest.pl Good filter: (objectGUID= ^\b7\c0\af\96\e2\bdN\b5\c3=V\0a\0b1X) Bad filter: Can't call method "print" on an undefined value at ./filtertest.pl lin +e 17.

    So, a bug in Net::LDAP::Filter, I think.

      I am convinced now it's a bug, that Net::LDAP::Filter's regexes are inadvertently matching things in the binary data causing the ->new() call to fail and return undef, but I found a work-around. When I looked up the objectGUID reference at LDAPWiki the proper way to create the search term for LDAP is (objectGUID=\12\34\56\78\9a\bc\de\f1) as a kind of escaped byte code.

      When I hand-constructed a searchfilter from a 'broken' objectGUID, the search worked

      So I wrote the following bit of code to turn the binary objectGUID into a hex string matching that format and I now can properly get all the info for the extant accounts.

      sub enc_hex { my @h = split(//,unpack('H*',(shift)); my ($i, $out, $first); foreach $i(@h) {if (!$first){$out.="\\$i"; $first=1;} else {$o +ut.=$i;$first='';}} return $out; }

      Plugging that into my actual module that gets a sAMAccountName from a stored uuencoded objectGUID worked.

      There is probably some Perl Master way to write this as a one-liner, but I'll be able to look at this three years from now and understand what I'm doing, so it'll do!

      Thanks again for the help!

        Assuming that you need to change 'ABCD' into '\AB\CD', there should be an easier way:

        sub enc_hex { my $out = unpack('H*', (shift)); $out =~ s/\G(..)/\\$1/g; return $out; }

        This uses the regex engine to advance through the string two characters at a time, inserting backslashes before each pair in the output. See perlre and perlop for more details.