dsdb: Put password lockout support in samdb_result_passwords()
authorAndrew Bartlett <abartlet@samba.org>
Mon, 4 Nov 2013 08:37:17 +0000 (21:37 +1300)
committerStefan Metzmacher <metze@samba.org>
Wed, 2 Apr 2014 15:12:46 +0000 (17:12 +0200)
This seems to be the best choke point to check for locked out
accounts, as aside from the KDC, all the password authentication and
change callers use it.

Andrew Bartlett

Change-Id: I0f21a79697cb8b08ef639445bd05a896a2c9ee1b
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
source4/auth/ntlm/auth_sam.c
source4/dsdb/common/util.c
source4/dsdb/samdb/ldb_modules/password_hash.c
source4/kdc/kpasswdd.c
source4/rpc_server/netlogon/dcerpc_netlogon.c
source4/rpc_server/samr/samr_password.c

index 664908bfea7c80912dcf90f969c25d2b0924153c..d07f9301fb4acb4103baef81d5029c7aec09a39d 100644 (file)
@@ -179,15 +179,7 @@ static NTSTATUS authsam_authenticate(struct auth4_context *auth_context,
 {
        struct samr_Password *lm_pwd, *nt_pwd;
        NTSTATUS nt_status;
-
-       uint16_t acct_flags = samdb_result_acct_flags(msg, "msDS-User-Account-Control-Computed");
-       
-       /* Quit if the account was locked out. */
-       if (acct_flags & ACB_AUTOLOCK) {
-               DEBUG(3,("check_sam_security: Account for user %s was locked out.\n", 
-                        user_info->mapped.account_name));
-               return NT_STATUS_ACCOUNT_LOCKED_OUT;
-       }
+       uint16_t acct_flags = samdb_result_acct_flags(msg, NULL);
 
        /* You can only do an interactive login to normal accounts */
        if (user_info->flags & USER_INFO_INTERACTIVE_LOGON) {
index b65af66889b105515f1bb5f5205f14f6c2800cd6..8cecf79e020df847be5c5b8b1ec773cae10ef4dc 100644 (file)
@@ -558,10 +558,14 @@ unsigned int samdb_result_hashes(TALLOC_CTX *mem_ctx, const struct ldb_message *
        return count;
 }
 
-NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, struct ldb_message *msg,
-                               struct samr_Password **lm_pwd, struct samr_Password **nt_pwd) 
+NTSTATUS samdb_result_passwords_no_lockout(TALLOC_CTX *mem_ctx,
+                                          struct loadparm_context *lp_ctx,
+                                          struct ldb_message *msg,
+                                          struct samr_Password **lm_pwd,
+                                          struct samr_Password **nt_pwd)
 {
        struct samr_Password *lmPwdHash, *ntPwdHash;
+
        if (nt_pwd) {
                unsigned int num_nt;
                num_nt = samdb_result_hashes(mem_ctx, msg, "unicodePwd", &ntPwdHash);
@@ -594,6 +598,27 @@ NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx, struct loadparm_context *lp
        return NT_STATUS_OK;
 }
 
+NTSTATUS samdb_result_passwords(TALLOC_CTX *mem_ctx,
+                               struct loadparm_context *lp_ctx,
+                               struct ldb_message *msg,
+                               struct samr_Password **lm_pwd,
+                               struct samr_Password **nt_pwd)
+{
+       uint16_t acct_flags;
+
+       acct_flags = samdb_result_acct_flags(msg,
+                                            "msDS-User-Account-Control-Computed");
+       /* Quit if the account was locked out. */
+       if (acct_flags & ACB_AUTOLOCK) {
+               DEBUG(3,("samdb_result_passwords: Account for user %s was locked out.\n",
+                        ldb_dn_get_linearized(msg->dn)));
+               return NT_STATUS_ACCOUNT_LOCKED_OUT;
+       }
+
+       return samdb_result_passwords_no_lockout(mem_ctx, lp_ctx, msg,
+                                                lm_pwd, nt_pwd);
+}
+
 /*
   pull a samr_LogonHours structutre from a result set. 
 */
index 3e0f1a091e6209274dd15727b96fe61afc8b50ff..a8d327240530a86cc51ba92d9b0738630fd07e10 100644 (file)
@@ -3231,6 +3231,7 @@ static int password_hash_mod_search_self(struct ph_context *ac)
        struct ldb_context *ldb;
        static const char * const attrs[] = { "objectClass",
                                              "userAccountControl",
+                                             "msDS-User-Account-Control-Computed",
                                              "pwdLastSet",
                                              "sAMAccountName",
                                              "objectSid",
@@ -3293,11 +3294,21 @@ static int password_hash_mod_do_mod(struct ph_context *ac)
                return ret;
        }
        
-       /* Get the old password from the database */
-       status = samdb_result_passwords(io.ac,
-                                       lp_ctx,
-                                       discard_const_p(struct ldb_message, searched_msg),
-                                       &io.o.lm_hash, &io.o.nt_hash);
+       if (io.ac->pwd_reset) {
+               /* Get the old password from the database */
+               status = samdb_result_passwords_no_lockout(io.ac,
+                                                          lp_ctx,
+                                                          discard_const_p(struct ldb_message, searched_msg),
+                                                          &io.o.lm_hash,
+                                                          &io.o.nt_hash);
+       } else {
+               /* Get the old password from the database */
+               status = samdb_result_passwords(io.ac,
+                                               lp_ctx,
+                                               discard_const_p(struct ldb_message, searched_msg),
+                                               &io.o.lm_hash, &io.o.nt_hash);
+       }
+
        if (!NT_STATUS_IS_OK(status)) {
                return ldb_operr(ldb);
        }
index d79427b64f90d48ed87fd8d9dbe303efc90d473a..e8d46ad963d1c6ccccdfd55a3282e6c390cdecaa 100644 (file)
@@ -181,8 +181,13 @@ static bool kpasswdd_change_password(struct kdc_server *kdc,
                                                reply);
        }
 
-       status = samdb_result_passwords(mem_ctx, kdc->task->lp_ctx, msg,
-                                       &oldLmHash, &oldNtHash);
+       /*
+        * No need to check for password lockout here, the KDC will
+        * have done that when issuing the ticket, which is not based
+        * on the user's password
+        */
+       status = samdb_result_passwords_no_lockout(mem_ctx, kdc->task->lp_ctx, msg,
+                                                  &oldLmHash, &oldNtHash);
        if (!NT_STATUS_IS_OK(status)) {
                return kpasswdd_make_error_reply(kdc, mem_ctx,
                                                KRB5_KPASSWD_ACCESSDENIED,
index c3e33bd42095ab6a2b542a6513db9bd92de14bb9..50e7cab7ff14df560fb0e1a2b47af29f52b9d9c5 100644 (file)
@@ -461,9 +461,9 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet(struct dcesrv_call_state *dce_call
                return NT_STATUS_WRONG_PASSWORD;
        }
 
-       nt_status = samdb_result_passwords(mem_ctx,
-                                          dce_call->conn->dce_ctx->lp_ctx,
-                                          res[0], NULL, &oldNtHash);
+       nt_status = samdb_result_passwords_no_lockout(mem_ctx,
+                                                     dce_call->conn->dce_ctx->lp_ctx,
+                                                     res[0], NULL, &oldNtHash);
        if (!NT_STATUS_IS_OK(nt_status) || !oldNtHash) {
                return NT_STATUS_WRONG_PASSWORD;
        }
@@ -531,9 +531,9 @@ static NTSTATUS dcesrv_netr_ServerPasswordSet2(struct dcesrv_call_state *dce_cal
                return NT_STATUS_WRONG_PASSWORD;
        }
 
-       nt_status = samdb_result_passwords(mem_ctx,
-                                          dce_call->conn->dce_ctx->lp_ctx,
-                                          res[0], &oldLmHash, &oldNtHash);
+       nt_status = samdb_result_passwords_no_lockout(mem_ctx,
+                                                     dce_call->conn->dce_ctx->lp_ctx,
+                                                     res[0], &oldLmHash, &oldNtHash);
        if (!NT_STATUS_IS_OK(nt_status) || (!oldLmHash && !oldNtHash)) {
                return NT_STATUS_WRONG_PASSWORD;
        }
index 685a8e7864a027de7e320017cf57aedac685325c..0c4f3384604708b029542280afa93efd9edbfc3a 100644 (file)
@@ -61,7 +61,10 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
        struct ldb_dn *user_dn;
        int ret;
        struct ldb_message **res;
-       const char * const attrs[] = { "objectSid", "dBCSPwd", NULL };
+       const char * const attrs[] = { "objectSid", "dBCSPwd",
+                                      "userAccountControl",
+                                      "msDS-User-Account-Control-Computed",
+                                      NULL };
        struct samr_Password *lm_pwd;
        DATA_BLOB lm_pwd_blob;
        uint8_t new_lm_hash[16];
@@ -107,7 +110,9 @@ NTSTATUS dcesrv_samr_OemChangePasswordUser2(struct dcesrv_call_state *dce_call,
 
        status = samdb_result_passwords(mem_ctx, dce_call->conn->dce_ctx->lp_ctx,
                                        res[0], &lm_pwd, NULL);
-       if (!NT_STATUS_IS_OK(status) || !lm_pwd) {
+       if (!NT_STATUS_IS_OK(status)) {
+               return status;
+       } else if (!lm_pwd) {
                return NT_STATUS_WRONG_PASSWORD;
        }
 
@@ -202,7 +207,10 @@ NTSTATUS dcesrv_samr_ChangePasswordUser3(struct dcesrv_call_state *dce_call,
        struct ldb_dn *user_dn;
        int ret;
        struct ldb_message **res;
-       const char * const attrs[] = { "unicodePwd", "dBCSPwd", NULL };
+       const char * const attrs[] = { "unicodePwd", "dBCSPwd",
+                                      "userAccountControl",
+                                      "msDS-User-Account-Control-Computed",
+                                      NULL };
        struct samr_Password *nt_pwd, *lm_pwd;
        DATA_BLOB nt_pwd_blob;
        struct samr_DomInfo1 *dominfo = NULL;