r3952: added validation of the lm and nt verifiers to our server side password change...
authorAndrew Tridgell <tridge@samba.org>
Thu, 25 Nov 2004 01:13:44 +0000 (01:13 +0000)
committerGerald (Jerry) Carter <jerry@samba.org>
Wed, 10 Oct 2007 18:06:07 +0000 (13:06 -0500)
source/rpc_server/samr/samr_password.c

index 6f995081221e2b127d449709e8f444584e184f8f..745d2cfc054f4e57ed006bdece9d5cfdfe593831 100644 (file)
@@ -143,6 +143,8 @@ NTSTATUS samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_
        const char *domain_sid;
        struct samr_Password *lm_pwd;
        DATA_BLOB lm_pwd_blob;
+       uint8_t new_lm_hash[16];
+       struct samr_Password lm_verifier;
 
        if (pwbuf == NULL) {
                return NT_STATUS_WRONG_PASSWORD;
@@ -184,6 +186,17 @@ NTSTATUS samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_
                return NT_STATUS_WRONG_PASSWORD;
        }
 
+       /* check LM verifier */
+       if (lm_pwd == NULL || r->in.hash == NULL) {
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
+       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) {
+               return NT_STATUS_WRONG_PASSWORD;
+       }
+
        /* work out the domain dn */
        domain_sid = samdb_result_sid_prefix(mem_ctx, res[0], "objectSid");
        if (domain_sid == NULL) {
@@ -243,11 +256,13 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
                                           "pwdProperties", "minPwdAge", "maxPwdAge", 
                                           NULL };
        const char *domain_sid;
-       struct samr_Password *nt_pwd;
+       struct samr_Password *nt_pwd, *lm_pwd;
        DATA_BLOB nt_pwd_blob;
        struct samr_DomInfo1 *dominfo;
        struct samr_ChangeReject *reject;
        uint32_t reason = 0;
+       uint8_t new_nt_hash[16], new_lm_hash[16];
+       struct samr_Password nt_verifier, lm_verifier;
 
        ZERO_STRUCT(r->out);
 
@@ -279,7 +294,7 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
 
        user_dn = res[0]->dn;
 
-       status = samdb_result_passwords(mem_ctx, res[0], NULL, &nt_pwd);
+       status = samdb_result_passwords(mem_ctx, res[0], &lm_pwd, &nt_pwd);
        if (!NT_STATUS_IS_OK(status) ) {
                goto failed;
        }
@@ -301,6 +316,30 @@ NTSTATUS samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
                goto failed;
        }
 
+       if (r->in.nt_verifier == NULL) {
+               status = NT_STATUS_WRONG_PASSWORD;
+               goto failed;
+       }
+
+       /* check NT verifier */
+       E_md4hash(new_pass, new_nt_hash);
+       E_old_pw_hash(new_nt_hash, nt_pwd->hash, nt_verifier.hash);
+       if (memcmp(nt_verifier.hash, r->in.nt_verifier->hash, 16) != 0) {
+               status = NT_STATUS_WRONG_PASSWORD;
+               goto failed;
+       }
+
+       /* check LM verifier */
+       if (lm_pwd && r->in.lm_verifier != NULL) {
+               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.lm_verifier->hash, 16) != 0) {
+                       status = NT_STATUS_WRONG_PASSWORD;
+                       goto failed;
+               }
+       }
+
+
        /* work out the domain dn */
        domain_sid = samdb_result_sid_prefix(mem_ctx, res[0], "objectSid");
        if (domain_sid == NULL) {