Blame SOURCES/0001-ldap-update-shadow-last-change-in-sysdb-as-well.patch

3b3728
From d7da2966f5931bac3b17f42e251adbbb7e793619 Mon Sep 17 00:00:00 2001
3b3728
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
3b3728
Date: Thu, 8 Dec 2022 15:14:05 +0100
3b3728
Subject: [PATCH] ldap: update shadow last change in sysdb as well
3b3728
MIME-Version: 1.0
3b3728
Content-Type: text/plain; charset=UTF-8
3b3728
Content-Transfer-Encoding: 8bit
3b3728
3b3728
Otherwise pam can use the changed information whe id chaching is
3b3728
enabled, so next authentication that fits into the id timeout
3b3728
(5 seconds by default) will still sees the password as expired.
3b3728
3b3728
Resolves: https://github.com/SSSD/sssd/issues/6477
3b3728
3b3728
Reviewed-by: Sumit Bose <sbose@redhat.com>
3b3728
Reviewed-by: Tomáš Halman <thalman@redhat.com>
3b3728
(cherry picked from commit 7e8b97c14b8ef218d6ea23214be28d25dba13886)
3b3728
---
3b3728
 src/db/sysdb.h                 |  4 ++++
3b3728
 src/db/sysdb_ops.c             | 32 ++++++++++++++++++++++++++++++++
3b3728
 src/providers/ldap/ldap_auth.c | 21 ++++++++++++++++-----
3b3728
 3 files changed, 52 insertions(+), 5 deletions(-)
3b3728
3b3728
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
3b3728
index 7c666f5c4..06b44f5ba 100644
3b3728
--- a/src/db/sysdb.h
3b3728
+++ b/src/db/sysdb.h
3b3728
@@ -1061,6 +1061,10 @@ int sysdb_set_user_attr(struct sss_domain_info *domain,
3b3728
                         struct sysdb_attrs *attrs,
3b3728
                         int mod_op);
3b3728
 
3b3728
+errno_t sysdb_update_user_shadow_last_change(struct sss_domain_info *domain,
3b3728
+                                             const char *name,
3b3728
+                                             const char *attrname);
3b3728
+
3b3728
 /* Replace group attrs */
3b3728
 int sysdb_set_group_attr(struct sss_domain_info *domain,
3b3728
                          const char *name,
3b3728
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
3b3728
index 0d6f2d5cd..ed0df9872 100644
3b3728
--- a/src/db/sysdb_ops.c
3b3728
+++ b/src/db/sysdb_ops.c
3b3728
@@ -1485,6 +1485,38 @@ done:
3b3728
     return ret;
3b3728
 }
3b3728
 
3b3728
+errno_t sysdb_update_user_shadow_last_change(struct sss_domain_info *domain,
3b3728
+                                             const char *name,
3b3728
+                                             const char *attrname)
3b3728
+{
3b3728
+    struct sysdb_attrs *attrs;
3b3728
+    char *value;
3b3728
+    errno_t ret;
3b3728
+
3b3728
+    attrs = sysdb_new_attrs(NULL);
3b3728
+    if (attrs == NULL) {
3b3728
+        return ENOMEM;
3b3728
+    }
3b3728
+
3b3728
+    /* The attribute contains number of days since the epoch */
3b3728
+    value = talloc_asprintf(attrs, "%ld", (long)time(NULL)/86400);
3b3728
+    if (value == NULL) {
3b3728
+        ret = ENOMEM;
3b3728
+        goto done;
3b3728
+    }
3b3728
+
3b3728
+    ret = sysdb_attrs_add_string(attrs, attrname, value);
3b3728
+    if (ret != EOK) {
3b3728
+        goto done;
3b3728
+    }
3b3728
+
3b3728
+    ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP);
3b3728
+
3b3728
+done:
3b3728
+    talloc_free(attrs);
3b3728
+    return ret;
3b3728
+}
3b3728
+
3b3728
 /* =Replace-Attributes-On-Group=========================================== */
3b3728
 
3b3728
 int sysdb_set_group_attr(struct sss_domain_info *domain,
3b3728
diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c
3b3728
index 6404a9d3a..96b9d6df4 100644
3b3728
--- a/src/providers/ldap/ldap_auth.c
3b3728
+++ b/src/providers/ldap/ldap_auth.c
3b3728
@@ -1240,6 +1240,7 @@ struct sdap_pam_chpass_handler_state {
3b3728
     struct pam_data *pd;
3b3728
     struct sdap_handle *sh;
3b3728
     char *dn;
3b3728
+    enum pwexpire pw_expire_type;
3b3728
 };
3b3728
 
3b3728
 static void sdap_pam_chpass_handler_auth_done(struct tevent_req *subreq);
3b3728
@@ -1339,7 +1340,6 @@ static void sdap_pam_chpass_handler_auth_done(struct tevent_req *subreq)
3b3728
 {
3b3728
     struct sdap_pam_chpass_handler_state *state;
3b3728
     struct tevent_req *req;
3b3728
-    enum pwexpire pw_expire_type;
3b3728
     void *pw_expire_data;
3b3728
     size_t msg_len;
3b3728
     uint8_t *msg;
3b3728
@@ -1349,7 +1349,7 @@ static void sdap_pam_chpass_handler_auth_done(struct tevent_req *subreq)
3b3728
     state = tevent_req_data(req, struct sdap_pam_chpass_handler_state);
3b3728
 
3b3728
     ret = auth_recv(subreq, state, &state->sh, &state->dn,
3b3728
-                    &pw_expire_type, &pw_expire_data);
3b3728
+                    &state->pw_expire_type, &pw_expire_data);
3b3728
     talloc_free(subreq);
3b3728
 
3b3728
     if ((ret == EOK || ret == ERR_PASSWORD_EXPIRED) &&
3b3728
@@ -1361,7 +1361,7 @@ static void sdap_pam_chpass_handler_auth_done(struct tevent_req *subreq)
3b3728
     }
3b3728
 
3b3728
     if (ret == EOK) {
3b3728
-        switch (pw_expire_type) {
3b3728
+        switch (state->pw_expire_type) {
3b3728
         case PWEXPIRE_SHADOW:
3b3728
             ret = check_pwexpire_shadow(pw_expire_data, time(NULL), NULL);
3b3728
             break;
3b3728
@@ -1381,7 +1381,8 @@ static void sdap_pam_chpass_handler_auth_done(struct tevent_req *subreq)
3b3728
             break;
3b3728
         default:
3b3728
             DEBUG(SSSDBG_CRIT_FAILURE,
3b3728
-                  "Unknown password expiration type %d.\n", pw_expire_type);
3b3728
+                  "Unknown password expiration type %d.\n",
3b3728
+                  state->pw_expire_type);
3b3728
             state->pd->pam_status = PAM_SYSTEM_ERR;
3b3728
             goto done;
3b3728
         }
3b3728
@@ -1392,7 +1393,8 @@ static void sdap_pam_chpass_handler_auth_done(struct tevent_req *subreq)
3b3728
         case ERR_PASSWORD_EXPIRED:
3b3728
             DEBUG(SSSDBG_TRACE_LIBS,
3b3728
                   "user [%s] successfully authenticated.\n", state->dn);
3b3728
-            ret = sdap_pam_chpass_handler_change_step(state, req, pw_expire_type);
3b3728
+            ret = sdap_pam_chpass_handler_change_step(state, req,
3b3728
+                                                      state->pw_expire_type);
3b3728
             if (ret != EOK) {
3b3728
                 DEBUG(SSSDBG_OP_FAILURE,
3b3728
                       "sdap_pam_chpass_handler_change_step() failed.\n");
3b3728
@@ -1506,6 +1508,15 @@ static void sdap_pam_chpass_handler_chpass_done(struct tevent_req *subreq)
3b3728
 
3b3728
     switch (ret) {
3b3728
     case EOK:
3b3728
+        if (state->pw_expire_type == PWEXPIRE_SHADOW) {
3b3728
+            ret = sysdb_update_user_shadow_last_change(state->be_ctx->domain,
3b3728
+                    state->pd->user, SYSDB_SHADOWPW_LASTCHANGE);
3b3728
+            if (ret != EOK) {
3b3728
+                state->pd->pam_status = PAM_SYSTEM_ERR;
3b3728
+                goto done;
3b3728
+            }
3b3728
+        }
3b3728
+
3b3728
         state->pd->pam_status = PAM_SUCCESS;
3b3728
         break;
3b3728
     case ERR_CHPASS_DENIED:
3b3728
-- 
3b3728
2.37.3
3b3728