[SCM] Samba Shared Repository - branch master updated - release-4-0-0alpha6-703-gfe5b0b5

Andrew Tridgell tridge at samba.org
Tue Feb 10 06:32:02 GMT 2009


The branch, master has been updated
       via  fe5b0b595c926aea0916541ceeaf610bc018cb63 (commit)
       via  72c2da9d327288552084efad831ef8c3518de835 (commit)
      from  b4a4d4c9d06c93188d9705f944cde8ed359bd3f3 (commit)

http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master


- Log -----------------------------------------------------------------
commit fe5b0b595c926aea0916541ceeaf610bc018cb63
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Feb 10 17:31:57 2009 +1100

    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.

commit 72c2da9d327288552084efad831ef8c3518de835
Author: Andrew Tridgell <tridge at samba.org>
Date:   Tue Feb 10 17:28:05 2009 +1100

    fixed two problems with the DsRGetDCNameEx2 call, as used by
    Win7-beta.
    
    The first problem is that we removed the dnsDomain attribute a while
    back, so we were returning NULL for two fields. We now return the
    realm.
    
    The second problem is that Win7-beta sends the domain in the form the
    user typed it, so it may be in either the short or long form. We check
    for the short form and convert if needed.

-----------------------------------------------------------------------

Summary of changes:
 source4/dsdb/samdb/ldb_modules/password_hash.c |   31 +++++++++++++++++++++++-
 source4/rpc_server/netlogon/dcerpc_netlogon.c  |   12 +++++++--
 2 files changed, 39 insertions(+), 4 deletions(-)


Changeset truncated at 500 lines:

diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 2c07fa1..da4c574 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);
diff --git a/source4/rpc_server/netlogon/dcerpc_netlogon.c b/source4/rpc_server/netlogon/dcerpc_netlogon.c
index a9150d1..d5484d0 100644
--- a/source4/rpc_server/netlogon/dcerpc_netlogon.c
+++ b/source4/rpc_server/netlogon/dcerpc_netlogon.c
@@ -1166,7 +1166,7 @@ static WERROR dcesrv_netr_DsRAddressToSitenamesW(struct dcesrv_call_state *dce_c
 static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TALLOC_CTX *mem_ctx,
 				   struct netr_DsRGetDCNameEx2 *r)
 {
-	const char * const attrs[] = { "dnsDomain", "objectGUID", NULL };
+	const char * const attrs[] = { "objectGUID", NULL };
 	void *sam_ctx;
 	struct ldb_message **res;
 	struct ldb_dn *domain_dn;
@@ -1180,6 +1180,12 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
 		return WERR_DS_SERVICE_UNAVAILABLE;
 	}
 
+	/* Win7-beta will send the domain name in the form the user typed, so we have to cope
+	   with both the short and long form here */
+	if (strcasecmp(r->in.domain_name, lp_workgroup(dce_call->conn->dce_ctx->lp_ctx)) == 0) {
+		r->in.domain_name = lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+	}
+
 	domain_dn = samdb_dns_domain_to_dn(sam_ctx, mem_ctx,
 					   r->in.domain_name);   
 	if (domain_dn == NULL) {
@@ -1205,8 +1211,8 @@ static WERROR dcesrv_netr_DsRGetDCNameEx2(struct dcesrv_call_state *dce_call, TA
 	W_ERROR_HAVE_NO_MEMORY(info->dc_address);
 	info->dc_address_type		= DS_ADDRESS_TYPE_INET;
 	info->domain_guid		= samdb_result_guid(res[0], "objectGUID");
-	info->domain_name		= samdb_result_string(res[0], "dnsDomain", NULL);
-	info->forest_name		= samdb_result_string(res[0], "dnsDomain", NULL);
+	info->domain_name		= lp_realm(dce_call->conn->dce_ctx->lp_ctx);
+	info->forest_name		= lp_realm(dce_call->conn->dce_ctx->lp_ctx);
 	info->dc_flags			= DS_DNS_FOREST |
 					  DS_DNS_DOMAIN |
 					  DS_DNS_CONTROLLER |


-- 
Samba Shared Repository


More information about the samba-cvs mailing list