From 84bb9ec1bba8e60d1d87febd48749edd18e16787 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Wed, 8 Dec 2010 14:35:35 -0500 Subject: Add sysdb_has_enumerated and sysdb_set_enumerated helper functions Includes a unit test --- src/db/sysdb.c | 142 ++++++++++++++++++++++++++++++++++++++++++++++++ src/db/sysdb.h | 10 ++++ src/tests/sysdb-tests.c | 40 ++++++++++++++ 3 files changed, 192 insertions(+) (limited to 'src') 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 */ -- cgit