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

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