summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2008-10-17 12:41:02 +1100
committerAndrew Bartlett <abartlet@samba.org>2008-10-17 12:41:02 +1100
commit99315a19be4d28146e18dac7104ee2d18b798a48 (patch)
treed77c3cffc3b4e0f403cb170a32dfcb64cc67cc2a
parent7c88ea8aadfc2be0726cbe555543cfab8804c470 (diff)
downloadsamba-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
-rw-r--r--source4/dsdb/common/util.c2
-rw-r--r--source4/rpc_server/samr/samr_password.c17
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,