[prev in list] [next in list] [prev in thread] [next in thread] 

List:       perl-ldap-dev
Subject:    RE: Extended response from Active Directory?
From:       "Tanner, Bruce" <Bruce.Tanner () Cerritos ! edu>
Date:       2009-02-23 19:36:35
Message-ID: F7654F0670A4E24CB66EC9FFE60125B72B65481EC2 () evs02 ! Cerritos ! edu
[Download RAW message or body]

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";
x220054006500730074003100320033002200


Alternatives that I've played with are:

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


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

However, they all fail with error 53.


-Bruce


-----Original Message-----
From: Robert Leibl [mailto:robert.leibl@gmail.com] 
Sent: Thursday, February 19, 2009 1:33 AM
To: perl-ldap@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 (WILL_NOT_PERFORM), data 0
[...]

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

The unicode password must be surrounded by '"', each byte needs to be followed
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'.

HTH
robert



[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic