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

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