diff options
-rw-r--r-- | source3/smbd/chgpasswd.c | 26 |
1 files changed, 21 insertions, 5 deletions
diff --git a/source3/smbd/chgpasswd.c b/source3/smbd/chgpasswd.c index 5a179dbf47..bb30519319 100644 --- a/source3/smbd/chgpasswd.c +++ b/source3/smbd/chgpasswd.c @@ -1010,15 +1010,31 @@ static BOOL check_passwd_history(SAM_ACCOUNT *sampass, const char *plaintext) NTSTATUS change_oem_password(SAM_ACCOUNT *hnd, char *old_passwd, char *new_passwd, BOOL as_root) { BOOL ret; - uint32 min_len; + uint32 min_len, min_age; struct passwd *pass = NULL; const char *username = pdb_get_username(hnd); + time_t last_change_time = pdb_get_pass_last_set_time(hnd); time_t can_change_time = pdb_get_pass_can_change_time(hnd); - if ((can_change_time != 0) && (time(NULL) < can_change_time)) { - DEBUG(1, ("user %s cannot change password now, must wait until %s\n", - username, http_timestring(can_change_time))); - return NT_STATUS_ACCOUNT_RESTRICTION; + if (pdb_get_account_policy(AP_MIN_PASSWORD_AGE, &min_age)) { + /* + * Windows calculates the minimum password age check + * dynamically, it basically ignores the pwdcanchange + * timestamp. Do likewise. + */ + if (last_change_time + min_age > time(NULL)) { + DEBUG(1, ("user %s cannot change password now, must " + "wait until %s\n", username, + http_timestring(last_change_time+min_age))); + return NT_STATUS_ACCOUNT_RESTRICTION; + } + } else { + if ((can_change_time != 0) && (time(NULL) < can_change_time)) { + DEBUG(1, ("user %s cannot change password now, must " + "wait until %s\n", username, + http_timestring(can_change_time))); + return NT_STATUS_ACCOUNT_RESTRICTION; + } } if (pdb_get_account_policy(AP_MIN_PASSWORD_LEN, &min_len) && (str_charnum(new_passwd) < min_len)) { |