dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0180-SYSDB-Introduce-_search_-users-groups-_by_timestamp.patch

bb7cd1
From 11c34233ac7385c6f2a65c5cc57dfefb1cae48cd Mon Sep 17 00:00:00 2001
bb7cd1
From: =?UTF-8?q?Fabiano=20Fid=C3=AAncio?= <fidencio@redhat.com>
bb7cd1
Date: Wed, 7 Jun 2017 15:07:10 +0200
bb7cd1
Subject: [PATCH 180/181] SYSDB: Introduce
bb7cd1
 _search_{users,groups}_by_timestamp()
bb7cd1
MIME-Version: 1.0
bb7cd1
Content-Type: text/plain; charset=UTF-8
bb7cd1
Content-Transfer-Encoding: 8bit
bb7cd1
bb7cd1
These new two sysdb methods are going to be used, at least for now,
bb7cd1
uniquely and exclusively in the cleanup task.
bb7cd1
bb7cd1
The reason for adding those is that during the cleanup task a timestamp
bb7cd1
search is done in the persistent cache, which doesn't have the updated
bb7cd1
timestamps, returning then a wrong result that ends up in having all the
bb7cd1
users being removed from the cache.
bb7cd1
bb7cd1
The persistent cache doesn't have its entries' timestamps updated
bb7cd1
because those are kept updated in the timestamp cache, therefore these
bb7cd1
new two methods end up doing:
bb7cd1
- if the timestamp cache is present:
bb7cd1
  - search for the entries solely in the timestamp cache;
bb7cd1
  - get the needed attributes from these entries from the persistent
bb7cd1
    cache;
bb7cd1
- otherwise:
bb7cd1
  - search for the entries in the persistent cache;
bb7cd1
  - merge its results with timestamp cache's results;
bb7cd1
bb7cd1
Related:
bb7cd1
https://pagure.io/SSSD/sssd/issue/3369
bb7cd1
bb7cd1
Signed-off-by: Fabiano FidĂȘncio <fidencio@redhat.com>
bb7cd1
bb7cd1
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
bb7cd1
(cherry picked from commit 41708e1e500e7cada3d3e606aa2b8b9869a5c734)
bb7cd1
---
bb7cd1
 src/db/sysdb.h     |  14 +++++
bb7cd1
 src/db/sysdb_ops.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++++++
bb7cd1
 2 files changed, 192 insertions(+)
bb7cd1
bb7cd1
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
bb7cd1
index 62c561be9452a284a8ddf8ebb45720265852c8b0..21d6cf4fc90a050e203e1609be5ee267a618dda9 100644
bb7cd1
--- a/src/db/sysdb.h
bb7cd1
+++ b/src/db/sysdb.h
bb7cd1
@@ -1142,6 +1142,13 @@ int sysdb_search_users(TALLOC_CTX *mem_ctx,
bb7cd1
                        size_t *msgs_count,
bb7cd1
                        struct ldb_message ***msgs);
bb7cd1
 
bb7cd1
+int sysdb_search_users_by_timestamp(TALLOC_CTX *mem_ctx,
bb7cd1
+                                    struct sss_domain_info *domain,
bb7cd1
+                                    const char *sub_filter,
bb7cd1
+                                    const char **attrs,
bb7cd1
+                                    size_t *_msgs_count,
bb7cd1
+                                    struct ldb_message ***_msgs);
bb7cd1
+
bb7cd1
 int sysdb_delete_user(struct sss_domain_info *domain,
bb7cd1
                       const char *name, uid_t uid);
bb7cd1
 
bb7cd1
@@ -1152,6 +1159,13 @@ int sysdb_search_groups(TALLOC_CTX *mem_ctx,
bb7cd1
                         size_t *msgs_count,
bb7cd1
                         struct ldb_message ***msgs);
bb7cd1
 
bb7cd1
+int sysdb_search_groups_by_timestamp(TALLOC_CTX *mem_ctx,
bb7cd1
+                                     struct sss_domain_info *domain,
bb7cd1
+                                     const char *sub_filter,
bb7cd1
+                                     const char **attrs,
bb7cd1
+                                     size_t *_msgs_count,
bb7cd1
+                                     struct ldb_message ***_msgs);
bb7cd1
+
bb7cd1
 int sysdb_delete_group(struct sss_domain_info *domain,
bb7cd1
                        const char *name, gid_t gid);
bb7cd1
 
bb7cd1
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
bb7cd1
index ed936f0cb1a37155aabef96db1d267eb03ec0ed9..7ca6575ce75dab7805236c9f48dbf28a2f3946d2 100644
bb7cd1
--- a/src/db/sysdb_ops.c
bb7cd1
+++ b/src/db/sysdb_ops.c
bb7cd1
@@ -374,6 +374,58 @@ enum sysdb_obj_type {
bb7cd1
     SYSDB_GROUP
bb7cd1
 };
bb7cd1
 
bb7cd1
+static errno_t cleanup_dn_filter(TALLOC_CTX *mem_ctx,
bb7cd1
+                                struct ldb_result *ts_res,
bb7cd1
+                                const char *object_class,
bb7cd1
+                                const char *filter,
bb7cd1
+                                char **_dn_filter)
bb7cd1
+{
bb7cd1
+    TALLOC_CTX *tmp_ctx;
bb7cd1
+    char *dn_filter;
bb7cd1
+    errno_t ret;
bb7cd1
+
bb7cd1
+    if (ts_res->count == 0) {
bb7cd1
+        *_dn_filter = NULL;
bb7cd1
+        return EOK;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    tmp_ctx = talloc_new(NULL);
bb7cd1
+    if (tmp_ctx == NULL) {
bb7cd1
+        return ENOMEM;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    dn_filter = talloc_asprintf(tmp_ctx, "(&(%s)%s(|", object_class, filter);
bb7cd1
+    if (dn_filter == NULL) {
bb7cd1
+        ret = ENOMEM;
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    for (size_t i = 0; i < ts_res->count; i++) {
bb7cd1
+        dn_filter = talloc_asprintf_append(
bb7cd1
+                                    dn_filter,
bb7cd1
+                                    "(%s=%s)",
bb7cd1
+                                    SYSDB_DN,
bb7cd1
+                                    ldb_dn_get_linearized(ts_res->msgs[i]->dn));
bb7cd1
+        if (dn_filter == NULL) {
bb7cd1
+            ret = ENOMEM;
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    dn_filter = talloc_asprintf_append(dn_filter, "))");
bb7cd1
+    if (dn_filter == NULL) {
bb7cd1
+        ret = ENOMEM;
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    *_dn_filter = talloc_steal(mem_ctx, dn_filter);
bb7cd1
+    ret = EOK;
bb7cd1
+
bb7cd1
+done:
bb7cd1
+    talloc_zfree(tmp_ctx);
bb7cd1
+    return ret;
bb7cd1
+}
bb7cd1
+
bb7cd1
 static int sysdb_search_by_name(TALLOC_CTX *mem_ctx,
bb7cd1
                                 struct sss_domain_info *domain,
bb7cd1
                                 const char *name,
bb7cd1
@@ -3503,6 +3555,69 @@ int sysdb_search_users(TALLOC_CTX *mem_ctx,
bb7cd1
                                          attrs);
bb7cd1
 }
bb7cd1
 
bb7cd1
+int sysdb_search_users_by_timestamp(TALLOC_CTX *mem_ctx,
bb7cd1
+                                    struct sss_domain_info *domain,
bb7cd1
+                                    const char *sub_filter,
bb7cd1
+                                    const char **attrs,
bb7cd1
+                                    size_t *_msgs_count,
bb7cd1
+                                    struct ldb_message ***_msgs)
bb7cd1
+{
bb7cd1
+    TALLOC_CTX *tmp_ctx;
bb7cd1
+    struct ldb_result *res;
bb7cd1
+    struct ldb_result ts_res;
bb7cd1
+    struct ldb_message **msgs;
bb7cd1
+    size_t msgs_count;
bb7cd1
+    char *dn_filter = NULL;
bb7cd1
+    errno_t ret;
bb7cd1
+
bb7cd1
+    tmp_ctx = talloc_new(NULL);
bb7cd1
+    if (tmp_ctx == NULL) {
bb7cd1
+        return ENOMEM;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = sysdb_search_ts_users(tmp_ctx, domain, sub_filter, NULL, &ts_res);
bb7cd1
+    if (ret == ERR_NO_TS) {
bb7cd1
+        ret = sysdb_cache_search_users(tmp_ctx, domain, domain->sysdb->ldb,
bb7cd1
+                                       sub_filter, attrs, &msgs_count, &msgs);
bb7cd1
+        if (ret != EOK) {
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+
bb7cd1
+       ret = sysdb_merge_msg_list_ts_attrs(domain->sysdb, msgs_count, msgs, attrs);
bb7cd1
+       if (ret != EOK) {
bb7cd1
+           goto done;
bb7cd1
+       }
bb7cd1
+
bb7cd1
+       goto immediately;
bb7cd1
+    } else if (ret != EOK) {
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = cleanup_dn_filter(tmp_ctx, &ts_res, SYSDB_UC, sub_filter, &dn_filter);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = sysdb_search_ts_matches(tmp_ctx, domain->sysdb, attrs,
bb7cd1
+                                  &ts_res, dn_filter, &res;;
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    msgs_count = res->count;
bb7cd1
+    msgs = res->msgs;
bb7cd1
+
bb7cd1
+immediately:
bb7cd1
+    *_msgs_count = msgs_count;
bb7cd1
+    *_msgs = talloc_steal(mem_ctx, msgs);
bb7cd1
+
bb7cd1
+    ret = EOK;
bb7cd1
+
bb7cd1
+done:
bb7cd1
+    talloc_free(tmp_ctx);
bb7cd1
+    return ret;
bb7cd1
+}
bb7cd1
+
bb7cd1
 int sysdb_search_ts_users(TALLOC_CTX *mem_ctx,
bb7cd1
                           struct sss_domain_info *domain,
bb7cd1
                           const char *sub_filter,
bb7cd1
@@ -3720,6 +3835,69 @@ int sysdb_search_groups(TALLOC_CTX *mem_ctx,
bb7cd1
                                          attrs);
bb7cd1
 }
bb7cd1
 
bb7cd1
+int sysdb_search_groups_by_timestamp(TALLOC_CTX *mem_ctx,
bb7cd1
+                                     struct sss_domain_info *domain,
bb7cd1
+                                     const char *sub_filter,
bb7cd1
+                                     const char **attrs,
bb7cd1
+                                     size_t *_msgs_count,
bb7cd1
+                                     struct ldb_message ***_msgs)
bb7cd1
+{
bb7cd1
+    TALLOC_CTX *tmp_ctx;
bb7cd1
+    struct ldb_result *res;
bb7cd1
+    struct ldb_result ts_res;
bb7cd1
+    struct ldb_message **msgs;
bb7cd1
+    size_t msgs_count;
bb7cd1
+    char *dn_filter = NULL;
bb7cd1
+    errno_t ret;
bb7cd1
+
bb7cd1
+    tmp_ctx = talloc_new(NULL);
bb7cd1
+    if (tmp_ctx == NULL) {
bb7cd1
+        return ENOMEM;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = sysdb_search_ts_groups(tmp_ctx, domain, sub_filter, NULL, &ts_res);
bb7cd1
+    if (ret == ERR_NO_TS) {
bb7cd1
+        ret = sysdb_cache_search_groups(tmp_ctx, domain, domain->sysdb->ldb,
bb7cd1
+                                        sub_filter, attrs, &msgs_count, &msgs);
bb7cd1
+        if (ret != EOK) {
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+
bb7cd1
+       ret = sysdb_merge_msg_list_ts_attrs(domain->sysdb, msgs_count, msgs, attrs);
bb7cd1
+       if (ret != EOK) {
bb7cd1
+           goto done;
bb7cd1
+       }
bb7cd1
+
bb7cd1
+       goto immediately;
bb7cd1
+    } else if (ret != EOK) {
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = cleanup_dn_filter(tmp_ctx, &ts_res, SYSDB_GC, sub_filter, &dn_filter);
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    ret = sysdb_search_ts_matches(tmp_ctx, domain->sysdb, attrs,
bb7cd1
+                                  &ts_res, dn_filter, &res;;
bb7cd1
+    if (ret != EOK) {
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    msgs_count = res->count;
bb7cd1
+    msgs = res->msgs;
bb7cd1
+
bb7cd1
+immediately:
bb7cd1
+    *_msgs_count = msgs_count;
bb7cd1
+    *_msgs = talloc_steal(mem_ctx, msgs);
bb7cd1
+
bb7cd1
+    ret = EOK;
bb7cd1
+
bb7cd1
+done:
bb7cd1
+    talloc_free(tmp_ctx);
bb7cd1
+    return ret;
bb7cd1
+}
bb7cd1
+
bb7cd1
 int sysdb_search_ts_groups(TALLOC_CTX *mem_ctx,
bb7cd1
                            struct sss_domain_info *domain,
bb7cd1
                            const char *sub_filter,
bb7cd1
-- 
bb7cd1
2.9.4
bb7cd1