desertrat has asked for the wisdom of the Perl Monks concerning the following question:
I have a set of scripts to maintain a match table in a database between our local AD domain and an external (non-AD) directory. Net::LDAPS works great for this...when I use sAMAccountName as the search attribute. but since we routinely have people change that (and the match table is only populated whenpeople are onboarded) I need to use permanent unique identifiers. For AD this is objectGUID.
For most of the accounts in our Active Directory this works well, I save a base64 encoded copy of the binary objectGUID in the database and I can retrieve the details for the user regardless of any changes in the AD record. for most users this works both ways...I can retrieve the objectGUID using the sAMAccountName, then use that retrieved objectGUID to retrieve the sAMAccount name back.
for about 10% of the 700 accounts in this system, though, using objectGUID results in a 'Bad filter' error from the AD LDAP server. The code associated with it is param_error code 89
This has to be an error in the data side of the filter expression, since the filter statement is the same for both working and non-working accounts. There seems to be no pattern to the accounts that fail; I only really noticed this when I started trying to do some sweeps of the data to better ID changes in users (ie find people who are no longer in one or the other of the two directories.
I guess I'm asking has anyone ever run into this and how did you fix it? I cannot find any error in my code because it works, most of the time.
The following is a code template that I've used to test this:
#!/usr/bin/perl use strict; use Net::LDAPS; use Data::Dumper; my $ldu ='ldapquery'; my $ldp ='nottherealpassword'; my $unamein = 'johnson'; my $attr = ['objectGUID', 'sAMAccountName', 'employeeNumber', 'mail']; my $ldaps = Net::LDAPS->new("ldaps://host.domain") or return "FAIL LDA +P ERROR $0"; my $searchBase = "DC=host,DC=domain"; # Bind as AD user my $mesg1 = $ldaps->bind("$ldu\@host.domain", password=>$ldp); $mesg1->code && die "Authentication failed: " . $mesg1->error . "\n"; my $searchFilter = "(sAMAccountName=$unamein)"; $mesg1 = $ldaps->search ( # perform a search base => $searchBase, filter => $searchFilter, attrs => $attr ); $mesg1->code; print Dumper $mesg1; my $binguid= $mesg1->entry(0)->get_value('objectGUID'); $searchFilter = "(objectGUID=$binguid)"; $mesg1 = $ldaps->search ( # perform a search base => $searchBase, filter => $searchFilter, attrs => $attr ); $mesg1->code; print Dumper $mesg1; exit;
Running this for a user that works produces the following expected results:
LDAP query filter on sAMAccountName: ----------------------------------------------------- $VAR1 = bless( { 'reference' => [ 'ldaps://host.domain/CN=Configuratio +n,DC=Host,DC.Domain' ], 'errorMessage' => '', 'raw' => undef, 'parent' => bless( { 'net_ldap_scheme' => 'ldaps', 'net_ldap_refcnt' => 1, 'net_ldap_debug' => 0, 'net_ldap_host' => 'host.domain' +, 'net_ldap_rawsocket' => bless( \ +*Symbol::GEN2, 'IO::Socket::SSL' ), 'net_ldap_resp' => {}, 'net_ldap_uri' => 'ldaps://host. +domain', 'net_ldap_socket' => $VAR1->{'pa +rent'}{'net_ldap_rawsocket'}, 'net_ldap_async' => 0, 'net_ldap_mesg' => {}, 'net_ldap_port' => 636, 'net_ldap_version' => 3 }, 'Net::LDAPS' ), 'mesgid' => 6, 'ctrl_hash' => undef, 'entries' => [ bless( { 'asn' => { 'attributes' => [ +{ + 'vals' => [ + '06007454' + ], + 'type' => 'employeeNumber' +}, +{ + 'type' => 'objectGUID', + 'vals' => [ + 'T,.\\@?Ǔi2#FI' + ] +}, +{ + 'type' => 'sAMAccountName', + 'vals' => [ + 'johnson' + ] +}, +{ + 'vals' => [ + 'johnson@host.domain' + ], + 'type' => 'mail' +} ], 'objectName' => 'C +N=johnson,OU=ITStaff,OU=UA,OU=PharmAccounts,DC=Host,DC.Domain' }, 'changetype' => 'modify', 'changes' => [] }, 'Net::LDAP::Entry' ) ], 'controls' => undef, 'resultCode' => 0, 'matchedDN' => '', 'callback' => undef }, 'Net::LDAP::Search' ); LDAP query filter on objectGUID from previous query: ----------------------------------------------------- $VAR1 = bless( { 'entries' => [ bless( { 'changes' => [], 'changetype' => 'modify', 'asn' => { 'objectName' => 'C +N=johnson,OU=ITStaff,DC=Host,DC.Domain', 'attributes' => [ +{ + 'type' => 'employeeNumber', + 'vals' => [ + '06007454' + ] +}, +{ + 'vals' => [ + 'T,.\\@?Ǔi2#FI' + ], + 'type' => 'objectGUID' +}, +{ + 'vals' => [ + 'johnson' + ], + 'type' => 'sAMAccountName' +}, +{ + 'type' => 'mail', + 'vals' => [ + 'johnson@host.domain' + ] +} ] } }, 'Net::LDAP::Entry' ) ], 'controls' => undef, 'matchedDN' => '', 'callback' => undef, 'resultCode' => 0, 'reference' => [ 'ldaps://host.domain/CN=Configuratio +n,DC=Host,DC.Domain' ], 'parent' => bless( { 'net_ldap_scheme' => 'ldaps', 'net_ldap_refcnt' => 1, 'net_ldap_debug' => 0, 'net_ldap_host' => 'host.domain' +, 'net_ldap_rawsocket' => bless( \ +*Symbol::GEN2, 'IO::Socket::SSL' ), 'net_ldap_resp' => {}, 'net_ldap_uri' => 'ldaps://host. +domain', 'net_ldap_socket' => $VAR1->{'pa +rent'}{'net_ldap_rawsocket'}, 'net_ldap_async' => 0, 'net_ldap_mesg' => {}, 'net_ldap_port' => 636, 'net_ldap_version' => 3 }, 'Net::LDAPS' ), 'raw' => undef, 'errorMessage' => '', 'mesgid' => 7, 'ctrl_hash' => undef }, 'Net::LDAP::Search' );
Running this for a user that it does not work for results in the following for the second query; the first works as expected:
LDAP query filter on objectGUID from previous query: ----------------------------------------------------- $VAR1 = bless( { 'parent' => bless( { 'net_ldap_resp' => {}, 'net_ldap_host' => 'host.domain' +, 'net_ldap_version' => 3, 'net_ldap_rawsocket' => bless( \ +*Symbol::GEN2, 'IO::Socket::SSL' ), 'net_ldap_scheme' => 'ldaps', 'net_ldap_socket' => $VAR1->{'pa +rent'}{'net_ldap_rawsocket'}, 'net_ldap_refcnt' => 1, 'net_ldap_debug' => 0, 'net_ldap_uri' => 'host.domain', 'net_ldap_async' => 0, 'net_ldap_port' => 636, 'net_ldap_mesg' => {} }, 'Net::LDAPS' ), 'errorMessage' => 'Bad filter', 'resultCode' => 89, 'mesgid' => 7, 'raw' => undef, 'callback' => undef }, 'Net::LDAP::Search'
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Peculiar problem with Net::LDAPS and AD LDAP
by Radiola (Monk) on Feb 19, 2021 at 17:59 UTC | |
by desertrat (Sexton) on Feb 19, 2021 at 18:41 UTC | |
by desertrat (Sexton) on Feb 19, 2021 at 22:37 UTC | |
by jcb (Parson) on Feb 21, 2021 at 04:32 UTC |