[lsc-dev] [Fwd: RE: Extended response from Active Directory?]

Clément OUDOT coudot at linagora.com
Tue Feb 24 10:18:38 CET 2009

I forward a discusion on perl-ldap dealing with the unicodePwd pb. Maybe
the solution is not far...


---------------------------- Message original ----------------------------
Objet:   RE: Extended response from Active Directory?
De:      "Tanner, Bruce" <Bruce.Tanner at Cerritos.edu>
Date:    Lun 23 février 2009 20:36
À:       "Robert Leibl" <robert.leibl at gmail.com>
         "perl-ldap at perl.org" <perl-ldap at perl.org>

The unicodePwd is done almost exactly this way:

my $password = 'Test123';
map { $utf_password .= "$_\000" } split(//, qq("$password"));
print "x", unpack("H*", $utf_password), "\n";

Alternatives that I've played with are:

my $utf_password = pack "v*", unpack "C*", qq("$password");

my $utf_password = pack( "S*", unpack( "C*", qq("$password") ) );

However, they all fail with error 53.


-----Original Message-----
From: Robert Leibl [mailto:robert.leibl at gmail.com]
Sent: Thursday, February 19, 2009 1:33 AM
To: perl-ldap at perl.org
Cc: Tanner, Bruce
Subject: Re: Extended response from Active Directory?

Tanner, Bruce wrote:
> Our user password reset program has been running for months but has
started giving an error 53 as each domain controller was rebooted.  I've
run out of ideas as to why this is happening.  This is with Net::LDAP
0.39 on Windows 2003/XP and Windows 2008 domain controllers.
> $modify_result = $ldap->modify( $dn, replace => { 'unicodePwd' =>
$utf_password } ); # change password
> if ($modify_result->is_error) {
>     print 'Modify: ', $modify_result->code, ': ',
$modify_result->error_text, "\n";
>     print 'Modify: ', $modify_result->error, "\n";
> }
> Modify: 53: The server is unwilling to perform the requested operation
Modify: 0000001F: SvcErr: DSID-031A11E5, problem 5003

You said that it has worked before, so I might not tell you anything new
But here goes anyway:

The unicode password must be surrounded by '"', each byte needs to be
by a \0 (null) character, and the whole string must be base64 encoded.

   my $raw_pass = 'secret';
   $raw_pass = '"' . $raw_pass . '"';
   my $password = '';
   map { $password .= "$_\000" } split( //, $raw_pass);

   $password = encode_base64($password);

(there are simpler ways, but this shows the idea)

Further, I used this in an LDIF file where you have to tell the parser
that the value is base64 encoded by adding an additional ':'

   unicodePwd:: $password

Using this I found that the server was 'willing to perform the operation'.


More information about the lsc-dev mailing list