summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Tridgell <tridge@samba.org>2009-02-10 17:31:57 +1100
committerAndrew Tridgell <tridge@samba.org>2009-02-10 17:31:57 +1100
commitfe5b0b595c926aea0916541ceeaf610bc018cb63 (patch)
tree85d2952921fbc8852cc70da083eb649b50bde4f7
parent72c2da9d327288552084efad831ef8c3518de835 (diff)
downloadsamba-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.c31
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);