dsdb/rpc: Update effective badPwdCount to use PSO settings
authorTim Beale <timbeale@catalyst.net.nz>
Tue, 10 Apr 2018 22:33:21 +0000 (10:33 +1200)
committerGarming Sam <garming@samba.org>
Wed, 23 May 2018 04:55:30 +0000 (06:55 +0200)
The lockOutObservationWindow is used to calculate the badPwdCount. When
a PSO applies to a user, we want to use the PSO's lockout-observation
window rather the the default domain setting.

This is finally enough to get some of the PSO password_lockout tests
to pass.

Signed-off-by: Tim Beale <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
selftest/knownfail.d/password_lockout
source4/dsdb/common/util.c
source4/rpc_server/samr/dcesrv_samr.c

index 115dc533da495a07205f11793d650208f35d743b..eebab10c86b46a1ffd3a568d5549ae72f101373f 100644 (file)
@@ -1,5 +1,3 @@
-samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTests.test_pso_login_lockout_ntlm\(ad_dc_ntvfs\)
-samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTests.test_pso_login_lockout_krb5\(ad_dc_ntvfs\)
 samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTests.test_pso_userPassword_lockout_with_clear_change_krb5_ldap_userAccountControl\(ad_dc_ntvfs\)
 samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTests.test_pso_userPassword_lockout_with_clear_change_ntlm_ldap_lockoutTime\(ad_dc_ntvfs\)
 samba4.ldap.password_lockout.python\(ad_dc_ntvfs\).__main__.PasswordTests.test_pso_userPassword_lockout_with_clear_change_ntlm_samr\(ad_dc_ntvfs\)
index cc5890952944a067bf917376529317a0c9f097a4..c227c836d0461e66a597a32a1a49e506efbed4fc 100644 (file)
@@ -5246,13 +5246,47 @@ static int dsdb_effective_badPwdCount(const struct ldb_message *user_msg,
        }
 }
 
+/*
+ * Returns a user's PSO, or NULL if none was found
+ */
+static struct ldb_result *lookup_user_pso(struct ldb_context *sam_ldb,
+                                         TALLOC_CTX *mem_ctx,
+                                         const struct ldb_message *user_msg,
+                                         const char * const *attrs)
+{
+       struct ldb_result *res = NULL;
+       struct ldb_dn *pso_dn = NULL;
+       int ret;
+
+       /* if the user has a PSO that applies, then use the PSO's setting */
+       pso_dn = ldb_msg_find_attr_as_dn(sam_ldb, mem_ctx, user_msg,
+                                        "msDS-ResultantPSO");
+
+       if (pso_dn != NULL) {
+
+               ret = dsdb_search_dn(sam_ldb, mem_ctx, &res, pso_dn, attrs, 0);
+               if (ret != LDB_SUCCESS) {
+
+                       /*
+                        * log the error. The caller should fallback to using
+                        * the default domain password settings
+                        */
+                       DBG_ERR("Error retrieving msDS-ResultantPSO %s for %s",
+                               ldb_dn_get_linearized(pso_dn),
+                               ldb_dn_get_linearized(user_msg->dn));
+               }
+               talloc_free(pso_dn);
+       }
+       return res;
+}
+
 /*
  * Return the effective badPwdCount
  *
  * This requires that the user_msg have (if present):
  *  - badPasswordTime
  *  - badPwdCount
- *
+ *  - msDS-ResultantPSO
  */
 int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb,
                                       TALLOC_CTX *mem_ctx,
@@ -5261,8 +5295,27 @@ int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb,
 {
        struct timeval tv_now = timeval_current();
        NTTIME now = timeval_to_nttime(&tv_now);
-       int64_t lockOutObservationWindow = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn,
-                                                             "lockOutObservationWindow", NULL);
+       int64_t lockOutObservationWindow;
+       struct ldb_result *res = NULL;
+       const char *attrs[] = { "msDS-LockoutObservationWindow",
+                               NULL };
+
+       res = lookup_user_pso(sam_ldb, mem_ctx, user_msg, attrs);
+
+       if (res != NULL) {
+               lockOutObservationWindow =
+                       ldb_msg_find_attr_as_int(res->msgs[0],
+                                                "msDS-LockoutObservationWindow",
+                                                 0);
+               talloc_free(res);
+       } else {
+
+               /* no PSO was found, lookup the default domain setting */
+               lockOutObservationWindow =
+                        samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn,
+                                           "lockOutObservationWindow", NULL);
+       }
+
        return dsdb_effective_badPwdCount(user_msg, lockOutObservationWindow, now);
 }
 
index bf086f772d3407fce515ec5653df934f5010052c..eccf9d2b8c0c1b29d8de0f1b81025013bb1ba385 100644 (file)
@@ -2781,6 +2781,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
                                                      "badPasswordTime",
                                                      "logonCount",
                                                      "pwdLastSet",
+                                                     "msDS-ResultantPSO",
                                                      "msDS-UserPasswordExpiryTimeComputed",
                                                      "accountExpires",
                                                      "userAccountControl",
@@ -2887,6 +2888,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA
                static const char * const attrs2[] = {"lastLogon",
                                                      "lastLogoff",
                                                      "pwdLastSet",
+                                                     "msDS-ResultantPSO",
                                                      "msDS-UserPasswordExpiryTimeComputed",
                                                      "accountExpires",
                                                      "sAMAccountName",