1
0
mirror of https://github.com/samba-team/samba.git synced 2025-01-10 01:18:15 +03:00

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 <timbeale@catalyst.net.nz>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Garming Sam <garming@catalyst.net.nz>
This commit is contained in:
Tim Beale 2018-04-19 13:51:36 +12:00 committed by Garming Sam
parent 3b849f87f7
commit 1ebfe6957f
2 changed files with 39 additions and 6 deletions

View File

@ -1,2 +0,0 @@
samba4.ldap.password_settings.python.password_settings.PasswordSettingsTestCase.test_pso_max_age\(ad_dc_ntvfs\)

View File

@ -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
};