I wrote a script to connect to AD, do some stuff, and spit out an
XML file. Works great. I picked up the script and handed it to a
colleague to run on his AIX server. Of course, his Perl install was
criminally out of date, so I spent a few minutes and did him the favor
of running CPAN and updating his 5.8 install with all the necessary
modules. I ran the script and lo and behold, this familiar error
message pops up:
80090303: LdapErr: DSID-0C090420, comment: The digest-uri does not
match any LDAP SPN's registered for this server.,
Makes me want to slap somebody.
I'm confident that all of the modules are up to date, given the
fact that I just ran CPAN. But I could be wrong, and the fact that I
developed it on 5.10 perl and ran it on a 5.8 perl install... well.
Anyway, I printed the SASL object I created via Dumper in a line
after the bind attempt. Here's a snippet. The @ldaploginservers is an
array of LDAP URLs:
my $sasl = Authen::SASL->new(mechanism => 'DIGEST-MD5',
callback => {
user => $aduser,
pass => $adpassword,
},
);
my $ldap = Net::LDAP->new(\@ldaploginservers, async => 0);
$mesg = $ldap->bind(sasl =>$sasl);
print Dumper($sasl);
When I ran it on the working Linux box, I noticed this in the
output
'service' => 'ldap',
'host' =>'fully.qualified.name.that.I.changed.for.this.post'
On the server that it did NOT work on, I saw this:
'service' => 'ldap',
'host' => '10.3.2.1'
Suspicious that this would not go well with AD, I poked around and
decided to downgrade the server version of Net::LDAP to 0.34. Bingo!
Worked. But now I'm worried that if I upgrade Net::LDAP for some
reason in the future, that this, as well as alot of other AD stuff
I've written, will die.
Ok, so nobody has responded, so I did some more lab work. I installed
every version of Net::LDAP working my way backwards from 0.39, with the
idea that I would stop at the version that worked. Every time I ran the
script with the DIGEST-MD5 SASL bind it failed, until I hit 0.36. I
looked at the Bug Fixes for the release notes of 0.37, and it mentions
that there was a patch worded as such: "Pass correct hostname to SASL
when connecting to a round-robin". The only module file to change from
0.36 to 0.37 was LDAP.pm. Could it be the call to the $ldap object
IO::Socket::INET ($ldap->{net_ldap_socket}->peerhost)is returning an IP
address instead of the desired hostname? Should I file a bug on CPAN?
I think yes.
Graham Barr wrote:
> I think Net::LDAP attempting to determine the host to pass to
> client_new is ultimately a bad choice. I do not really want to go
> through another round of doing that because we fix it for one person
> and break it for others.
>
> Currently the Authen::SASL object is passed to Net::LDAP. But all
> Net::LDAP does with that object is call client_new. So my proposal is
> that Net::LDAP also accept the result of client_new where it currently
> accepts an Authen::SASL object. This will allow the caller to
> determine the hostname to pass.
>
> Graham.
>
Can't locate object method "callback" via package "ldap" (perhaps you
forgot to load "ldap"?)
If that's not what you meant, then should I wait for a future rev of SASL?
Graham Barr wrote:
>
> On Mar 2, 2009, at 1:53 PM, Ismael wrote:
>
>> I'm not sure if I understand, but I see where continuing to rely on
>> Net::LDAP to get it right might be a problem. I'd like to see a
>> change to Authen::SASL::Perl where I can override whatever value the
>> host is populated with. For my uses, something like a callback where
>> I can stick in a reference to Net::LDAP->Host(). Reason being is that
>> I never know what server I'm connecting to at the time of scripting.
>> I rely on the results of a DNS SRV lookup to construct my Net::LDAP
>> object. I know that an array of servers is returned, and whichever
>> one I end up binding to is the one I would then need in my SASL
>> constructor so that the end result is an SPN that AD will not choke on.
>
> I think adding a callback to Authen::SASL is more than what is needed.
> What I am suggesting is changing code that currently looks like
>
> my $sasl = Authen::SASL->new(...);
> $ldap->bind( sasl => $sasl );
>
> to be
>
> my $sasl = Authen::SASL->new(...);
> $ldap->bind( sasl => $sasl->client_new("ldap", $host) );
>
> ie, you call client_new with the host that you want and then pass the
> client connection to bind.
>
> Graham.