0

The challange is to change user's AD passwort. I have a TCL Script wrapping ldapmodify to set the passcode, which works:

set unicodePwd [encodePw4ad $pw]
lappend text {dn: $dn}
lappend text {changetype: modify}
lappend text {replace: unicodePwd}
lappend text {unicodePwd:: $unicodePwd}
lappend text {-} 

set fn /tmp/ldiff.[clock microseconds].ldif
write_file $fn [subst [join $text \n]] 
.....
exec ldapmodify -H $host -D $binddn -x -w $bindpw -f $fn 

Using TCL 8.6 with LDAP 1.9.2 Package the code looks:

set unicodePwd [encodePw4ad $pw]
set handle [::ldap::secure_connect $host 636 0]
ldap::bind $handle $binddn $bindpw
#ldap::modify $handle $dn [list postalCode 123456]
ldap::modify $handle $dn [list unicodePwd $unicodePwd]                                                                                                                       
ldap::unbind $handle
ldap::disconnect $handle

This works for the "postalCode" but not for the "unicodePwd".

LDAP error unwillingToPerform '': 0000001F: SvcErr: DSID-031A12D2, problem 5003 (WILL_NOT_PERFORM), data 0

Any hint to investigate?

tbasien
  • 87
  • 7
  • It may be a problem from the LDAP server (and not the TCL client). Reference: https://ldapwiki.com/wiki/ERROR_PASSWORD_RESTRICTION, https://ldapwiki.com/wiki/WILL_NOT_PERFORM – Sharad Jan 29 '19 at 16:39
  • What does `encodePw4ad` do to the password string? Can this be a character-encoding issue on the way out to the ldap connection? Does writing `[list unicodePwd [encoding convertto utf-8 $unicodePwd]]` change the picture? What using [`ldapx`](https://core.tcl.tk/tcllib/doc/trunk/embedded/www/tcllib/files/modules/ldap/ldapx.html) with its `-utf8` flag? – mrcalvin Jan 29 '19 at 17:37
  • The ldapmodify works, the ldap::modify does not. So I expect it is not a real LDAP Server issue. Or does the LDAP Server differentiate betwenn differen clienst connecting secure? Also ldapmodify and ldap::modify can set/change attributes. So I think it not a TLS/security/protocoll issue. The test password I use is "abc123", which has (so I know) the same presenation in the different western encodings. – tbasien Jan 30 '19 at 07:20
  • 0000001F/ 5003 is reportedly (as you write) related to using a non-secure LDAP connection or violating some AD password policy ... do you have access to the server log? – mrcalvin Jan 30 '19 at 10:30
  • Did you work through the possible causes at https://stackoverflow.com/questions/6797955/how-do-i-resolve-will-not-perform-ms-ad-reply-when-trying-to-change-password-i? – mrcalvin Jan 30 '19 at 10:43
  • For instance, if the UTF-16LE hint were valid, then my initial comment would have to read: `[list unicodePwd [encoding convertto unicode $unicodePwd]]` (this assumes that `encodePw4ad` takes care about the base64 encoding before). – mrcalvin Jan 30 '19 at 10:46
  • "The test password I use is "abc123", which has (so I know) the same presenation in the different western encodings." not necessarily, in utf-16, this would be two bytes per character ... while in utf-8 the characters would fall into the 1-byte range. – mrcalvin Jan 30 '19 at 10:48
  • I think, base encoding and charset-conversion have to be flipped, see my tentative answer. – mrcalvin Jan 30 '19 at 11:11
  • But am I able to set anyother attribute correctly? BTW: encodePw4ad already include the mention unicodeing. – tbasien Jan 30 '19 at 11:12
  • Well, haven't I ask you to show all necessary details incl. `encodePw4ad`? How have you ruled out all other issues (SSL/TLS)? So what is the actual value then for `unicodePwd` passed into modify? I suggest that you condense your example to a minimal, but self-contained script that we can run. – mrcalvin Jan 30 '19 at 11:22
  • what is the output of `tls::status [set [set handle](sock)]` just before executing modify? – mrcalvin Jan 30 '19 at 11:40

2 Answers2

0

I cannot test this (as I don't have a the environment available), but following this quote ...

The syntax of the unicodePwd attribute is octet-string; however, the directory service expects that the octet-string will contain a UNICODE string (as the name of the attribute indicates). This means that any values for this attribute passed in LDAP must be UNICODE strings that are BER-encoded (Basic Encoding Rules) as an octet-string. In addition, the UNICODE string must begin and end in quotes that are not part of the desired password.

from https://support.microsoft.com/en-gb/help/269190/how-to-change-a-windows-active-directory-and-lds-user-password-through

... the value for the unicodePwd record entry must be formatted as follows in Tcl (>= 8.6):

set pwd "abc123"
set pwd [string cat \" $pwd \"]; # must begin/ end in quotes
set pwd [encoding convertto unicode $pwd]; # UNICODE (UTF-16LE) string
set unicodePwd [binary encode base64 $pwd]; # base64 encoded variant

NB: You can watch that the resulting string from [encoding convertto unicode $pwd] using 2 bytes per character (16 bytes for "abc123" incl. quotes), or just eight if you were using the utf-8 or whatever, when running [string length] at the different steps.

mrcalvin
  • 3,291
  • 12
  • 18
  • Tx so far! This is exactlly what my 'proc encodePw4ad' does. And this works with TCL wrapping 'exec ldapmodify ..'. In this case there is no vialoation. An authenication test on that new password is positive. This means the AD is acceppting "abc123". – tbasien Jan 30 '19 at 11:21
0

Problem found:

ldapmodify uses 'unicodePwd::'. The '::' tells the AD, that the value is base64 encoded.

in TCL ldap::modify 'unicodePwd' has to be send in unicode only (no base64).

We did find a way to send base64 via the TCL ldap::modify

tbasien
  • 87
  • 7