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

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