diff options
author | Andrew Tridgell <tridge@samba.org> | 2009-02-10 17:31:57 +1100 |
---|---|---|
committer | Andrew Tridgell <tridge@samba.org> | 2009-02-10 17:31:57 +1100 |
commit | fe5b0b595c926aea0916541ceeaf610bc018cb63 (patch) | |
tree | 85d2952921fbc8852cc70da083eb649b50bde4f7 | |
parent | 72c2da9d327288552084efad831ef8c3518de835 (diff) | |
download | samba-fe5b0b595c926aea0916541ceeaf610bc018cb63.tar.gz samba-fe5b0b595c926aea0916541ceeaf610bc018cb63.tar.bz2 samba-fe5b0b595c926aea0916541ceeaf610bc018cb63.zip |
added a workaround to the handling of unicodePwd for Win7-beta
The Win7-beta domain process has changed. It no longer uses SAMR for
setting the password, and instead uses a ldap modify on a SASL
encrypted ldap connection. We didn't handle that as the unicodePwd
attribute has a dual use, holding the nt style MD4 hases for DRS
replication, but holding a UTF-16 plaintext password for a LDAP
modify.
This patch copes with the ldap unicodePwd modify by recognising the
format and creating the correct attributes on the fly. Note that this
assumes we will never get a unicodePwd attribute set in NT MD4 format
with the first 2 and last 2 bytes set to 0x22 0x00.
Andrew Bartlett is looking at a more robust solution, possibly using a
flag to say that this modify came via ldap, and not internal ldb
calls.
-rw-r--r-- | source4/dsdb/samdb/ldb_modules/password_hash.c | 31 |
1 files changed, 30 insertions, 1 deletions
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c index 2c07fa1be6..da4c57463b 100644 --- a/source4/dsdb/samdb/ldb_modules/password_hash.c +++ b/source4/dsdb/samdb/ldb_modules/password_hash.c @@ -109,6 +109,7 @@ struct setup_password_fields_io { struct { const struct ldb_val *cleartext_utf8; const struct ldb_val *cleartext_utf16; + struct ldb_val quoted_utf16; struct samr_Password *nt_hash; struct samr_Password *lm_hash; } n; @@ -2102,6 +2103,7 @@ static int password_hash_mod_do_mod(struct ph_context *ac) struct ldb_message *orig_msg; struct ldb_message *searched_msg; struct setup_password_fields_io io; + const struct ldb_val *quoted_utf16; int ret; ldb = ldb_module_get_ctx(ac->module); @@ -2138,7 +2140,34 @@ static int password_hash_mod_do_mod(struct ph_context *ac) io.n.cleartext_utf8 = ldb_msg_find_ldb_val(orig_msg, "userPassword"); io.n.cleartext_utf16 = ldb_msg_find_ldb_val(orig_msg, "clearTextPassword"); - io.n.nt_hash = samdb_result_hash(io.ac, orig_msg, "unicodePwd"); + + /* this rather strange looking piece of code is there to + handle a ldap client setting a password remotely using the + unicodePwd ldap field. The syntax is that the password is + in UTF-16LE, with a " at either end. Unfortunately the + unicodePwd field is also used to store the nt hashes + internally in Samba, and is used in the nt hash format on + the wire in DRS replication, so we have a single name for + two distinct values. The code below leaves us with a small + chance (less than 1 in 2^32) of a mixup, if someone manages + to create a MD4 hash which starts and ends in 0x22 0x00, as + that would then be treated as a UTF16 password rather than + a nthash */ + quoted_utf16 = ldb_msg_find_ldb_val(orig_msg, "unicodePwd"); + if (quoted_utf16 && + quoted_utf16->length >= 4 && + quoted_utf16->data[0] == '"' && + quoted_utf16->data[1] == 0 && + quoted_utf16->data[quoted_utf16->length-2] == '"' && + quoted_utf16->data[quoted_utf16->length-1] == 0) { + io.n.quoted_utf16.data = talloc_memdup(orig_msg, quoted_utf16->data+2, quoted_utf16->length-4); + io.n.quoted_utf16.length = quoted_utf16->length-4; + io.n.cleartext_utf16 = &io.n.quoted_utf16; + io.n.nt_hash = NULL; + } else { + io.n.nt_hash = samdb_result_hash(io.ac, orig_msg, "unicodePwd"); + } + io.n.lm_hash = samdb_result_hash(io.ac, orig_msg, "dBCSPwd"); io.o.kvno = samdb_result_uint(searched_msg, "msDs-KeyVersionNumber", 0); |