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

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