How to bind to AD?

19 views
Skip to first unread message

David Lee Lambert

unread,
Jun 12, 2015, 8:30:01 PM6/12/15
to perl...@perl.org
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

unread,
Jun 13, 2015, 2:45:02 AM6/13/15
to David Lee Lambert, perl...@perl.org
hi,

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

unread,
Jun 13, 2015, 6:00:02 AM6/13/15
to David Lee Lambert, perl...@perl.org

> On 11 Jun 2015, at 22:45, David Lee Lambert <dav...@lmert.com> wrote:
>
> 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: $@, $!”;

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

unread,
Jun 13, 2015, 7:45:02 AM6/13/15
to perl...@perl.org
On Sat, Jun 13, 2015 at 11:47 AM, Chris Ridd <chri...@mac.com> wrote:

> On 11 Jun 2015, at 22:45, David Lee Lambert <dav...@lmert.com> wrote:

> 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: $@, $!”;

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.


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

--
Groeten,
natxo

Peter Karman

unread,
Jun 15, 2015, 9:30:02 AM6/15/15
to perl...@perl.org
Chris Ridd wrote on 6/13/15, 12:16 PM:
>
>> On 13 Jun 2015, at 12:30, Natxo Asenjo<natxo....@gmail.com> wrote:

>> 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/ . pe...@peknet.com
Reply all
Reply to author
Forward
0 new messages