summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/db/sysdb.c142
-rw-r--r--src/db/sysdb.h10
-rw-r--r--src/tests/sysdb-tests.c40
3 files changed, 192 insertions, 0 deletions
diff --git a/src/db/sysdb.c b/src/db/sysdb.c
index ace31a46c..8806fe05f 100644
--- a/src/db/sysdb.c
+++ b/src/db/sysdb.c
@@ -1863,3 +1863,145 @@ errno_t sysdb_attrs_to_list(TALLOC_CTX *memctx,
*_list = list;
return EOK;
}
+
+errno_t sysdb_has_enumerated(struct sysdb_ctx *ctx,
+ struct sss_domain_info *dom,
+ bool *has_enumerated)
+{
+ errno_t ret;
+ int lret;
+ struct ldb_dn *base_dn;
+ struct ldb_result *res;
+ const char *attributes[2] = {SYSDB_HAS_ENUMERATED,
+ NULL};
+ TALLOC_CTX *tmpctx;
+
+
+ tmpctx = talloc_new(NULL);
+ if (!tmpctx) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ base_dn = ldb_dn_new_fmt(tmpctx, ctx->ldb,
+ SYSDB_DOM_BASE,
+ dom->name);
+ if (!base_dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ lret = ldb_search(ctx->ldb, tmpctx, &res, base_dn,
+ LDB_SCOPE_BASE, attributes, NULL);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ if (res->count == 0) {
+ /* This entry has not been populated in LDB
+ * This is a common case, as unlike LDAP,
+ * LDB does not need to have all of its parent
+ * objects actually exist.
+ * This object in the sysdb exists mostly just
+ * to contain this attribute.
+ */
+ *has_enumerated = false;
+ ret = EOK;
+ goto done;
+ } else if (res->count != 1) {
+ DEBUG(0, ("Corrupted database. "
+ "More than one entry for base search.\n"));
+ ret = EIO;
+ goto done;
+ }
+
+ /* Object existed. Return the stored value */
+ *has_enumerated = ldb_msg_find_attr_as_bool(res->msgs[0],
+ SYSDB_HAS_ENUMERATED,
+ false);
+
+ ret = EOK;
+
+done:
+ talloc_free(tmpctx);
+ return ret;
+}
+
+errno_t sysdb_set_enumerated(struct sysdb_ctx *ctx,
+ struct sss_domain_info *dom,
+ bool enumerated)
+{
+ errno_t ret;
+ int lret;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_message *msg;
+ struct ldb_result *res;
+ struct ldb_dn *dn;
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ dn = ldb_dn_new_fmt(tmp_ctx, ctx->ldb,
+ SYSDB_DOM_BASE,
+ dom->name);
+ if (!dn) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ lret = ldb_search(ctx->ldb, tmp_ctx, &res,
+ dn, LDB_SCOPE_BASE,
+ NULL, NULL);
+ if (lret != LDB_SUCCESS) {
+ ret = EIO;
+ goto done;
+ }
+
+ msg = ldb_msg_new(tmp_ctx);
+ if (!msg) {
+ ret = ENOMEM;
+ goto done;
+ }
+ msg->dn = dn;
+
+ if (res->count == 0) {
+ lret = ldb_msg_add_string(msg, "cn", dom->name);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+ } else if (res->count != 1) {
+ DEBUG(0, ("Got more than one reply for base search!\n"));
+ ret = EIO;
+ goto done;
+ } else {
+ lret = ldb_msg_add_empty(msg, SYSDB_HAS_ENUMERATED,
+ LDB_FLAG_MOD_REPLACE, NULL);
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+ }
+ lret = ldb_msg_add_fmt(msg, SYSDB_HAS_ENUMERATED, "%s",
+ enumerated?"TRUE":"FALSE");
+ if (lret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(lret);
+ goto done;
+ }
+
+ if (res->count) {
+ lret = ldb_modify(ctx->ldb, msg);
+ } else {
+ lret = ldb_add(ctx->ldb, msg);
+ }
+
+ ret = sysdb_error_to_errno(lret);
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index ed100b699..b5eed49b4 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -122,6 +122,8 @@
#define SYSDB_NETGR_FILTER "(&("SYSDB_NC")("SYSDB_NAME"=%s))"
#define SYSDB_NETGR_TRIPLES_FILTER "(|("SYSDB_NAME"=%s)("SYSDB_MEMBEROF"=%s))"
+#define SYSDB_HAS_ENUMERATED "has_enumerated"
+
#define SYSDB_DEFAULT_ATTRS SYSDB_LAST_UPDATE, \
SYSDB_CACHE_EXPIRE, \
SYSDB_INITGR_EXPIRE, \
@@ -700,4 +702,12 @@ errno_t sysdb_netgr_to_entries(TALLOC_CTX *mem_ctx,
errno_t sysdb_dn_sanitize(void *mem_ctx, const char *input,
char **sanitized);
+errno_t sysdb_has_enumerated(struct sysdb_ctx *ctx,
+ struct sss_domain_info *dom,
+ bool *has_enumerated);
+
+errno_t sysdb_set_enumerated(struct sysdb_ctx *ctx,
+ struct sss_domain_info *dom,
+ bool enumerated);
+
#endif /* __SYS_DB_H__ */
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index c6d1678ce..2beb25884 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -2860,6 +2860,43 @@ START_TEST(test_odd_characters)
}
END_TEST
+START_TEST(test_sysdb_has_enumerated)
+{
+ errno_t ret;
+ struct sysdb_test_ctx *test_ctx;
+ bool enumerated;
+
+ /* Setup */
+ ret = setup_sysdb_tests(&test_ctx);
+ fail_if(ret != EOK, "Could not set up the test");
+
+ ret = sysdb_has_enumerated(test_ctx->sysdb,
+ test_ctx->domain,
+ &enumerated);
+ fail_if(ret != EOK, "Error [%d][%s] checking enumeration",
+ ret, strerror(ret));
+
+ fail_if(enumerated, "Enumeration should default to false");
+
+ ret = sysdb_set_enumerated(test_ctx->sysdb,
+ test_ctx->domain,
+ true);
+ fail_if(ret != EOK, "Error [%d][%s] setting enumeration",
+ ret, strerror(ret));
+
+ /* Recheck enumeration status */
+ ret = sysdb_has_enumerated(test_ctx->sysdb,
+ test_ctx->domain,
+ &enumerated);
+ fail_if(ret != EOK, "Error [%d][%s] checking enumeration",
+ ret, strerror(ret));
+
+ fail_unless(enumerated, "Enumeration should have been set to true");
+
+ talloc_free(test_ctx);
+}
+END_TEST
+
Suite *create_sysdb_suite(void)
{
Suite *s = suite_create("sysdb");
@@ -2984,6 +3021,9 @@ Suite *create_sysdb_suite(void)
/* Test unusual characters */
tcase_add_test(tc_sysdb, test_odd_characters);
+ /* Test sysdb enumerated flag */
+ tcase_add_test(tc_sysdb, test_sysdb_has_enumerated);
+
/* ===== NETGROUP TESTS ===== */
/* Create a new netgroup */