Discussion:
How to bind to AD?
(too old to reply)
David Lee Lambert
2015-06-11 21:45:23 UTC
Permalink
I know this question has been asked before, but maybe the
answers were in response to differnt details...

I'm trying to write a script that compares data in an Oracle
database with Active Directory. So, it seems like I should be
able to use DBD::Oracle and Net::LDAP, but I can't seem to get
bind() to work.

I've reduced my non-working code to the following...

#! perl -w

use Net::LDAP;
my $ad = Net::LDAP->new('ad.**org**.com', debug => 2)
or die "Couldn't connect to AD: $@, $!";
$ad->bind('**tried lots of stuff**', password => '**password**')
or die "Couldn't bind: $@, $!";

my $results = $ad->search(
filter => '(&(objectClass=user)(sAMAccountName=**userid**))');
die $results->error if $results->code;
my $count = $results->count;
print $count;

Whatever I do, I get an error like this...

000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a
successful bind must be completed on the connection., data 0, v1db1 at searchde
mo_1.pl line 13, <DATA> line 755.

So, my first question is, why does the bind() not return an error
if it didn't succeed for the purposes of a successful operation?

Second, how do I figure out what to use as the first argument
to bind()? I built a small C# program that looks up my LDAP
record and prints it out, and I can see that my CN has a comma
in it (it's in the form "Last, First M"), and I'm below two
OUs and three DCs (DC=ad,DC=**org**,DC=com)... do I have to write
that whole path as the bind DN?

Thanks if anyone can help,

--
DLL
Natxo Asenjo
2015-06-13 06:33:54 UTC
Permalink
hi,
Post by David Lee Lambert
I know this question has been asked before, but maybe the
answers were in response to differnt details...
I'm trying to write a script that compares data in an Oracle
database with Active Directory. So, it seems like I should be
able to use DBD::Oracle and Net::LDAP, but I can't seem to get
bind() to work.
I've reduced my non-working code to the following...
#! perl -w
use Net::LDAP;
my $ad = Net::LDAP->new('ad.**org**.com', debug => 2)
$ad->bind('**tried lots of stuff**', password => '**password**')
my $results = $ad->search(
filter => '(&(objectClass=user)(sAMAccountName=**userid**))');
die $results->error if $results->code;
my $count = $results->count;
print $count;
Whatever I do, I get an error like this...
000004DC: LdapErr: DSID-0C0906E8, comment: In order to perform this operation a
successful bind must be completed on the connection., data 0, v1db1 at searchde
mo_1.pl line 13, <DATA> line 755.
So, my first question is, why does the bind() not return an error
if it didn't succeed for the purposes of a successful operation?
Second, how do I figure out what to use as the first argument
to bind()? I built a small C# program that looks up my LDAP
record and prints it out, and I can see that my CN has a comma
in it (it's in the form "Last, First M"), and I'm below two
OUs and three DCs (DC=ad,DC=**org**,DC=com)... do I have to write
that whole path as the bind DN?
not necessarily. You can bind using your dn, your upn or your
netbios\samaccountname.

this is how we bind to our AD (we use tls, you can skip the start_tls step
first to test it's working without). In this case I use a upn and bind to
the global catalog port which should be faster than the normal ldap port.

my $ldapprod = Net::LDAP->new('dc01.domain.tldl') || die "$@";

my $msg_prod = $ldapprod->start_tls(
verify => 'require',
sslversion => 'tlsv1',
port => '3268',
);

$msg_prod = $ldapprod->bind(
"testuser\@domain.tld",
password => 'pwd',
version => 3,
);

Basically the same stuff in the synopsis for Net::LDAP in
http://search.cpan.org/~marschap/perl-ldap/lib/Net/LDAP.pod or using
perldoc Net::LDAP.

--
Groeten,
natxo
Chris Ridd
2015-06-13 09:47:08 UTC
Permalink
Post by David Lee Lambert
I know this question has been asked before, but maybe the
answers were in response to differnt details...
I'm trying to write a script that compares data in an Oracle
database with Active Directory. So, it seems like I should be
able to use DBD::Oracle and Net::LDAP, but I can't seem to get
bind() to work.
I've reduced my non-working code to the following...
#! perl -w
use Net::LDAP;
my $ad = Net::LDAP->new('ad.**org**.com', debug => 2)
$ad->bind('**tried lots of stuff**', password => '**password**')
I think what you’re checking here is a failure to either construct the bind operation or send the bind to the server.

But this *isn’t* the right way to check for bind failures. Binds are just another LDAP operation which returns a result, so you should check the result message like you do for search further down.

This won’t solve your underlying problem with AD, but you might get more of an idea what’s failing if you look at the bind result.

Chris
Natxo Asenjo
2015-06-13 11:30:15 UTC
Permalink
Post by David Lee Lambert
I've reduced my non-working code to the following...
#! perl -w
use Net::LDAP;
my $ad = Net::LDAP->new('ad.**org**.com', debug => 2)
$ad->bind('**tried lots of stuff**', password => '**password**')
I think what you’re checking here is a failure to either construct the
bind operation or send the bind to the server.
But this *isn’t* the right way to check for bind failures. Binds are just
another LDAP operation which returns a result, so you should check the
result message like you do for search further down.
exactly, and it turns out it is a FAQ ;-)

http://search.cpan.org/~marschap/perl-ldap-0.65/lib/Net/LDAP/FAQ.pod#How_can_I_tell_when_the_server_returns_an_error,_bind%28%29_always_returns_true
?

$mesg = $ldap->bind( $dn, password => $passwd );

if ( $mesg->code ) {
# Handle error codes here
}
This won’t solve your underlying problem with AD, but you might get more
of an idea what’s failing if you look at the bind result.
this is a FAQ as well :-):

http://search.cpan.org/~marschap/perl-ldap-0.65/lib/Net/LDAP/FAQ.pod#What_is_the_proper_format_of_the_bind_DN
?

but as I replied earlier for AD ldap there are other options which are
usually shorter.

--
Groeten,
natxo
Peter Karman
2015-06-14 00:02:10 UTC
Permalink
Post by Chris Ridd
But this *isn’t* the right way to check for bind failures. Binds are just another LDAP operation which returns a result, so you should check the result message like you do for search further down.
exactly, and it turns out it is a FAQ ;-)
http://search.cpan.org/~marschap/perl-ldap-0.65/lib/Net/LDAP/FAQ.pod#How_can_I_tell_when_the_server_returns_an_error,_bind%28%29_always_returns_true?
It is quite a common mistake though. I know the synopsis in the main doc takes care to show bind returning a $mesg, but it never does anything with it. Perhaps that’s wrong.
While I’m looking at the man page, I see references still to bigfoot.com and umich.edu! Maybe they should be replaced with something less obsolete - such as example.com.
+1

IMHO, it's a common mistake because the Net::LDAP syntax isn't consistent with
idiomatic Perl as the language has evolved. Maybe if we're updating the docs, we
could add a new interface that effectively adds something like:

$ad->try( $ad->bind('**tried lots of stuff**', password => '**password**') )
or die $ad->error;

which underneath does something effectively like:

sub try {
my $self = shift;
my $msg = shift or confess "ldap_msg required";
return 1 unless $msg->code;
$self->{__error} = join( "\n",
"Return code: " . $msg->code,
"Message: " . $msg->error_name,
" :" . $msg->error_text,
"MessageID: " . $msg->mesg_id,
"DN: " . $msg->dn,
) . "\n";
return 0;
}
--
Peter Karman . http://peknet.com/ . ***@peknet.com
Loading...