]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
user-record: don't refuse login when last pw change time is in the future
authorLennart Poettering <lennart@poettering.net>
Wed, 2 Sep 2020 14:37:42 +0000 (16:37 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 21 Sep 2020 16:02:35 +0000 (18:02 +0200)
The RTC is like just off, it's a weird system state, let's continue
without requiring pw change.

src/home/homed-home.c
src/home/pam_systemd_home.c
src/shared/user-record-show.c
src/shared/user-record.c

index e4757c724a30a39ff973e30cbb35ff3d4e40a2da..328ec32fd368485fe4a66509b6ca2bb6a16485be 100644 (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);
index db182dc999786801c86643d8f9c01872ea4cef21..8fe52f44aac607cb8c6683e04fbeaaded485629e 100644 (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;
index 7839f6c2b8f738c59ad5144f5e3c77bd1debad1d..9046fafcb2e3b481e8a28b6b4d5fceff38d784dd 100644 (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;
index e14a8f44cb232581aba566d00a3e6f6bb8e6651b..4149205b8abd9736f49929bd5fe2288b3d37e009 100644 (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) {