Blame SOURCES/0063-DP-SYSDB-Move-the-code-to-set-initgrExpireTimestamp-.patch

8d3578
From 3543c929ea2264ae83cc5de195a33b48da5dfd16 Mon Sep 17 00:00:00 2001
8d3578
From: Jakub Hrozek <jhrozek@redhat.com>
8d3578
Date: Mon, 1 Jul 2019 14:15:29 +0200
8d3578
Subject: [PATCH 63/64] DP/SYSDB: Move the code to set initgrExpireTimestamp to
8d3578
 a reusable function
8d3578
8d3578
Related: https://pagure.io/SSSD/sssd/issue/4012
8d3578
8d3578
Because the initgroups request can, especially in the case of IPA provider
8d3578
with trusts, contain several sub-requests that run some provider-specific
8d3578
initgroups internally and then run post-processing AND because at the same
8d3578
time concurrent requests in the responder need to be sure that the
8d3578
initgrExpireTimestamp is only increased when the initgroups request is
8d3578
really done, we only set the initgrExpireTimestamp in the DP when the
8d3578
request finishes.
8d3578
8d3578
This means, the background refresh task needs to also set the
8d3578
initgrExpireTimestamp attribute on its own as well. This patch so far
8d3578
splits the helper function into a reusable one so it can later be used
8d3578
by the background refresh.
8d3578
8d3578
For examples of the bugs caused by the initgrTimestamp being set before
8d3578
the whole multi-step operation finishes, please see tickets #3744
8d3578
or #2634.
8d3578
8d3578
Reviewed-by: Sumit Bose <sbose@redhat.com>
8d3578
(cherry picked from commit 7a08d1dea8cb9148ba1afe13f4d4567229c9b381)
8d3578
8d3578
Reviewed-by: Sumit Bose <sbose@redhat.com>
8d3578
---
8d3578
 src/db/sysdb.h                             | 11 ++++
8d3578
 src/db/sysdb_ops.c                         | 70 ++++++++++++++++++++++
8d3578
 src/providers/data_provider/dp_target_id.c | 55 ++---------------
8d3578
 3 files changed, 85 insertions(+), 51 deletions(-)
8d3578
8d3578
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
8d3578
index 15df1a726..dfd91f6b8 100644
8d3578
--- a/src/db/sysdb.h
8d3578
+++ b/src/db/sysdb.h
8d3578
@@ -1122,6 +1122,17 @@ errno_t sysdb_store_override(struct sss_domain_info *domain,
8d3578
                              enum sysdb_member_type type,
8d3578
                              struct sysdb_attrs *attrs, struct ldb_dn *obj_dn);
8d3578
 
8d3578
+/*
8d3578
+ * Cache the time of last initgroups invocation. Typically this is not done when
8d3578
+ * the provider-specific request itself finishes, because currently the request
8d3578
+ * might hand over to other requests from a different provider (e.g. an AD user
8d3578
+ * from a trusted domain might need to also call an IPA request to fetch the
8d3578
+ * external groups). Instead, the caller of the initgroups request, typically
8d3578
+ * the DP or the periodical refresh task sets the timestamp.
8d3578
+ */
8d3578
+errno_t sysdb_set_initgr_expire_timestamp(struct sss_domain_info *domain,
8d3578
+                                          const char *name_or_upn_or_sid);
8d3578
+
8d3578
 /* Password caching function.
8d3578
  * If you are in a transaction ignore sysdb and pass in the handle.
8d3578
  * If you are not in a transaction pass NULL in handle and provide sysdb,
8d3578
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
8d3578
index 340062f6f..fa3842d8f 100644
8d3578
--- a/src/db/sysdb_ops.c
8d3578
+++ b/src/db/sysdb_ops.c
8d3578
@@ -3259,6 +3259,76 @@ int sysdb_cache_password(struct sss_domain_info *domain,
8d3578
                                    SSS_AUTHTOK_TYPE_PASSWORD, 0);
8d3578
 }
8d3578
 
8d3578
+static errno_t set_initgroups_expire_attribute(struct sss_domain_info *domain,
8d3578
+                                               const char *name)
8d3578
+{
8d3578
+    errno_t ret;
8d3578
+    time_t cache_timeout;
8d3578
+    struct sysdb_attrs *attrs;
8d3578
+
8d3578
+    attrs = sysdb_new_attrs(NULL);
8d3578
+    if (attrs == NULL) {
8d3578
+        return ENOMEM;
8d3578
+    }
8d3578
+
8d3578
+    cache_timeout = domain->user_timeout
8d3578
+                        ? time(NULL) + domain->user_timeout
8d3578
+                        : 0;
8d3578
+
8d3578
+    ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, cache_timeout);
8d3578
+    if (ret != EOK) {
8d3578
+        DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n");
8d3578
+        goto done;
8d3578
+    }
8d3578
+
8d3578
+    ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP);
8d3578
+    if (ret != EOK) {
8d3578
+        DEBUG(SSSDBG_CRIT_FAILURE,
8d3578
+              "Failed to set initgroups expire attribute\n");
8d3578
+        goto done;
8d3578
+    }
8d3578
+
8d3578
+done:
8d3578
+    talloc_zfree(attrs);
8d3578
+    return ret;
8d3578
+}
8d3578
+
8d3578
+errno_t sysdb_set_initgr_expire_timestamp(struct sss_domain_info *domain,
8d3578
+                                          const char *name_or_upn_or_sid)
8d3578
+{
8d3578
+    const char *cname;
8d3578
+    errno_t ret;
8d3578
+    TALLOC_CTX *tmp_ctx;
8d3578
+
8d3578
+    tmp_ctx = talloc_new(NULL);
8d3578
+    if (!tmp_ctx) {
8d3578
+        return ENOMEM;
8d3578
+    }
8d3578
+
8d3578
+    ret = sysdb_get_real_name(tmp_ctx, domain, name_or_upn_or_sid, &cname);
8d3578
+    if (ret == ENOENT) {
8d3578
+        /* No point trying to bump timestamp of an entry that does not exist..*/
8d3578
+        ret = EOK;
8d3578
+        goto done;
8d3578
+    } else if (ret != EOK) {
8d3578
+        cname = name_or_upn_or_sid;
8d3578
+        DEBUG(SSSDBG_MINOR_FAILURE,
8d3578
+              "Failed to canonicalize name, using [%s]\n", name_or_upn_or_sid);
8d3578
+    }
8d3578
+
8d3578
+    ret = set_initgroups_expire_attribute(domain, cname);
8d3578
+    if (ret != EOK) {
8d3578
+        DEBUG(SSSDBG_MINOR_FAILURE,
8d3578
+              "Cannot set the initgroups expire attribute [%d]: %s\n",
8d3578
+              ret, sss_strerror(ret));
8d3578
+    }
8d3578
+
8d3578
+    ret = EOK;
8d3578
+done:
8d3578
+    talloc_free(tmp_ctx);
8d3578
+    return ret;
8d3578
+}
8d3578
+
8d3578
 /* =Custom Search================== */
8d3578
 
8d3578
 int sysdb_search_custom(TALLOC_CTX *mem_ctx,
8d3578
diff --git a/src/providers/data_provider/dp_target_id.c b/src/providers/data_provider/dp_target_id.c
8d3578
index d123638eb..591ddd32d 100644
8d3578
--- a/src/providers/data_provider/dp_target_id.c
8d3578
+++ b/src/providers/data_provider/dp_target_id.c
8d3578
@@ -372,69 +372,22 @@ done:
8d3578
     talloc_free(tmp_ctx);
8d3578
 }
8d3578
 
8d3578
-static errno_t set_initgroups_expire_attribute(struct sss_domain_info *domain,
8d3578
-                                               const char *name)
8d3578
-{
8d3578
-    errno_t ret;
8d3578
-    time_t cache_timeout;
8d3578
-    struct sysdb_attrs *attrs;
8d3578
-
8d3578
-    attrs = sysdb_new_attrs(NULL);
8d3578
-    if (attrs == NULL) {
8d3578
-        return ENOMEM;
8d3578
-    }
8d3578
-
8d3578
-    cache_timeout = domain->user_timeout
8d3578
-                        ? time(NULL) + domain->user_timeout
8d3578
-                        : 0;
8d3578
-
8d3578
-    ret = sysdb_attrs_add_time_t(attrs, SYSDB_INITGR_EXPIRE, cache_timeout);
8d3578
-    if (ret != EOK) {
8d3578
-        DEBUG(SSSDBG_CRIT_FAILURE, "Could not set up attrs\n");
8d3578
-        goto done;
8d3578
-    }
8d3578
-
8d3578
-    ret = sysdb_set_user_attr(domain, name, attrs, SYSDB_MOD_REP);
8d3578
-    if (ret != EOK) {
8d3578
-        DEBUG(SSSDBG_CRIT_FAILURE,
8d3578
-              "Failed to set initgroups expire attribute\n");
8d3578
-        goto done;
8d3578
-    }
8d3578
-
8d3578
-done:
8d3578
-    talloc_zfree(attrs);
8d3578
-    return ret;
8d3578
-}
8d3578
-
8d3578
 static void dp_req_initgr_pp_set_initgr_timestamp(struct dp_initgr_ctx *ctx,
8d3578
                                                   struct dp_reply_std *reply)
8d3578
 {
8d3578
     errno_t ret;
8d3578
-    const char *cname;
8d3578
 
8d3578
     if (reply->dp_error != DP_ERR_OK || reply->error != EOK) {
8d3578
         /* Only bump the timestamp on successful lookups */
8d3578
         return;
8d3578
     }
8d3578
 
8d3578
-    ret = sysdb_get_real_name(ctx,
8d3578
-                              ctx->domain_info,
8d3578
-                              ctx->filter_value,
8d3578
-                              &cname);
8d3578
-    if (ret == ENOENT) {
8d3578
-        /* No point trying to bump timestamp of an entry that does not exist..*/
8d3578
-        return;
8d3578
-    } else if (ret != EOK) {
8d3578
-        cname = ctx->filter_value;
8d3578
-        DEBUG(SSSDBG_MINOR_FAILURE,
8d3578
-              "Failed to canonicalize name, using [%s]\n", cname);
8d3578
-    }
8d3578
-
8d3578
-    ret = set_initgroups_expire_attribute(ctx->domain_info, cname);
8d3578
+    ret = sysdb_set_initgr_expire_timestamp(ctx->domain_info,
8d3578
+                                            ctx->filter_value);
8d3578
     if (ret != EOK) {
8d3578
         DEBUG(SSSDBG_MINOR_FAILURE,
8d3578
-              "Cannot set the initgroups expire attribute [%d]: %s\n",
8d3578
-              ret, sss_strerror(ret));
8d3578
+              "Failed to set initgroups expiration for [%s]\n",
8d3578
+              ctx->filter_value);
8d3578
     }
8d3578
 }
8d3578
 
8d3578
-- 
8d3578
2.20.1
8d3578