diff options
author | Andrew Bartlett <abartlet@samba.org> | 2008-10-17 12:41:02 +1100 |
---|---|---|
committer | Andrew Bartlett <abartlet@samba.org> | 2008-10-17 12:41:02 +1100 |
commit | 99315a19be4d28146e18dac7104ee2d18b798a48 (patch) | |
tree | d77c3cffc3b4e0f403cb170a32dfcb64cc67cc2a /source4 | |
parent | 7c88ea8aadfc2be0726cbe555543cfab8804c470 (diff) | |
download | samba-99315a19be4d28146e18dac7104ee2d18b798a48.tar.gz samba-99315a19be4d28146e18dac7104ee2d18b798a48.tar.bz2 samba-99315a19be4d28146e18dac7104ee2d18b798a48.zip |
Fix errrors in new password handling code found by RPC-SAMR.
I'm very glad we have such a comprehensive testsuite for the SAMR
password change process, as it makes this a much easier task to get
right.
Andrew Bartlett
Diffstat (limited to 'source4')
-rw-r--r-- | source4/dsdb/common/util.c | 2 | ||||
-rw-r--r-- | source4/rpc_server/samr/samr_password.c | 17 |
2 files changed, 16 insertions, 3 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 0a87c5ffe1..6a6f370943 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -1644,7 +1644,7 @@ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx, char *new_pass; /* check the various password restrictions */ - if (restrictions && minPwdLength > utf16_len_n(new_password->data, (new_password->length / 2))) { + if (restrictions && minPwdLength > utf16_len_n(new_password->data, new_password->length) / 2) { if (reject_reason) { *reject_reason = SAMR_REJECT_TOO_SHORT; } diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c index 336720ecc7..859fd03801 100644 --- a/source4/rpc_server/samr/samr_password.c +++ b/source4/rpc_server/samr/samr_password.c @@ -184,7 +184,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, struct samr_OemChangePasswordUser2 *r) { NTSTATUS status; - DATA_BLOB new_password; + DATA_BLOB new_password, new_unicode_password; char *new_pass; struct samr_CryptPassword *pwbuf = r->in.password; struct ldb_context *sam_ctx; @@ -196,6 +196,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, DATA_BLOB lm_pwd_blob; uint8_t new_lm_hash[16]; struct samr_Password lm_verifier; + ssize_t unicode_pw_len; if (pwbuf == NULL) { return NT_STATUS_INVALID_PARAMETER; @@ -260,6 +261,18 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, return NT_STATUS_WRONG_PASSWORD; } + unicode_pw_len = convert_string_talloc(mem_ctx, lp_iconv_convenience(dce_call->conn->dce_ctx->lp_ctx), + CH_DOS, CH_UTF16, + (const char *)new_password.data, + new_password.length, + (void **)&new_unicode_password.data); + if (unicode_pw_len == -1) { + DEBUG(3,("samr: failed to convert incoming password buffer to UTF16 charset\n")); + ldb_transaction_cancel(sam_ctx); + return NT_STATUS_WRONG_PASSWORD; + } + new_unicode_password.length = unicode_pw_len; + E_deshash(new_pass, new_lm_hash); E_old_pw_hash(new_lm_hash, lm_pwd->hash, lm_verifier.hash); if (memcmp(lm_verifier.hash, r->in.hash->hash, 16) != 0) { @@ -283,7 +296,7 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, * due to password policies */ status = samdb_set_password(sam_ctx, mem_ctx, user_dn, NULL, - mod, &new_password, + mod, &new_unicode_password, NULL, NULL, true, /* this is a user password change */ NULL, |