[SCM] Samba Shared Repository - branch master updated -
release-4-0-0alpha8-288-g2481ce8
Andrew Bartlett
abartlet at samba.org
Thu Jul 9 04:57:07 GMT 2009
The branch, master has been updated
via 2481ce89427ef38b47fb29d16c15b77e9d2c20b9 (commit)
via 2c873c43534d61cd411b5c8d56425fd9c2ddd128 (commit)
from fbaa8497a5c8c209de9ca86bebf8387e6d33a608 (commit)
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 2481ce89427ef38b47fb29d16c15b77e9d2c20b9
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Jul 9 14:53:26 2009 +1000
s4:dsdb Allow unicodePwd to be set when adding a user
Windows 7 sets it's join password using the unicodePwd attribute (as a
quoted, utf16 string), and does so during the LDAPAdd of the object.
Previously, this code only handled unicodePwd for modifies.
Andrew Bartlett
commit 2c873c43534d61cd411b5c8d56425fd9c2ddd128
Author: Andrew Bartlett <abartlet at samba.org>
Date: Thu Jul 9 10:08:02 2009 +1000
Add const
-----------------------------------------------------------------------
Summary of changes:
source4/dsdb/common/util.c | 4 +-
source4/dsdb/samdb/ldb_modules/password_hash.c | 169 ++++++++++++------------
2 files changed, 86 insertions(+), 87 deletions(-)
Changeset truncated at 500 lines:
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 313005b..cbae2ec 100644
--- a/source4/dsdb/common/util.c
+++ b/source4/dsdb/common/util.c
@@ -529,7 +529,7 @@ NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb,
/*
pull a samr_Password structutre from a result set.
*/
-struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, struct ldb_message *msg, const char *attr)
+struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, const struct ldb_message *msg, const char *attr)
{
struct samr_Password *hash = NULL;
const struct ldb_val *val = ldb_msg_find_ldb_val(msg, attr);
@@ -543,7 +543,7 @@ struct samr_Password *samdb_result_hash(TALLOC_CTX *mem_ctx, struct ldb_message
/*
pull an array of samr_Password structutres from a result set.
*/
-uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, struct ldb_message *msg,
+uint_t samdb_result_hashes(TALLOC_CTX *mem_ctx, const struct ldb_message *msg,
const char *attr, struct samr_Password **hashes)
{
uint_t count = 0;
diff --git a/source4/dsdb/samdb/ldb_modules/password_hash.c b/source4/dsdb/samdb/ldb_modules/password_hash.c
index 5a9926b..44b7ef9 100644
--- a/source4/dsdb/samdb/ldb_modules/password_hash.c
+++ b/source4/dsdb/samdb/ldb_modules/password_hash.c
@@ -1432,6 +1432,67 @@ static int setup_password_fields(struct setup_password_fields_io *io)
return LDB_SUCCESS;
}
+static int setup_io(struct ph_context *ac,
+ const struct ldb_message *new_msg,
+ const struct ldb_message *searched_msg,
+ struct setup_password_fields_io *io)
+{
+ const struct ldb_val *quoted_utf16;
+ struct ldb_context *ldb = ldb_module_get_ctx(ac->module);
+
+ ZERO_STRUCTP(io);
+
+ /* Some operations below require kerberos contexts */
+ if (smb_krb5_init_context(ac,
+ ldb_get_event_context(ldb),
+ (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
+ &io->smb_krb5_context) != 0) {
+ return LDB_ERR_OPERATIONS_ERROR;
+ }
+
+ io->ac = ac;
+ io->domain = ac->domain;
+
+ io->u.user_account_control = samdb_result_uint(searched_msg, "userAccountControl", 0);
+ io->u.sAMAccountName = samdb_result_string(searched_msg, "samAccountName", NULL);
+ io->u.user_principal_name = samdb_result_string(searched_msg, "userPrincipalName", NULL);
+ io->u.is_computer = ldb_msg_check_string_attribute(searched_msg, "objectClass", "computer");
+
+ io->n.cleartext_utf8 = ldb_msg_find_ldb_val(new_msg, "userPassword");
+ io->n.cleartext_utf16 = ldb_msg_find_ldb_val(new_msg, "clearTextPassword");
+
+ /* 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(new_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(io->ac, 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, new_msg, "unicodePwd");
+ }
+
+ io->n.lm_hash = samdb_result_hash(io->ac, new_msg, "dBCSPwd");
+
+ return LDB_SUCCESS;
+}
+
static struct ph_context *ph_init_context(struct ldb_module *module,
struct ldb_request *req)
{
@@ -1743,50 +1804,32 @@ static int password_hash_add_do_add(struct ph_context *ac)
{
struct ldb_context *ldb;
struct ldb_request *down_req;
- struct smb_krb5_context *smb_krb5_context;
struct ldb_message *msg;
struct setup_password_fields_io io;
int ret;
- ldb = ldb_module_get_ctx(ac->module);
+ /* Prepare the internal data structure containing the passwords */
+ ret = setup_io(ac, ac->req->op.add.message, ac->req->op.add.message, &io);
+ if (ret != LDB_SUCCESS) {
+ return ret;
+ }
msg = ldb_msg_copy_shallow(ac, ac->req->op.add.message);
if (msg == NULL) {
return LDB_ERR_OPERATIONS_ERROR;
}
- /* Some operations below require kerberos contexts */
- if (smb_krb5_init_context(ac,
- ldb_get_event_context(ldb),
- (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
- &smb_krb5_context) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- ZERO_STRUCT(io);
- io.ac = ac;
- io.domain = ac->domain;
- io.smb_krb5_context = smb_krb5_context;
-
- io.u.user_account_control = samdb_result_uint(msg, "userAccountControl", 0);
- io.u.sAMAccountName = samdb_result_string(msg, "samAccountName", NULL);
- io.u.user_principal_name = samdb_result_string(msg, "userPrincipalName", NULL);
- io.u.is_computer = ldb_msg_check_string_attribute(msg, "objectClass", "computer");
-
- io.n.cleartext_utf8 = ldb_msg_find_ldb_val(msg, "userPassword");
- io.n.cleartext_utf16 = ldb_msg_find_ldb_val(msg, "clearTextPassword");
- io.n.nt_hash = samdb_result_hash(io.ac, msg, "unicodePwd");
- io.n.lm_hash = samdb_result_hash(io.ac, msg, "dBCSPwd");
-
- /* remove attributes */
- if (io.n.cleartext_utf8) ldb_msg_remove_attr(msg, "userPassword");
- if (io.n.cleartext_utf16) ldb_msg_remove_attr(msg, "clearTextPassword");
- if (io.n.nt_hash) ldb_msg_remove_attr(msg, "unicodePwd");
- if (io.n.lm_hash) ldb_msg_remove_attr(msg, "dBCSPwd");
+ /* remove attributes that we just read into 'io' */
+ ldb_msg_remove_attr(msg, "userPassword");
+ ldb_msg_remove_attr(msg, "clearTextPassword");
+ ldb_msg_remove_attr(msg, "unicodePwd");
+ ldb_msg_remove_attr(msg, "dBCSPwd");
ldb_msg_remove_attr(msg, "pwdLastSet");
io.o.kvno = samdb_result_uint(msg, "msDs-KeyVersionNumber", 1) - 1;
ldb_msg_remove_attr(msg, "msDs-KeyVersionNumber");
+ ldb = ldb_module_get_ctx(ac->module);
+
ret = setup_password_fields(&io);
if (ret != LDB_SUCCESS) {
return ret;
@@ -2096,12 +2139,9 @@ static int password_hash_mod_do_mod(struct ph_context *ac)
{
struct ldb_context *ldb;
struct ldb_request *mod_req;
- struct smb_krb5_context *smb_krb5_context;
struct ldb_message *msg;
- struct ldb_message *orig_msg;
- struct ldb_message *searched_msg;
+ const 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);
@@ -2115,59 +2155,18 @@ static int password_hash_mod_do_mod(struct ph_context *ac)
/* modify dn */
msg->dn = ac->req->op.mod.message->dn;
- /* Some operations below require kerberos contexts */
- if (smb_krb5_init_context(ac,
- ldb_get_event_context(ldb),
- (struct loadparm_context *)ldb_get_opaque(ldb, "loadparm"),
- &smb_krb5_context) != 0) {
- return LDB_ERR_OPERATIONS_ERROR;
- }
-
- orig_msg = discard_const(ac->req->op.mod.message);
- searched_msg = ac->search_res->message;
-
- ZERO_STRUCT(io);
- io.ac = ac;
- io.domain = ac->domain;
- io.smb_krb5_context = smb_krb5_context;
-
- io.u.user_account_control = samdb_result_uint(searched_msg, "userAccountControl", 0);
- io.u.sAMAccountName = samdb_result_string(searched_msg, "samAccountName", NULL);
- io.u.user_principal_name = samdb_result_string(searched_msg, "userPrincipalName", NULL);
- io.u.is_computer = ldb_msg_check_string_attribute(searched_msg, "objectClass", "computer");
-
- io.n.cleartext_utf8 = ldb_msg_find_ldb_val(orig_msg, "userPassword");
- io.n.cleartext_utf16 = ldb_msg_find_ldb_val(orig_msg, "clearTextPassword");
-
- /* 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");
+ /* Prepare the internal data structure containing the passwords */
+ ret = setup_io(ac,
+ ac->req->op.mod.message,
+ ac->search_res->message,
+ &io);
+ if (ret != LDB_SUCCESS) {
+ return ret;
}
+
+ searched_msg = ac->search_res->message;
- io.n.lm_hash = samdb_result_hash(io.ac, orig_msg, "dBCSPwd");
-
+ /* Fill in some final details (only relevent once the password has been set) */
io.o.kvno = samdb_result_uint(searched_msg, "msDs-KeyVersionNumber", 0);
io.o.nt_history_len = samdb_result_hashes(io.ac, searched_msg, "ntPwdHistory", &io.o.nt_history);
io.o.lm_history_len = samdb_result_hashes(io.ac, searched_msg, "lmPwdHistory", &io.o.lm_history);
--
Samba Shared Repository
More information about the samba-cvs
mailing list