From a9f03f01b95031f748fdb968ae9c16b9c3d6ed21 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Wed, 18 Sep 2019 17:33:55 +0200 Subject: [PATCH 96/97] sysdb: add sysdb_subdomain_content_delete() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit sysdb_subdomain_content_delete() will remove all user and group objects from a sub-domain container but not the sub-domain object and the user and group container itself. Related to https://pagure.io/SSSD/sssd/issue/4078 Reviewed-by: Pavel Březina --- src/db/sysdb.h | 8 ++++ src/db/sysdb_ops.c | 17 ++++++-- src/db/sysdb_subdomains.c | 20 ++++++++- src/tests/sysdb-tests.c | 88 +++++++++++++++++++++++++++++++++++++++ 4 files changed, 127 insertions(+), 6 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 0a7e7c4f8..f8a2c87ae 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -557,6 +557,9 @@ errno_t sysdb_master_domain_add_info(struct sss_domain_info *domain, errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name); +errno_t sysdb_subdomain_content_delete(struct sysdb_ctx *sysdb, + const char *name); + errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, size_t *range_count, struct range_info ***range_list); @@ -892,6 +895,11 @@ int sysdb_delete_recursive(struct sysdb_ctx *sysdb, struct ldb_dn *dn, bool ignore_not_found); +int sysdb_delete_recursive_with_filter(struct sysdb_ctx *sysdb, + struct ldb_dn *dn, + bool ignore_not_found, + const char *filter); + /* Mark entry as expired */ errno_t sysdb_mark_entry_as_expired_ldb_dn(struct sss_domain_info *dom, struct ldb_dn *ldbdn); diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index fa3842d8f..262e12380 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -196,9 +196,10 @@ int sysdb_delete_entry(struct sysdb_ctx *sysdb, /* =Remove-Subentries-From-Sysdb=========================================== */ -int sysdb_delete_recursive(struct sysdb_ctx *sysdb, - struct ldb_dn *dn, - bool ignore_not_found) +int sysdb_delete_recursive_with_filter(struct sysdb_ctx *sysdb, + struct ldb_dn *dn, + bool ignore_not_found, + const char *filter) { const char *no_attrs[] = { NULL }; struct ldb_message **msgs; @@ -219,7 +220,7 @@ int sysdb_delete_recursive(struct sysdb_ctx *sysdb, } ret = sysdb_search_entry(tmp_ctx, sysdb, dn, - LDB_SCOPE_SUBTREE, "(distinguishedName=*)", + LDB_SCOPE_SUBTREE, filter, no_attrs, &msgs_count, &msgs); if (ret) { if (ignore_not_found && ret == ENOENT) { @@ -258,6 +259,14 @@ done: return ret; } +int sysdb_delete_recursive(struct sysdb_ctx *sysdb, + struct ldb_dn *dn, + bool ignore_not_found) +{ + return sysdb_delete_recursive_with_filter(sysdb, dn, ignore_not_found, + "(distinguishedName=*)"); +} + /* =Search-Entry========================================================== */ diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c index af838b44c..0ca6a611f 100644 --- a/src/db/sysdb_subdomains.c +++ b/src/db/sysdb_subdomains.c @@ -1250,7 +1250,9 @@ done: return ret; } -errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name) +static errno_t sysdb_subdomain_delete_with_filter(struct sysdb_ctx *sysdb, + const char *name, + const char *filter) { TALLOC_CTX *tmp_ctx = NULL; struct ldb_dn *dn; @@ -1269,7 +1271,7 @@ errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name) goto done; } - ret = sysdb_delete_recursive(sysdb, dn, true); + ret = sysdb_delete_recursive_with_filter(sysdb, dn, true, filter); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sysdb_delete_recursive failed.\n"); goto done; @@ -1280,6 +1282,20 @@ done: return ret; } +errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name) +{ + return sysdb_subdomain_delete_with_filter(sysdb, name, + "(distinguishedName=*)"); +} + +errno_t sysdb_subdomain_content_delete(struct sysdb_ctx *sysdb, + const char *name) +{ + const char *filter = "(|("SYSDB_UC")("SYSDB_GC"))"; + + return sysdb_subdomain_delete_with_filter(sysdb, name, filter); +} + errno_t sysdb_domain_get_domain_resolution_order(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb, diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c index 22460d9db..45a278e2a 100644 --- a/src/tests/sysdb-tests.c +++ b/src/tests/sysdb-tests.c @@ -6204,6 +6204,93 @@ START_TEST(test_sysdb_subdomain_store_user) } END_TEST +START_TEST(test_sysdb_subdomain_content_delete) +{ + struct sysdb_test_ctx *test_ctx; + errno_t ret; + struct sss_domain_info *subdomain = NULL; + struct ldb_result *results = NULL; + struct ldb_dn *base_dn = NULL; + struct ldb_dn *check_dn = NULL; + struct ldb_dn *check_dom_dn = NULL; + struct test_data *data; + char *alias; + + ret = setup_sysdb_tests(&test_ctx); + fail_if(ret != EOK, "Could not set up the test"); + + subdomain = new_subdomain(test_ctx, test_ctx->domain, + testdom[0], testdom[1], testdom[2], testdom[3], + MPG_DISABLED, false, NULL, NULL, 0, NULL, true); + fail_unless(subdomain != NULL, "Failed to create new subdomain."); + ret = sysdb_subdomain_store(test_ctx->sysdb, + testdom[0], testdom[1], testdom[2], testdom[3], + false, false, NULL, 0, NULL); + fail_if(ret != EOK, "Could not set up the test (test subdom)"); + + ret = sysdb_update_subdomains(test_ctx->domain, NULL); + fail_unless(ret == EOK, "sysdb_update_subdomains failed with [%d][%s]", + ret, strerror(ret)); + + data = test_data_new_user(test_ctx, 12345); + fail_if(data == NULL); + data->username = test_asprintf_fqname(data, subdomain, "SubDomUser"); + + alias = test_asprintf_fqname(data, subdomain, "subdomuser"); + fail_if(alias == NULL); + + ret = sysdb_attrs_add_string(data->attrs, SYSDB_NAME_ALIAS, alias); + fail_unless(ret == EOK, "sysdb_store_user failed."); + + ret = sysdb_store_user(subdomain, data->username, + NULL, data->uid, 0, "Sub Domain User", + "/home/subdomuser", "/bin/bash", + NULL, data->attrs, NULL, -1, 0); + fail_unless(ret == EOK, "sysdb_store_user failed."); + + base_dn =ldb_dn_new(test_ctx, test_ctx->sysdb->ldb, "cn=sysdb"); + fail_unless(base_dn != NULL); + + check_dn = sysdb_user_dn(data, subdomain, data->username); + fail_unless(check_dn != NULL); + + ret = ldb_search(test_ctx->sysdb->ldb, test_ctx, &results, base_dn, + LDB_SCOPE_SUBTREE, NULL, "name=%s", data->username); + fail_unless(ret == EOK, "ldb_search failed."); + fail_unless(results->count == 1, "Unexpected number of results, " + "expected [%d], got [%d]", + 1, results->count); + fail_unless(ldb_dn_compare(results->msgs[0]->dn, check_dn) == 0, + "Unexpected DN returned"); + + ret = sysdb_subdomain_content_delete(test_ctx->sysdb, testdom[0]); + fail_unless(ret == EOK, "sysdb_subdomain_content_delete failed."); + + /* Check if user is removed */ + ret = ldb_search(test_ctx->sysdb->ldb, test_ctx, &results, base_dn, + LDB_SCOPE_SUBTREE, NULL, "name=%s", alias); + fail_unless(ret == EOK, "ldb_search failed."); + fail_unless(results->count == 0, "Unexpected number of results, " + "expected [%d], got [%d]", + 0, results->count); + + check_dom_dn = ldb_dn_new_fmt(test_ctx, test_ctx->sysdb->ldb, + SYSDB_DOM_BASE, testdom[0]); + fail_unless(check_dom_dn != NULL, "ldb_dn_new_fmt failed."); + + /* Check if domain object is still present */ + ret = ldb_search(test_ctx->sysdb->ldb, test_ctx, &results, base_dn, + LDB_SCOPE_SUBTREE, NULL, "cn=%s", testdom[0]); + fail_unless(ret == EOK, "ldb_search failed."); + fail_unless(results->count == 1, "Unexpected number of results, " + "expected [%d], got [%d]", + 1, results->count); + fail_unless(ldb_dn_compare(results->msgs[0]->dn, check_dom_dn) == 0, + "Unexpected DN returned"); + +} +END_TEST + START_TEST(test_sysdb_subdomain_user_ops) { struct sysdb_test_ctx *test_ctx; @@ -7574,6 +7661,7 @@ Suite *create_sysdb_suite(void) TCase *tc_subdomain = tcase_create("SYSDB sub-domain Tests"); tcase_add_test(tc_subdomain, test_sysdb_subdomain_store_user); + tcase_add_test(tc_subdomain, test_sysdb_subdomain_content_delete); tcase_add_test(tc_subdomain, test_sysdb_subdomain_user_ops); tcase_add_test(tc_subdomain, test_sysdb_subdomain_group_ops); -- 2.20.1