|
|
8d3578 |
From e935d41ec6c187c61e0a6f8c353276fbf69780a5 Mon Sep 17 00:00:00 2001
|
|
|
8d3578 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
8d3578 |
Date: Tue, 28 May 2019 14:56:05 +0200
|
|
|
8d3578 |
Subject: [PATCH 45/64] SYSDB: Add sysdb_search_with_ts_attr
|
|
|
8d3578 |
|
|
|
8d3578 |
Adds a new public sysdb call sysdb_search_with_ts_attr() that allows to
|
|
|
8d3578 |
search on the timestamp cache attributes, but merge back persistent
|
|
|
8d3578 |
cache attributes. The converse also works, when searching the persistent
|
|
|
8d3578 |
cache the timestamp attributes or even entries matches only in the
|
|
|
8d3578 |
timestamp cache are merged.
|
|
|
8d3578 |
|
|
|
8d3578 |
What does not work is AND-ed complex filter that contains both
|
|
|
8d3578 |
attributes from the timestamp cache and the persistent cache because
|
|
|
8d3578 |
the searches use the same filter, which doesn't match. We would need to
|
|
|
8d3578 |
decompose the filter ourselves.
|
|
|
8d3578 |
|
|
|
8d3578 |
Because matching and merging the results can be time-consuming, two
|
|
|
8d3578 |
flags are provided:
|
|
|
8d3578 |
SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER that only searches the timestamp
|
|
|
8d3578 |
cache, but merges back the corresponding entries from the persistent
|
|
|
8d3578 |
cache
|
|
|
8d3578 |
SYSDB_SEARCH_WITH_TS_ONLY_SYSDB_FILTER that only searches the
|
|
|
8d3578 |
persistent cache but merges back the attributes from the timestamp
|
|
|
8d3578 |
cache
|
|
|
8d3578 |
|
|
|
8d3578 |
Related:
|
|
|
8d3578 |
https://pagure.io/SSSD/sssd/issue/4012
|
|
|
8d3578 |
|
|
|
8d3578 |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
8d3578 |
(cherry picked from commit db99504a5295ae1f9bc5166133c8f21e4510c676)
|
|
|
8d3578 |
|
|
|
8d3578 |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
8d3578 |
---
|
|
|
8d3578 |
src/db/sysdb.h | 12 ++
|
|
|
8d3578 |
src/db/sysdb_ops.c | 16 +-
|
|
|
8d3578 |
src/db/sysdb_private.h | 10 ++
|
|
|
8d3578 |
src/db/sysdb_search.c | 231 +++++++++++++++++++++++--
|
|
|
8d3578 |
src/tests/cmocka/test_sysdb_ts_cache.c | 198 +++++++++++++++++++++
|
|
|
8d3578 |
5 files changed, 446 insertions(+), 21 deletions(-)
|
|
|
8d3578 |
|
|
|
8d3578 |
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
|
|
|
8d3578 |
index 56468a169..15df1a726 100644
|
|
|
8d3578 |
--- a/src/db/sysdb.h
|
|
|
8d3578 |
+++ b/src/db/sysdb.h
|
|
|
8d3578 |
@@ -1190,6 +1190,18 @@ int sysdb_search_users(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
size_t *msgs_count,
|
|
|
8d3578 |
struct ldb_message ***msgs);
|
|
|
8d3578 |
|
|
|
8d3578 |
+#define SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER 0x0001
|
|
|
8d3578 |
+#define SYSDB_SEARCH_WITH_TS_ONLY_SYSDB_FILTER 0x0002
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+errno_t sysdb_search_with_ts_attr(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
+ struct sss_domain_info *domain,
|
|
|
8d3578 |
+ struct ldb_dn *base_dn,
|
|
|
8d3578 |
+ enum ldb_scope scope,
|
|
|
8d3578 |
+ int optflags,
|
|
|
8d3578 |
+ const char *filter,
|
|
|
8d3578 |
+ const char *attrs[],
|
|
|
8d3578 |
+ struct ldb_result **_result);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
int sysdb_search_users_by_timestamp(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
struct sss_domain_info *domain,
|
|
|
8d3578 |
const char *sub_filter,
|
|
|
8d3578 |
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
|
|
|
8d3578 |
index d05950732..340062f6f 100644
|
|
|
8d3578 |
--- a/src/db/sysdb_ops.c
|
|
|
8d3578 |
+++ b/src/db/sysdb_ops.c
|
|
|
8d3578 |
@@ -261,14 +261,14 @@ done:
|
|
|
8d3578 |
|
|
|
8d3578 |
/* =Search-Entry========================================================== */
|
|
|
8d3578 |
|
|
|
8d3578 |
-static int sysdb_cache_search_entry(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
- struct ldb_context *ldb,
|
|
|
8d3578 |
- struct ldb_dn *base_dn,
|
|
|
8d3578 |
- enum ldb_scope scope,
|
|
|
8d3578 |
- const char *filter,
|
|
|
8d3578 |
- const char **attrs,
|
|
|
8d3578 |
- size_t *_msgs_count,
|
|
|
8d3578 |
- struct ldb_message ***_msgs)
|
|
|
8d3578 |
+int sysdb_cache_search_entry(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
+ struct ldb_context *ldb,
|
|
|
8d3578 |
+ struct ldb_dn *base_dn,
|
|
|
8d3578 |
+ enum ldb_scope scope,
|
|
|
8d3578 |
+ const char *filter,
|
|
|
8d3578 |
+ const char **attrs,
|
|
|
8d3578 |
+ size_t *_msgs_count,
|
|
|
8d3578 |
+ struct ldb_message ***_msgs)
|
|
|
8d3578 |
{
|
|
|
8d3578 |
TALLOC_CTX *tmp_ctx;
|
|
|
8d3578 |
struct ldb_result *res;
|
|
|
8d3578 |
diff --git a/src/db/sysdb_private.h b/src/db/sysdb_private.h
|
|
|
8d3578 |
index f3d34dd6f..7063d4594 100644
|
|
|
8d3578 |
--- a/src/db/sysdb_private.h
|
|
|
8d3578 |
+++ b/src/db/sysdb_private.h
|
|
|
8d3578 |
@@ -253,6 +253,16 @@ errno_t sysdb_merge_msg_list_ts_attrs(struct sysdb_ctx *ctx,
|
|
|
8d3578 |
struct ldb_result *sss_merge_ldb_results(struct ldb_result *res,
|
|
|
8d3578 |
struct ldb_result *subres);
|
|
|
8d3578 |
|
|
|
8d3578 |
+/* Search Entry in an ldb cache */
|
|
|
8d3578 |
+int sysdb_cache_search_entry(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
+ struct ldb_context *ldb,
|
|
|
8d3578 |
+ struct ldb_dn *base_dn,
|
|
|
8d3578 |
+ enum ldb_scope scope,
|
|
|
8d3578 |
+ const char *filter,
|
|
|
8d3578 |
+ const char **attrs,
|
|
|
8d3578 |
+ size_t *_msgs_count,
|
|
|
8d3578 |
+ struct ldb_message ***_msgs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
/* Search Entry in the timestamp cache */
|
|
|
8d3578 |
int sysdb_search_ts_entry(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
struct sysdb_ctx *sysdb,
|
|
|
8d3578 |
diff --git a/src/db/sysdb_search.c b/src/db/sysdb_search.c
|
|
|
8d3578 |
index f0918bf9a..a71c43112 100644
|
|
|
8d3578 |
--- a/src/db/sysdb_search.c
|
|
|
8d3578 |
+++ b/src/db/sysdb_search.c
|
|
|
8d3578 |
@@ -68,6 +68,29 @@ static errno_t merge_ts_attr(struct ldb_message *ts_msg,
|
|
|
8d3578 |
return EOK;
|
|
|
8d3578 |
}
|
|
|
8d3578 |
|
|
|
8d3578 |
+static errno_t merge_all_ts_attrs(struct ldb_message *ts_msg,
|
|
|
8d3578 |
+ struct ldb_message *sysdb_msg,
|
|
|
8d3578 |
+ const char *want_attrs[])
|
|
|
8d3578 |
+{
|
|
|
8d3578 |
+ int ret;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* Deliberately start from 2 in order to not merge
|
|
|
8d3578 |
+ * objectclass/objectcategory and avoid breaking MPGs where the OC might
|
|
|
8d3578 |
+ * be made up
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+ for (size_t c = 2; sysdb_ts_cache_attrs[c]; c++) {
|
|
|
8d3578 |
+ ret = merge_ts_attr(ts_msg, sysdb_msg,
|
|
|
8d3578 |
+ sysdb_ts_cache_attrs[c], want_attrs);
|
|
|
8d3578 |
+ if (ret != EOK) {
|
|
|
8d3578 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
8d3578 |
+ "Cannot merge ts attr %s\n", sysdb_ts_cache_attrs[c]);
|
|
|
8d3578 |
+ return ret;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ return EOK;
|
|
|
8d3578 |
+}
|
|
|
8d3578 |
+
|
|
|
8d3578 |
static errno_t merge_msg_ts_attrs(struct sysdb_ctx *sysdb,
|
|
|
8d3578 |
struct ldb_message *sysdb_msg,
|
|
|
8d3578 |
const char *attrs[])
|
|
|
8d3578 |
@@ -114,21 +137,46 @@ static errno_t merge_msg_ts_attrs(struct sysdb_ctx *sysdb,
|
|
|
8d3578 |
return EIO;
|
|
|
8d3578 |
}
|
|
|
8d3578 |
|
|
|
8d3578 |
- /* Deliberately start from 2 in order to not merge
|
|
|
8d3578 |
- * objectclass/objectcategory and avoid breaking MPGs where the OC might
|
|
|
8d3578 |
- * be made up
|
|
|
8d3578 |
- */
|
|
|
8d3578 |
- for (size_t c = 2; sysdb_ts_cache_attrs[c]; c++) {
|
|
|
8d3578 |
- ret = merge_ts_attr(ts_msgs[0], sysdb_msg,
|
|
|
8d3578 |
- sysdb_ts_cache_attrs[c], attrs);
|
|
|
8d3578 |
- if (ret != EOK) {
|
|
|
8d3578 |
- DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
8d3578 |
- "Cannot merge ts attr %s\n", sysdb_ts_cache_attrs[c]);
|
|
|
8d3578 |
- goto done;
|
|
|
8d3578 |
- }
|
|
|
8d3578 |
+ ret = merge_all_ts_attrs(ts_msgs[0], sysdb_msg, attrs);
|
|
|
8d3578 |
+done:
|
|
|
8d3578 |
+ talloc_zfree(tmp_ctx);
|
|
|
8d3578 |
+ return ret;
|
|
|
8d3578 |
+}
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+static errno_t merge_msg_sysdb_attrs(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
+ struct sysdb_ctx *sysdb,
|
|
|
8d3578 |
+ struct ldb_message *ts_msg,
|
|
|
8d3578 |
+ struct ldb_message **_sysdb_msg,
|
|
|
8d3578 |
+ const char *attrs[])
|
|
|
8d3578 |
+{
|
|
|
8d3578 |
+ errno_t ret;
|
|
|
8d3578 |
+ TALLOC_CTX *tmp_ctx;
|
|
|
8d3578 |
+ size_t msgs_count;
|
|
|
8d3578 |
+ struct ldb_message **sysdb_msgs;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ tmp_ctx = talloc_new(NULL);
|
|
|
8d3578 |
+ if (tmp_ctx == NULL) {
|
|
|
8d3578 |
+ return ENOMEM;
|
|
|
8d3578 |
}
|
|
|
8d3578 |
|
|
|
8d3578 |
- ret = EOK;
|
|
|
8d3578 |
+ ret = sysdb_cache_search_entry(tmp_ctx, sysdb->ldb, ts_msg->dn, LDB_SCOPE_BASE,
|
|
|
8d3578 |
+ NULL, attrs, &msgs_count, &sysdb_msgs);
|
|
|
8d3578 |
+ if (ret != EOK) {
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ if (msgs_count != 1) {
|
|
|
8d3578 |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
8d3578 |
+ "Expected 1 result for base search, got %zu\n", msgs_count);
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ret = merge_all_ts_attrs(ts_msg, sysdb_msgs[0], attrs);
|
|
|
8d3578 |
+ if (ret != EOK) {
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ *_sysdb_msg = talloc_steal(mem_ctx, sysdb_msgs[0]);
|
|
|
8d3578 |
done:
|
|
|
8d3578 |
talloc_zfree(tmp_ctx);
|
|
|
8d3578 |
return ret;
|
|
|
8d3578 |
@@ -166,6 +214,50 @@ errno_t sysdb_merge_res_ts_attrs(struct sysdb_ctx *ctx,
|
|
|
8d3578 |
return EOK;
|
|
|
8d3578 |
}
|
|
|
8d3578 |
|
|
|
8d3578 |
+static errno_t merge_res_sysdb_attrs(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
+ struct sysdb_ctx *ctx,
|
|
|
8d3578 |
+ struct ldb_result *ts_res,
|
|
|
8d3578 |
+ struct ldb_result **_ts_cache_res,
|
|
|
8d3578 |
+ const char *attrs[])
|
|
|
8d3578 |
+{
|
|
|
8d3578 |
+ errno_t ret;
|
|
|
8d3578 |
+ struct ldb_result *ts_cache_res = NULL;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ if (ts_res == NULL || ctx->ldb_ts == NULL) {
|
|
|
8d3578 |
+ return EOK;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ts_cache_res = talloc_zero(mem_ctx, struct ldb_result);
|
|
|
8d3578 |
+ if (ts_cache_res == NULL) {
|
|
|
8d3578 |
+ return ENOMEM;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+ ts_cache_res->count = ts_res->count;
|
|
|
8d3578 |
+ ts_cache_res->msgs = talloc_zero_array(ts_cache_res,
|
|
|
8d3578 |
+ struct ldb_message *,
|
|
|
8d3578 |
+ ts_res->count);
|
|
|
8d3578 |
+ if (ts_cache_res->msgs == NULL) {
|
|
|
8d3578 |
+ talloc_free(ts_cache_res);
|
|
|
8d3578 |
+ return ENOMEM;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ for (size_t c = 0; c < ts_res->count; c++) {
|
|
|
8d3578 |
+ ret = merge_msg_sysdb_attrs(ts_cache_res->msgs,
|
|
|
8d3578 |
+ ctx,
|
|
|
8d3578 |
+ ts_res->msgs[c],
|
|
|
8d3578 |
+ &ts_cache_res->msgs[c], attrs);
|
|
|
8d3578 |
+ if (ret != EOK) {
|
|
|
8d3578 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
8d3578 |
+ "Cannot merge sysdb cache values for %s\n",
|
|
|
8d3578 |
+ ldb_dn_get_linearized(ts_res->msgs[c]->dn));
|
|
|
8d3578 |
+ /* non-fatal, we just get only the non-timestamp attrs */
|
|
|
8d3578 |
+ continue;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ *_ts_cache_res = ts_cache_res;
|
|
|
8d3578 |
+ return EOK;
|
|
|
8d3578 |
+}
|
|
|
8d3578 |
+
|
|
|
8d3578 |
errno_t sysdb_merge_msg_list_ts_attrs(struct sysdb_ctx *ctx,
|
|
|
8d3578 |
size_t msgs_count,
|
|
|
8d3578 |
struct ldb_message **msgs,
|
|
|
8d3578 |
@@ -543,6 +635,119 @@ done:
|
|
|
8d3578 |
return ret;
|
|
|
8d3578 |
}
|
|
|
8d3578 |
|
|
|
8d3578 |
+errno_t sysdb_search_with_ts_attr(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
+ struct sss_domain_info *domain,
|
|
|
8d3578 |
+ struct ldb_dn *base_dn,
|
|
|
8d3578 |
+ enum ldb_scope scope,
|
|
|
8d3578 |
+ int optflags,
|
|
|
8d3578 |
+ const char *filter,
|
|
|
8d3578 |
+ const char *attrs[],
|
|
|
8d3578 |
+ struct ldb_result **_res)
|
|
|
8d3578 |
+{
|
|
|
8d3578 |
+ TALLOC_CTX *tmp_ctx = NULL;
|
|
|
8d3578 |
+ struct ldb_result *res;
|
|
|
8d3578 |
+ errno_t ret;
|
|
|
8d3578 |
+ struct ldb_message **ts_msgs = NULL;
|
|
|
8d3578 |
+ struct ldb_result *ts_cache_res = NULL;
|
|
|
8d3578 |
+ size_t ts_count;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ if (filter == NULL) {
|
|
|
8d3578 |
+ return EINVAL;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ tmp_ctx = talloc_new(NULL);
|
|
|
8d3578 |
+ if (tmp_ctx == NULL) {
|
|
|
8d3578 |
+ return ENOMEM;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ res = talloc_zero(tmp_ctx, struct ldb_result);
|
|
|
8d3578 |
+ if (res == NULL) {
|
|
|
8d3578 |
+ ret = ENOMEM;
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ if (optflags & SYSDB_SEARCH_WITH_TS_ONLY_SYSDB_FILTER) {
|
|
|
8d3578 |
+ /* We only care about searching the persistent db */
|
|
|
8d3578 |
+ ts_cache_res = talloc_zero(tmp_ctx, struct ldb_result);
|
|
|
8d3578 |
+ if (ts_cache_res == NULL) {
|
|
|
8d3578 |
+ ret = ENOMEM;
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+ ts_cache_res->count = 0;
|
|
|
8d3578 |
+ ts_cache_res->msgs = NULL;
|
|
|
8d3578 |
+ } else {
|
|
|
8d3578 |
+ /* Because the timestamp database does not contain all the
|
|
|
8d3578 |
+ * attributes, we need to search the persistent db for each
|
|
|
8d3578 |
+ * of the entries found and merge the results
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+ struct ldb_result ts_res;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* We assume that some of the attributes are more up-to-date in
|
|
|
8d3578 |
+ * timestamps db and we're supposed to search by them, so let's
|
|
|
8d3578 |
+ * first search the timestamp db
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+ ret = sysdb_search_ts_entry(tmp_ctx, domain->sysdb, base_dn,
|
|
|
8d3578 |
+ scope, filter, attrs,
|
|
|
8d3578 |
+ &ts_count, &ts_msgs);
|
|
|
8d3578 |
+ if (ret == ENOENT) {
|
|
|
8d3578 |
+ ts_count = 0;
|
|
|
8d3578 |
+ } else if (ret != EOK) {
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ memset(&ts_res, 0, sizeof(struct ldb_result));
|
|
|
8d3578 |
+ ts_res.count = ts_count;
|
|
|
8d3578 |
+ ts_res.msgs = ts_msgs;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* Overlay the results from the main cache with the ts attrs */
|
|
|
8d3578 |
+ ret = merge_res_sysdb_attrs(tmp_ctx,
|
|
|
8d3578 |
+ domain->sysdb,
|
|
|
8d3578 |
+ &ts_res,
|
|
|
8d3578 |
+ &ts_cache_res,
|
|
|
8d3578 |
+ attrs);
|
|
|
8d3578 |
+ if (ret != EOK) {
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ if (optflags & SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER) {
|
|
|
8d3578 |
+ /* The filter only contains timestamp attrs, no need to search the
|
|
|
8d3578 |
+ * persistent db
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+ if (ts_cache_res) {
|
|
|
8d3578 |
+ res->count = ts_cache_res->count;
|
|
|
8d3578 |
+ res->msgs = talloc_steal(res, ts_cache_res->msgs);
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+ } else {
|
|
|
8d3578 |
+ /* Because some of the attributes being searched might exist in the persistent
|
|
|
8d3578 |
+ * database only, we also search the persistent db
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+ size_t count;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ret = sysdb_search_entry(res, domain->sysdb, base_dn, scope,
|
|
|
8d3578 |
+ filter, attrs, &count, &res->msgs);
|
|
|
8d3578 |
+ if (ret == ENOENT) {
|
|
|
8d3578 |
+ res->count = 0;
|
|
|
8d3578 |
+ } else if (ret != EOK) {
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+ res->count = count; /* Just to cleanly assign size_t to unsigned */
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ res = sss_merge_ldb_results(res, ts_cache_res);
|
|
|
8d3578 |
+ if (res == NULL) {
|
|
|
8d3578 |
+ ret = ENOMEM;
|
|
|
8d3578 |
+ goto done;
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+ }
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ *_res = talloc_steal(mem_ctx, res);
|
|
|
8d3578 |
+ ret = EOK;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+done:
|
|
|
8d3578 |
+ talloc_zfree(tmp_ctx);
|
|
|
8d3578 |
+ return ret;
|
|
|
8d3578 |
+}
|
|
|
8d3578 |
+
|
|
|
8d3578 |
static errno_t sysdb_enum_dn_filter(TALLOC_CTX *mem_ctx,
|
|
|
8d3578 |
struct ldb_result *ts_res,
|
|
|
8d3578 |
const char *name_filter,
|
|
|
8d3578 |
diff --git a/src/tests/cmocka/test_sysdb_ts_cache.c b/src/tests/cmocka/test_sysdb_ts_cache.c
|
|
|
8d3578 |
index fdf9935da..d2296d1b8 100644
|
|
|
8d3578 |
--- a/src/tests/cmocka/test_sysdb_ts_cache.c
|
|
|
8d3578 |
+++ b/src/tests/cmocka/test_sysdb_ts_cache.c
|
|
|
8d3578 |
@@ -1411,6 +1411,201 @@ static void test_sysdb_zero_now(void **state)
|
|
|
8d3578 |
assert_true(cache_expire_ts > TEST_CACHE_TIMEOUT);
|
|
|
8d3578 |
}
|
|
|
8d3578 |
|
|
|
8d3578 |
+static void test_sysdb_search_with_ts(void **state)
|
|
|
8d3578 |
+{
|
|
|
8d3578 |
+ int ret;
|
|
|
8d3578 |
+ struct sysdb_ts_test_ctx *test_ctx = talloc_get_type_abort(*state,
|
|
|
8d3578 |
+ struct sysdb_ts_test_ctx);
|
|
|
8d3578 |
+ struct ldb_result *res = NULL;
|
|
|
8d3578 |
+ struct ldb_dn *base_dn;
|
|
|
8d3578 |
+ const char *attrs[] = { SYSDB_NAME,
|
|
|
8d3578 |
+ SYSDB_OBJECTCATEGORY,
|
|
|
8d3578 |
+ SYSDB_GIDNUM,
|
|
|
8d3578 |
+ SYSDB_CACHE_EXPIRE,
|
|
|
8d3578 |
+ NULL };
|
|
|
8d3578 |
+ struct sysdb_attrs *group_attrs = NULL;
|
|
|
8d3578 |
+ char *filter;
|
|
|
8d3578 |
+ uint64_t cache_expire_sysdb;
|
|
|
8d3578 |
+ uint64_t cache_expire_ts;
|
|
|
8d3578 |
+ size_t count;
|
|
|
8d3578 |
+ struct ldb_message **msgs;
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ base_dn = sysdb_base_dn(test_ctx->tctx->dom->sysdb, test_ctx);
|
|
|
8d3578 |
+ assert_non_null(base_dn);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* Nothing must be stored in either cache at the beginning of the test */
|
|
|
8d3578 |
+ ret = sysdb_search_with_ts_attr(test_ctx,
|
|
|
8d3578 |
+ test_ctx->tctx->dom,
|
|
|
8d3578 |
+ base_dn,
|
|
|
8d3578 |
+ LDB_SCOPE_SUBTREE,
|
|
|
8d3578 |
+ 0,
|
|
|
8d3578 |
+ SYSDB_NAME"=*",
|
|
|
8d3578 |
+ attrs,
|
|
|
8d3578 |
+ &res;;
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+ assert_int_equal(res->count, 0);
|
|
|
8d3578 |
+ talloc_free(res);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ group_attrs = create_modstamp_attrs(test_ctx, TEST_MODSTAMP_1);
|
|
|
8d3578 |
+ assert_non_null(group_attrs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ret = sysdb_store_group(test_ctx->tctx->dom,
|
|
|
8d3578 |
+ TEST_GROUP_NAME,
|
|
|
8d3578 |
+ TEST_GROUP_GID,
|
|
|
8d3578 |
+ group_attrs,
|
|
|
8d3578 |
+ TEST_CACHE_TIMEOUT,
|
|
|
8d3578 |
+ TEST_NOW_1);
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+ talloc_zfree(group_attrs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ group_attrs = create_modstamp_attrs(test_ctx, TEST_MODSTAMP_1);
|
|
|
8d3578 |
+ assert_non_null(group_attrs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ret = sysdb_store_group(test_ctx->tctx->dom,
|
|
|
8d3578 |
+ TEST_GROUP_NAME_2,
|
|
|
8d3578 |
+ TEST_GROUP_GID_2,
|
|
|
8d3578 |
+ group_attrs,
|
|
|
8d3578 |
+ TEST_CACHE_TIMEOUT,
|
|
|
8d3578 |
+ TEST_NOW_2);
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+ talloc_zfree(group_attrs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* Bump the timestamps in the cache so that the ts cache
|
|
|
8d3578 |
+ * and sysdb differ
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ group_attrs = create_modstamp_attrs(test_ctx, TEST_MODSTAMP_1);
|
|
|
8d3578 |
+ assert_non_null(group_attrs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ret = sysdb_store_group(test_ctx->tctx->dom,
|
|
|
8d3578 |
+ TEST_GROUP_NAME,
|
|
|
8d3578 |
+ TEST_GROUP_GID,
|
|
|
8d3578 |
+ group_attrs,
|
|
|
8d3578 |
+ TEST_CACHE_TIMEOUT,
|
|
|
8d3578 |
+ TEST_NOW_3);
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ talloc_zfree(group_attrs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ group_attrs = create_modstamp_attrs(test_ctx, TEST_MODSTAMP_1);
|
|
|
8d3578 |
+ assert_non_null(group_attrs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ret = sysdb_store_group(test_ctx->tctx->dom,
|
|
|
8d3578 |
+ TEST_GROUP_NAME_2,
|
|
|
8d3578 |
+ TEST_GROUP_GID_2,
|
|
|
8d3578 |
+ group_attrs,
|
|
|
8d3578 |
+ TEST_CACHE_TIMEOUT,
|
|
|
8d3578 |
+ TEST_NOW_4);
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ talloc_zfree(group_attrs);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ get_gr_timestamp_attrs(test_ctx, TEST_GROUP_NAME,
|
|
|
8d3578 |
+ &cache_expire_sysdb, &cache_expire_ts);
|
|
|
8d3578 |
+ assert_int_equal(cache_expire_sysdb, TEST_CACHE_TIMEOUT + TEST_NOW_1);
|
|
|
8d3578 |
+ assert_int_equal(cache_expire_ts, TEST_CACHE_TIMEOUT + TEST_NOW_3);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ get_gr_timestamp_attrs(test_ctx, TEST_GROUP_NAME_2,
|
|
|
8d3578 |
+ &cache_expire_sysdb, &cache_expire_ts);
|
|
|
8d3578 |
+ assert_int_equal(cache_expire_sysdb, TEST_CACHE_TIMEOUT + TEST_NOW_2);
|
|
|
8d3578 |
+ assert_int_equal(cache_expire_ts, TEST_CACHE_TIMEOUT + TEST_NOW_4);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* Search for groups that don't expire until TEST_NOW_4 */
|
|
|
8d3578 |
+ filter = talloc_asprintf(test_ctx, SYSDB_CACHE_EXPIRE">=%d", TEST_NOW_4);
|
|
|
8d3578 |
+ assert_non_null(filter);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* This search should yield only one group (so, it needs to search the ts
|
|
|
8d3578 |
+ * cache to hit the TEST_NOW_4), but should return attributes merged from
|
|
|
8d3578 |
+ * both caches
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+ ret = sysdb_search_with_ts_attr(test_ctx,
|
|
|
8d3578 |
+ test_ctx->tctx->dom,
|
|
|
8d3578 |
+ base_dn,
|
|
|
8d3578 |
+ LDB_SCOPE_SUBTREE,
|
|
|
8d3578 |
+ 0,
|
|
|
8d3578 |
+ filter,
|
|
|
8d3578 |
+ attrs,
|
|
|
8d3578 |
+ &res;;
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+ assert_int_equal(res->count, 1);
|
|
|
8d3578 |
+ assert_int_equal(TEST_GROUP_GID_2, ldb_msg_find_attr_as_uint64(res->msgs[0],
|
|
|
8d3578 |
+ SYSDB_GIDNUM, 0));
|
|
|
8d3578 |
+ talloc_free(res);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /*
|
|
|
8d3578 |
+ * In contrast, sysdb_search_entry merges the timestamp attributes, but does
|
|
|
8d3578 |
+ * not search the timestamp cache
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+ ret = sysdb_search_entry(test_ctx,
|
|
|
8d3578 |
+ test_ctx->tctx->dom->sysdb,
|
|
|
8d3578 |
+ base_dn,
|
|
|
8d3578 |
+ LDB_SCOPE_SUBTREE,
|
|
|
8d3578 |
+ filter,
|
|
|
8d3578 |
+ attrs,
|
|
|
8d3578 |
+ &count,
|
|
|
8d3578 |
+ &msgs);
|
|
|
8d3578 |
+ assert_int_equal(ret, ENOENT);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* Should get the same result when searching by ts attrs only */
|
|
|
8d3578 |
+ ret = sysdb_search_with_ts_attr(test_ctx,
|
|
|
8d3578 |
+ test_ctx->tctx->dom,
|
|
|
8d3578 |
+ base_dn,
|
|
|
8d3578 |
+ LDB_SCOPE_SUBTREE,
|
|
|
8d3578 |
+ SYSDB_SEARCH_WITH_TS_ONLY_TS_FILTER,
|
|
|
8d3578 |
+ filter,
|
|
|
8d3578 |
+ attrs,
|
|
|
8d3578 |
+ &res;;
|
|
|
8d3578 |
+ talloc_zfree(filter);
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+ assert_int_equal(res->count, 1);
|
|
|
8d3578 |
+ assert_int_equal(TEST_GROUP_GID_2, ldb_msg_find_attr_as_uint64(res->msgs[0],
|
|
|
8d3578 |
+ SYSDB_GIDNUM, 0));
|
|
|
8d3578 |
+ talloc_free(res);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* We can also search in sysdb only as well, we should get back ts attrs */
|
|
|
8d3578 |
+ filter = talloc_asprintf(test_ctx, SYSDB_GIDNUM"=%d", TEST_GROUP_GID);
|
|
|
8d3578 |
+ assert_non_null(filter);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ret = sysdb_search_with_ts_attr(test_ctx,
|
|
|
8d3578 |
+ test_ctx->tctx->dom,
|
|
|
8d3578 |
+ base_dn,
|
|
|
8d3578 |
+ LDB_SCOPE_SUBTREE,
|
|
|
8d3578 |
+ SYSDB_SEARCH_WITH_TS_ONLY_SYSDB_FILTER,
|
|
|
8d3578 |
+ filter,
|
|
|
8d3578 |
+ attrs,
|
|
|
8d3578 |
+ &res;;
|
|
|
8d3578 |
+ talloc_zfree(filter);
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+ assert_int_equal(res->count, 1);
|
|
|
8d3578 |
+ assert_int_equal(TEST_GROUP_GID, ldb_msg_find_attr_as_uint64(res->msgs[0],
|
|
|
8d3578 |
+ SYSDB_GIDNUM, 0));
|
|
|
8d3578 |
+ assert_int_equal(TEST_CACHE_TIMEOUT + TEST_NOW_3,
|
|
|
8d3578 |
+ ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_CACHE_EXPIRE, 0));
|
|
|
8d3578 |
+ talloc_free(res);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ /* We can also search in both using an OR-filter. Note that an AND-filter is not possible
|
|
|
8d3578 |
+ * unless we deconstruct the filter..
|
|
|
8d3578 |
+ */
|
|
|
8d3578 |
+ filter = talloc_asprintf(test_ctx, "(|("SYSDB_GIDNUM"=%d)"
|
|
|
8d3578 |
+ "("SYSDB_CACHE_EXPIRE">=%d))",
|
|
|
8d3578 |
+ TEST_GROUP_GID, TEST_NOW_4);
|
|
|
8d3578 |
+ assert_non_null(filter);
|
|
|
8d3578 |
+
|
|
|
8d3578 |
+ ret = sysdb_search_with_ts_attr(test_ctx,
|
|
|
8d3578 |
+ test_ctx->tctx->dom,
|
|
|
8d3578 |
+ base_dn,
|
|
|
8d3578 |
+ LDB_SCOPE_SUBTREE,
|
|
|
8d3578 |
+ 0,
|
|
|
8d3578 |
+ filter,
|
|
|
8d3578 |
+ attrs,
|
|
|
8d3578 |
+ &res;;
|
|
|
8d3578 |
+ talloc_zfree(filter);
|
|
|
8d3578 |
+ assert_int_equal(ret, EOK);
|
|
|
8d3578 |
+ assert_int_equal(res->count, 2);
|
|
|
8d3578 |
+ talloc_free(res);
|
|
|
8d3578 |
+}
|
|
|
8d3578 |
+
|
|
|
8d3578 |
int main(int argc, const char *argv[])
|
|
|
8d3578 |
{
|
|
|
8d3578 |
int rv;
|
|
|
8d3578 |
@@ -1462,6 +1657,9 @@ int main(int argc, const char *argv[])
|
|
|
8d3578 |
cmocka_unit_test_setup_teardown(test_sysdb_zero_now,
|
|
|
8d3578 |
test_sysdb_ts_setup,
|
|
|
8d3578 |
test_sysdb_ts_teardown),
|
|
|
8d3578 |
+ cmocka_unit_test_setup_teardown(test_sysdb_search_with_ts,
|
|
|
8d3578 |
+ test_sysdb_ts_setup,
|
|
|
8d3578 |
+ test_sysdb_ts_teardown),
|
|
|
8d3578 |
};
|
|
|
8d3578 |
|
|
|
8d3578 |
/* Set debug level to invalid value so we can decide if -d 0 was used. */
|
|
|
8d3578 |
--
|
|
|
8d3578 |
2.20.1
|
|
|
8d3578 |
|