user-record: don't refuse login when last pw change time is in the future

The RTC is like just off, it's a weird system state, let's continue
without requiring pw change.
This commit is contained in:
Lennart Poettering 2020-09-02 16:37:42 +02:00
parent 61a29a020c
commit 3e0b54867e
4 changed files with 19 additions and 1 deletions

View File

@ -1574,7 +1574,7 @@ static int home_may_change_password(
assert(h);
r = user_record_test_password_change_required(h->record);
if (IN_SET(r, -EKEYREVOKED, -EOWNERDEAD, -EKEYEXPIRED))
if (IN_SET(r, -EKEYREVOKED, -EOWNERDEAD, -EKEYEXPIRED, -ESTALE))
return 0; /* expired in some form, but changing is allowed */
if (IN_SET(r, -EKEYREJECTED, -EROFS))
return sd_bus_error_setf(error, SD_BUS_ERROR_ACCESS_DENIED, "Expiration settings of account %s do not allow changing of password.", h->user_name);

View File

@ -904,6 +904,11 @@ _public_ PAM_EXTERN int pam_sm_acct_mgmt(
(void) pam_prompt(handle, PAM_ERROR_MSG, NULL, "Password will expire soon, please change.");
break;
case -ESTALE:
/* If the system clock is wrong, let's log but continue */
pam_syslog(handle, LOG_WARNING, "Couldn't check if password change is required, last change is in the future, system clock likely wrong.");
break;
case -EROFS:
/* All good, just means the password if we wanted to change we couldn't, but we don't need to */
break;

View File

@ -124,6 +124,10 @@ void user_record_show(UserRecord *hr, bool show_full_group_info) {
printf(" Password OK: %schange not permitted%s\n", ansi_highlight_yellow(), ansi_normal());
break;
case -ESTALE:
printf(" Password OK: %slast password change in future%s\n", ansi_highlight_yellow(), ansi_normal());
break;
default:
if (r < 0) {
errno = -r;

View File

@ -2061,6 +2061,7 @@ int user_record_test_password_change_required(UserRecord *h) {
-EKEYEXPIRED: Password is about to expire, warn user
-ENETDOWN: Record has expiration info but no password change timestamp
-EROFS: No password change required nor permitted
-ESTALE: RTC likely incorrect, last password change is in the future
0: No password change required, but permitted
*/
@ -2070,6 +2071,14 @@ int user_record_test_password_change_required(UserRecord *h) {
n = now(CLOCK_REALTIME);
/* Password change in the future? Then our RTC is likely incorrect */
if (h->last_password_change_usec != UINT64_MAX &&
h->last_password_change_usec > n &&
(h->password_change_min_usec != UINT64_MAX ||
h->password_change_max_usec != UINT64_MAX ||
h->password_change_inactive_usec != UINT64_MAX))
return -ESTALE;
/* Then, let's check if password changing is currently allowed at all */
if (h->password_change_min_usec != UINT64_MAX) {