From 1ebfe6957fd8995e7c7690c842e196e6c649b6db Mon Sep 17 00:00:00 2001 From: Tim Beale Date: Thu, 19 Apr 2018 13:51:36 +1200 Subject: [PATCH] dsdb: Use PSO maxPwdAge for operational msDS-PasswordExpiryTimeComputed When calculating the Password-Expiry-Time, we should use the PSO's max-password-age setting, if one applies to the user. This is code may be inefficient, as it may repeat the PSO-lookup work several times (once for each constructed attribute that tries to use it). For now, I've gone for the simplest code change, and efficiency can be addressed in a subsequent patch (once we have a good test to measure it). Signed-off-by: Tim Beale Reviewed-by: Andrew Bartlett Reviewed-by: Garming Sam --- selftest/knownfail.d/password_settings | 2 - source4/dsdb/samdb/ldb_modules/operational.c | 43 ++++++++++++++++++-- 2 files changed, 39 insertions(+), 6 deletions(-) delete mode 100644 selftest/knownfail.d/password_settings diff --git a/selftest/knownfail.d/password_settings b/selftest/knownfail.d/password_settings deleted file mode 100644 index b23f3f9ef42..00000000000 --- a/selftest/knownfail.d/password_settings +++ /dev/null @@ -1,2 +0,0 @@ -samba4.ldap.password_settings.python.password_settings.PasswordSettingsTestCase.test_pso_max_age\(ad_dc_ntvfs\) - diff --git a/source4/dsdb/samdb/ldb_modules/operational.c b/source4/dsdb/samdb/ldb_modules/operational.c index e72ebb9415d..c2968a4b802 100644 --- a/source4/dsdb/samdb/ldb_modules/operational.c +++ b/source4/dsdb/samdb/ldb_modules/operational.c @@ -695,11 +695,43 @@ static int construct_msds_keyversionnumber(struct ldb_module *module, _UF_TRUST_ACCOUNTS \ ) + +/* + * Returns the Effective-MaximumPasswordAge for a user + */ +static int64_t get_user_max_pwd_age(struct ldb_module *module, + struct ldb_message *user_msg, + struct ldb_request *parent, + struct ldb_dn *nc_root) +{ + int ret; + struct ldb_message *pso = NULL; + struct ldb_context *ldb = ldb_module_get_ctx(module); + + /* if a PSO applies to the user, use its maxPwdAge */ + ret = get_pso_for_user(module, user_msg, parent, &pso); + if (ret != LDB_SUCCESS) { + + /* log the error, but fallback to the domain default */ + DBG_ERR("Error retrieving PSO for %s\n", + ldb_dn_get_linearized(user_msg->dn)); + } + + if (pso != NULL) { + return ldb_msg_find_attr_as_int64(pso, + "msDS-MaximumPasswordAge", 0); + } + + /* otherwise return the default domain value */ + return samdb_search_int64(ldb, user_msg, 0, nc_root, "maxPwdAge", NULL); +} + /* calculate msDS-UserPasswordExpiryTimeComputed */ static NTTIME get_msds_user_password_expiry_time_computed(struct ldb_module *module, struct ldb_message *msg, + struct ldb_request *parent, struct ldb_dn *domain_dn) { int64_t pwdLastSet, maxPwdAge; @@ -742,8 +774,7 @@ static NTTIME get_msds_user_password_expiry_time_computed(struct ldb_module *mod * maxPwdAge: -9223372036854775808 (-0x8000000000000000ULL) * */ - maxPwdAge = samdb_search_int64(ldb_module_get_ctx(module), msg, 0, - domain_dn, "maxPwdAge", NULL); + maxPwdAge = get_user_max_pwd_age(module, msg, parent, domain_dn); if (maxPwdAge >= -864000000000) { /* * This is not really possible... @@ -859,7 +890,9 @@ static int construct_msds_user_account_control_computed(struct ldb_module *modul if (!(userAccountControl & _UF_NO_EXPIRY_ACCOUNTS)) { NTTIME must_change_time = get_msds_user_password_expiry_time_computed(module, - msg, nc_root); + msg, + parent, + nc_root); /* check for expired password */ if (must_change_time < now) { msDS_User_Account_Control_Computed |= UF_PASSWORD_EXPIRED; @@ -900,7 +933,7 @@ static int construct_msds_user_password_expiry_time_computed(struct ldb_module * password_expiry_time = get_msds_user_password_expiry_time_computed(module, msg, - nc_root); + parent, nc_root); return samdb_msg_add_int64(ldb, msg->elements, msg, @@ -993,6 +1026,7 @@ static int pso_search_by_sids(struct ldb_module *module, TALLOC_CTX *mem_ctx, "msDS-PasswordSettingsPrecedence", "objectGUID", "msDS-LockoutDuration", + "msDS-MaximumPasswordAge", NULL }; @@ -1246,6 +1280,7 @@ static const char *user_account_control_computed_attrs[] = static const char *user_password_expiry_time_computed_attrs[] = { "pwdLastSet", + PSO_ATTR_DEPENDENCIES, NULL }; -- 2.47.2