dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

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

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