Simplify the 'password must change' logic
authorAndrew Bartlett <abartlet@samba.org>
Thu, 28 Feb 2008 21:47:42 +0000 (08:47 +1100)
committerAndrew Bartlett <abartlet@samba.org>
Thu, 28 Feb 2008 21:47:42 +0000 (08:47 +1100)
This takes the previous patches further, so we catch all the cases
(the KDC looked at the time directly).

Andrew Bartlett
(This used to be commit cda4642a937d249399e25eaa6e5e20a0d440bcbf)

source4/auth/sam.c
source4/dsdb/common/util.c

index abcb72f292927540dce874ac2c9ee3c9847ec909..9a8045f62d62071aac9a5bfb05112ea261fbe845 100644 (file)
@@ -149,7 +149,6 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
        const char *workstation_list;
        NTTIME acct_expiry;
        NTTIME must_change_time;
-       NTTIME last_set_time;
 
        struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", ldb_dn_new(mem_ctx, sam_ctx, NULL));
 
@@ -159,9 +158,11 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
        acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn);
        
        acct_expiry = samdb_result_nttime(msg, "accountExpires", 0);
+
+       /* Check for when we must change this password, taking the
+        * userAccountControl flags into account */
        must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, 
                                                              domain_dn, msg);
-       last_set_time = samdb_result_nttime(msg, "pwdLastSet", 0);
 
        workstation_list = samdb_result_string(msg, "userWorkstations", NULL);
 
@@ -187,14 +188,14 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx,
        }
 
        /* check for immediate expiry "must change at next logon" */
-       if (!(acct_flags & ACB_PWNOEXP) && (must_change_time == 0 && last_set_time != 0)) {
+       if (must_change_time == 0) {
                DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n", 
                         name_for_logs));
                return NT_STATUS_PASSWORD_MUST_CHANGE;
        }
 
-       /* check for expired password (dynamicly gnerated in samdb_result_acct_flags) */
-       if (acct_flags & ACB_PW_EXPIRED) {
+       /* check for expired password */
+       if (must_change_time < now) {
                DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n", 
                         name_for_logs));
                DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n", 
index c9c0285604d705cb36583ba67af7953d07160609..ba8841ceb06e2e5b9f66e05c80243ff2a60f4e72 100644 (file)
@@ -469,8 +469,8 @@ NTTIME samdb_result_allow_password_change(struct ldb_context *sam_ldb,
 }
 
 /*
-  construct the force_password_change field from the PwdLastSet attribute and the 
-  domain password settings
+  construct the force_password_change field from the PwdLastSet
+  attribute, the userAccountControl and the domain password settings
 */
 NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb, 
                                          TALLOC_CTX *mem_ctx, 
@@ -478,10 +478,12 @@ NTTIME samdb_result_force_password_change(struct ldb_context *sam_ldb,
                                          struct ldb_message *msg)
 {
        uint64_t attr_time = samdb_result_uint64(msg, "pwdLastSet", 0);
-       uint32_t user_flags = samdb_result_uint64(msg, "userAccountControl", 0);
+       uint32_t userAccountcontrol = samdb_result_uint64(msg, "userAccountControl", 0);
        int64_t maxPwdAge;
 
-       if (user_flags & UF_DONT_EXPIRE_PASSWD) {
+       /* Machine accounts don't expire, and there is a flag for 'no expiry' */
+       if (!(userAccountControl & UF_NORMAL_ACCOUNT)
+           || (userAccountControl & UF_DONT_EXPIRE_PASSWD)) {
                return 0x7FFFFFFFFFFFFFFFULL;
        }
 
@@ -607,24 +609,17 @@ uint32_t samdb_result_acct_flags(struct ldb_context *sam_ctx, TALLOC_CTX *mem_ct
 {
        uint32_t userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
        uint32_t acct_flags = samdb_uf2acb(userAccountControl); 
-       if ((userAccountControl & UF_NORMAL_ACCOUNT) && !(userAccountControl & UF_DONT_EXPIRE_PASSWD)) {
-               NTTIME must_change_time;
-               NTTIME pwdLastSet = samdb_result_nttime(msg, "pwdLastSet", 0);
-               if (pwdLastSet == 0) {
-                       acct_flags |= ACB_PW_EXPIRED;
-               } else {
-                       NTTIME now;
-                       
-                       must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, 
-                                                                             domain_dn, msg);
-                       
-                       /* Test account expire time */
-                       unix_to_nt_time(&now, time(NULL));
-                       /* check for expired password */
-                       if ((must_change_time != 0) && (must_change_time < now)) {
-                               acct_flags |= ACB_PW_EXPIRED;
-                       }
-               }
+       NTTIME must_change_time;
+       NTTIME now;
+       
+       must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, 
+                                                             domain_dn, msg);
+       
+       /* Test account expire time */
+       unix_to_nt_time(&now, time(NULL));
+       /* check for expired password */
+       if (must_change_time < now) {
+               acct_flags |= ACB_PW_EXPIRED;
        }
        return acct_flags;
 }