URL: https://github.com/SSSD/sssd/pull/85 Author: celestian Title: #85: SYSDB: Removing of sysdb_try_to_find_expected_dn() Action: synchronized
To pull the PR as Git branch: git remote add ghsssd https://github.com/SSSD/sssd git fetch ghsssd pull/85/head:pr85 git checkout pr85
From 04ef9e4852cc74c2b942d0b48f23ea3130dd27a2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com> Date: Thu, 19 Jan 2017 12:51:27 +0100 Subject: [PATCH 1/4] LDAP: Better logging message --- src/providers/ldap/sdap.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index dc7d5e0..eb460d9 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -1691,7 +1691,8 @@ static bool sdap_object_in_domain(struct sdap_options *opts, sdmatch = sdap_domain_get_by_dn(opts, original_dn); if (sdmatch == NULL) { DEBUG(SSSDBG_FUNC_DATA, - "The group has no original DN, assuming our domain\n"); + "The original DN of the group cannot " + "be related to any search base\n"); return true; } From df8eb16cc9b3427df3857fd10caf48d444e8ffdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com> Date: Wed, 4 Jan 2017 15:33:30 +0100 Subject: [PATCH 2/4] SYSDB: Removing of sysdb_try_to_find_expected_dn() Currently in order to match multiple LDAP search results we use two different functions - we have sysdb_try_to_find_expected_dn() but also sdap_object_in_domain(). This patch removes sysdb_try_to_find_expected_dn() and add new sdap_search_initgr_user_in_batch() based on sdap_object_in_domain(). This function covers necessary logic. Resolves: https://fedorahosted.org/sssd/ticket/3230 --- src/db/sysdb.h | 6 - src/db/sysdb_subdomains.c | 332 ----------------------------- src/providers/ldap/sdap.c | 6 +- src/providers/ldap/sdap.h | 4 + src/providers/ldap/sdap_async_initgroups.c | 28 ++- src/tests/cmocka/test_sysdb_subdomains.c | 104 --------- 6 files changed, 30 insertions(+), 450 deletions(-) diff --git a/src/db/sysdb.h b/src/db/sysdb.h index 407a197..ae3ff35 100644 --- a/src/db/sysdb.h +++ b/src/db/sysdb.h @@ -1309,10 +1309,4 @@ errno_t sysdb_handle_original_uuid(const char *orig_name, struct sysdb_attrs *dest_attrs, const char *dest_name); -errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, - const char *domain_component_name, - const char *ldap_search_base, - struct sysdb_attrs **usr_attrs, - size_t count, - struct sysdb_attrs **exp_usr); #endif /* __SYS_DB_H__ */ diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c index 7801404..1f43bfc 100644 --- a/src/db/sysdb_subdomains.c +++ b/src/db/sysdb_subdomains.c @@ -1144,335 +1144,3 @@ errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name) talloc_free(tmp_ctx); return ret; } - -static errno_t match_cn_users(TALLOC_CTX *tmp_ctx, - struct sysdb_attrs **usr_attrs, - size_t count, - const char *dom_basedn, - struct sysdb_attrs **_result) -{ - errno_t ret; - const char *orig_dn; - size_t dn_len; - struct sysdb_attrs *result = NULL; - const char *result_dn_str = NULL; - char *cn_users_basedn; - size_t cn_users_basedn_len; - - cn_users_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn); - if (cn_users_basedn == NULL) { - ret = ENOMEM; - goto done; - } - cn_users_basedn_len = strlen(cn_users_basedn); - DEBUG(SSSDBG_TRACE_ALL, "cn=users baseDN is [%s].\n", cn_users_basedn); - - for (size_t c = 0; c < count; c++) { - ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); - goto done; - } - dn_len = strlen(orig_dn); - - if (dn_len > cn_users_basedn_len - && strcasecmp(orig_dn + (dn_len - cn_users_basedn_len), - cn_users_basedn) == 0) { - DEBUG(SSSDBG_TRACE_ALL, - "Found matching dn [%s].\n", orig_dn); - if (result != NULL) { - DEBUG(SSSDBG_OP_FAILURE, - "Found 2 matching DN [%s] and [%s], expecting only 1.\n", - result_dn_str, orig_dn); - ret = EINVAL; - goto done; - } - result = usr_attrs[c]; - result_dn_str = orig_dn; - } - } - - ret = EOK; -done: - *_result = result; - return ret; -} - -static errno_t match_non_dc_comp(TALLOC_CTX *tmp_ctx, - struct sss_domain_info *dom, - struct sysdb_attrs **usr_attrs, - size_t count, - struct ldb_dn *ldb_basedn, - const char *basedn, - const char *domain_component_name, - struct sysdb_attrs **_result) -{ - errno_t ret; - const char *orig_dn; - size_t orig_dn_len; - size_t basedn_len; - struct ldb_context *ldb_ctx; - struct ldb_dn *ldb_orig_dn; - int dn_comp_num; - int basedn_comp_num; - const char *component_name; - struct sysdb_attrs *result = NULL; - const char *result_dn_str = NULL; - - ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb); - if (ldb_ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n"); - ret = EINVAL; - goto done; - } - - basedn_len = strlen(basedn); - - basedn_comp_num = ldb_dn_get_comp_num(ldb_basedn); - basedn_comp_num++; - - for (size_t c = 0; c < count; c++) { - ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n"); - goto done; - } - orig_dn_len = strlen(orig_dn); - - if (orig_dn_len > basedn_len - /* Does the user's original DN with the non-domain part - * stripped match the domain base DN? - */ - && strcasecmp(orig_dn + (orig_dn_len - basedn_len), - basedn) == 0) { - ldb_orig_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn); - if (ldb_orig_dn == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed"); - ret = ENOMEM; - goto done; - } - - dn_comp_num = ldb_dn_get_comp_num(ldb_orig_dn); - if (dn_comp_num > basedn_comp_num) { - component_name = ldb_dn_get_component_name(ldb_orig_dn, - (dn_comp_num - basedn_comp_num)); - DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n", - component_name, - domain_component_name); - /* If the component is NOT a DC component, then the entry - * must come from our domain, perhaps from a child container. - * If it matched the DC component, the entry was from a child - * subdomain different from this one. - */ - if (component_name != NULL - && strcasecmp(component_name, - domain_component_name) != 0) { - DEBUG(SSSDBG_TRACE_ALL, - "Found matching dn [%s].\n", orig_dn); - if (result != NULL) { - DEBUG(SSSDBG_OP_FAILURE, - "Found 2 matching DN [%s] and [%s], " - "expecting only 1.\n", result_dn_str, orig_dn); - ret = EINVAL; - goto done; - } - result = usr_attrs[c]; - result_dn_str = orig_dn; - } - } - } - } - - ret = EOK; - *_result = result; -done: - return ret; -} - -static errno_t match_basedn(TALLOC_CTX *tmp_ctx, - struct sss_domain_info *dom, - struct sysdb_attrs **usr_attrs, - size_t count, - const char *dom_basedn, - const char *domain_component_name, - struct sysdb_attrs **_result) -{ - struct ldb_context *ldb_ctx; - struct ldb_dn *ldb_dom_basedn; - - ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb); - if (ldb_ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n"); - return EINVAL; - } - - - ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn); - if (ldb_dom_basedn == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); - return ENOMEM; - } - - return match_non_dc_comp(tmp_ctx, dom, - usr_attrs, count, - ldb_dom_basedn, dom_basedn, - domain_component_name, - _result); -} - -static errno_t match_search_base(TALLOC_CTX *tmp_ctx, - struct sss_domain_info *dom, - const char *domain_component_name, - const char *domain_search_base, - struct sysdb_attrs **usr_attrs, - size_t count, - struct sysdb_attrs **_result) -{ - errno_t ret; - bool ok; - const char *search_base; - struct ldb_context *ldb_ctx; - struct sysdb_attrs *result = NULL; - struct ldb_dn *ldb_search_base; - int search_base_comp_num; - int non_dc_comp_num; - const char *component_name; - - ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb); - if (ldb_ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n"); - ret = EINVAL; - goto done; - } - - ldb_search_base = ldb_dn_new(tmp_ctx, ldb_ctx, domain_search_base); - if (ldb_search_base == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n"); - ret = ENOMEM; - goto done; - } - - /* strip non-DC components from the search base */ - search_base_comp_num = ldb_dn_get_comp_num(ldb_search_base); - for (non_dc_comp_num = 0; - non_dc_comp_num < search_base_comp_num; - non_dc_comp_num++) { - - component_name = ldb_dn_get_component_name(ldb_search_base, - non_dc_comp_num); - if (strcasecmp(domain_component_name, component_name) == 0) { - break; - } - } - - if (non_dc_comp_num == search_base_comp_num) { - /* The search base does not have any non-DC components, the search wouldn't - * match anyway - */ - ret = EOK; - *_result = NULL; - goto done; - } - - ok = ldb_dn_remove_child_components(ldb_search_base, non_dc_comp_num); - if (!ok) { - ret = EINVAL; - goto done; - } - - search_base = ldb_dn_get_linearized(ldb_search_base); - if (search_base == NULL) { - ret = ENOMEM; - goto done; - } - - ret = match_cn_users(tmp_ctx, usr_attrs, count, search_base, &result); - if (ret != EOK) { - goto done; - } - - if (result == NULL) { - ret = match_non_dc_comp(tmp_ctx, dom, - usr_attrs, count, - ldb_search_base, search_base, - domain_component_name, - &result); - if (ret != EOK) { - goto done; - } - } - - ret = EOK; - *_result = result; -done: - return ret; -} - -errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom, - const char *domain_component_name, - const char *domain_search_base, - struct sysdb_attrs **usr_attrs, - size_t count, - struct sysdb_attrs **exp_usr) -{ - char *dom_basedn; - int ret; - TALLOC_CTX *tmp_ctx; - struct sysdb_attrs *result = NULL; - - if (dom == NULL || domain_component_name == NULL - || domain_search_base == NULL - || usr_attrs == NULL || count == 0) { - return EINVAL; - } - - tmp_ctx = talloc_new(NULL); - if (tmp_ctx == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); - return ENOMEM; - } - - ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n"); - ret = EINVAL; - goto done; - } - - ret = match_cn_users(tmp_ctx, usr_attrs, count, dom_basedn, &result); - if (ret != EOK) { - goto done; - } - - if (result == NULL) { - ret = match_basedn(tmp_ctx, dom, usr_attrs, - count, dom_basedn, domain_component_name, - &result); - if (ret != EOK) { - goto done; - } - } - - if (result == NULL) { - ret = match_search_base(tmp_ctx, dom, domain_component_name, - domain_search_base, usr_attrs, count, - &result); - if (ret != EOK) { - goto done; - } - } - - if (result == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n"); - ret = ENOENT; - goto done; - } - - *exp_usr = result; - - ret = EOK; -done: - talloc_free(tmp_ctx); - - return ret; -} diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index eb460d9..bfb7fc6 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -1673,9 +1673,9 @@ char *sdap_make_oc_list(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map) } } -static bool sdap_object_in_domain(struct sdap_options *opts, - struct sysdb_attrs *obj, - struct sss_domain_info *dom) +bool sdap_object_in_domain(struct sdap_options *opts, + struct sysdb_attrs *obj, + struct sss_domain_info *dom) { errno_t ret; const char *original_dn = NULL; diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index e3cb846..6d4543e 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -616,4 +616,8 @@ size_t sdap_steal_objects_in_dom(struct sdap_options *opts, size_t count, bool filter); +bool sdap_object_in_domain(struct sdap_options *opts, + struct sysdb_attrs *obj, + struct sss_domain_info *dom); + #endif /* _SDAP_H_ */ diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c index 9b505e7..edb2981 100644 --- a/src/providers/ldap/sdap_async_initgroups.c +++ b/src/providers/ldap/sdap_async_initgroups.c @@ -23,6 +23,7 @@ #include "util/util.h" #include "db/sysdb.h" +#include "providers/ldap/sdap.h" #include "providers/ldap/sdap_async_private.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_idmap.h" @@ -2890,6 +2891,25 @@ static errno_t sdap_get_initgr_next_base(struct tevent_req *req) return EOK; } +static int sdap_search_initgr_user_in_batch(struct sdap_get_initgr_state *state, + struct sysdb_attrs **users, + size_t count) +{ + int ret = EINVAL; + + for (size_t i = 0; i < count; i++) { + if (sdap_object_in_domain(state->opts, users[i], state->dom) == false) { + continue; + } + + state->orig_user = talloc_steal(state, users[i]); + ret = EOK; + break; + } + + return ret; +} + static void sdap_get_initgr_user(struct tevent_req *subreq) { struct tevent_req *req = tevent_req_callback_data(subreq, @@ -2951,13 +2971,11 @@ static void sdap_get_initgr_user(struct tevent_req *subreq) * the first search base because all bases in a single domain would * have the same DC= components */ - ret = sysdb_try_to_find_expected_dn(state->dom, "dc", - state->sdom->search_bases[0]->basedn, - usr_attrs, count, - &state->orig_user); + ret = sdap_search_initgr_user_in_batch(state, usr_attrs, count); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, - "try_to_find_expected_dn failed. No matching DN found.\n"); + "sdap_search_initgr_user_in_batch failed. " + "No matching DN found.\n"); tevent_req_error(req, EINVAL); return; } diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c index 52056e0..52242e5 100644 --- a/src/tests/cmocka/test_sysdb_subdomains.c +++ b/src/tests/cmocka/test_sysdb_subdomains.c @@ -515,107 +515,6 @@ static void test_sysdb_link_ad_multidom(void **state) } -static void test_try_to_find_expected_dn(void **state) -{ - int ret; - struct sysdb_attrs *result; - struct sysdb_attrs *usr_attrs[10] = { NULL }; - struct sysdb_attrs *dom_usr_attrs[10] = { NULL }; - struct sss_domain_info *dom; - char *dom_basedn; - struct subdom_test_ctx *test_ctx = - talloc_get_type(*state, struct subdom_test_ctx); - - dom = find_domain_by_name(test_ctx->tctx->dom, - "child2.test_sysdb_subdomains_2", true); - assert_non_null(dom); - - ret = domain_to_basedn(test_ctx, dom->name, &dom_basedn); - assert_int_equal(ret, EOK); - - usr_attrs[0] = sysdb_new_attrs(test_ctx); - assert_non_null(usr_attrs[0]); - - ret = sysdb_attrs_add_string(usr_attrs[0], SYSDB_ORIG_DN, - "uid=user,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2"); - assert_int_equal(ret, EOK); - - ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, NULL, 0, NULL); - assert_int_equal(ret, EINVAL); - - ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 1, &result); - assert_int_equal(ret, ENOENT); - - ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 1, &result); - assert_int_equal(ret, EOK); - assert_ptr_equal(result, usr_attrs[0]); - - usr_attrs[1] = sysdb_new_attrs(test_ctx); - assert_non_null(usr_attrs[1]); - - ret = sysdb_attrs_add_string(usr_attrs[1], SYSDB_ORIG_DN, - "uid=user1,cn=abc,dc=child2,dc=test_sysdb_subdomains_2"); - assert_int_equal(ret, EOK); - - usr_attrs[2] = sysdb_new_attrs(test_ctx); - assert_non_null(usr_attrs[2]); - - ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN, - "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2"); - assert_int_equal(ret, EOK); - - ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result); - assert_int_equal(ret, EOK); - assert_ptr_equal(result, usr_attrs[1]); - - ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 3, &result); - assert_int_equal(ret, EINVAL); - - /* Make sure cn=users match is preferred */ - talloc_free(usr_attrs[2]); - usr_attrs[2] = sysdb_new_attrs(test_ctx); - assert_non_null(usr_attrs[2]); - - ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN, - "uid=user2,cn=abc,cn=users,dc=child2,dc=test_sysdb_subdomains_2"); - assert_int_equal(ret, EOK); - - ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result); - assert_int_equal(ret, EOK); - assert_ptr_equal(result, usr_attrs[2]); - - /* test a case where the domain name does not match the basedn */ - dom->name = discard_const("default"); - dom_usr_attrs[0] = usr_attrs[0]; - - ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 1, &result); - assert_int_equal(ret, ENOENT); - - dom_usr_attrs[1] = usr_attrs[1]; - dom_usr_attrs[2] = usr_attrs[2]; - - /* Make sure cn=users match is preferred */ - ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result); - assert_int_equal(ret, EOK); - assert_ptr_equal(result, dom_usr_attrs[2]); - - talloc_free(usr_attrs[2]); - usr_attrs[2] = sysdb_new_attrs(test_ctx); - assert_non_null(usr_attrs[2]); - ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN, - "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2"); - assert_int_equal(ret, EOK); - - dom_usr_attrs[2] = usr_attrs[2]; - ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result); - assert_int_equal(ret, EOK); - assert_ptr_equal(result, usr_attrs[1]); - - talloc_free(usr_attrs[0]); - talloc_free(usr_attrs[1]); - talloc_free(usr_attrs[2]); -} - int main(int argc, const char *argv[]) { int rv; @@ -649,9 +548,6 @@ int main(int argc, const char *argv[]) cmocka_unit_test_setup_teardown(test_sysdb_link_ad_multidom, test_sysdb_subdom_setup, test_sysdb_subdom_teardown), - cmocka_unit_test_setup_teardown(test_try_to_find_expected_dn, - test_sysdb_subdom_setup, - test_sysdb_subdom_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ From fcd4260717dd17c342a74f691f3039f7f53047a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com> Date: Thu, 12 Jan 2017 13:16:10 +0100 Subject: [PATCH 3/4] TEST: create_multidom_test_ctx() extending Function create_multidom_test_ctx() prepares test environment for multidomains. This patch enables setting of different params for each domain. Resolves: https://fedorahosted.org/sssd/ticket/3230 --- src/tests/cmocka/test_ad_common.c | 5 +---- src/tests/cmocka/test_sysdb_subdomains.c | 5 +---- src/tests/cmocka/test_sysdb_ts_cache.c | 5 +---- src/tests/common.h | 2 +- src/tests/common_dom.c | 6 +++--- 5 files changed, 7 insertions(+), 16 deletions(-) diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c index 7ec2920..ea99989 100644 --- a/src/tests/cmocka/test_ad_common.c +++ b/src/tests/cmocka/test_ad_common.c @@ -78,9 +78,6 @@ struct ad_sysdb_test_ctx { static int test_ad_sysdb_setup(void **state) { struct ad_sysdb_test_ctx *test_ctx; - struct sss_test_conf_param params[] = { - { NULL, NULL }, /* Sentinel */ - }; assert_true(leak_check_setup()); @@ -92,7 +89,7 @@ static int test_ad_sysdb_setup(void **state) test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, domains, - TEST_ID_PROVIDER, params); + TEST_ID_PROVIDER, NULL); assert_non_null(test_ctx->tctx); *state = test_ctx; diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c index 52242e5..49f4499 100644 --- a/src/tests/cmocka/test_sysdb_subdomains.c +++ b/src/tests/cmocka/test_sysdb_subdomains.c @@ -60,9 +60,6 @@ struct subdom_test_ctx { static int test_sysdb_subdom_setup(void **state) { struct subdom_test_ctx *test_ctx; - struct sss_test_conf_param params[] = { - { NULL, NULL }, /* Sentinel */ - }; assert_true(leak_check_setup()); @@ -74,7 +71,7 @@ static int test_sysdb_subdom_setup(void **state) test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, domains, - TEST_ID_PROVIDER, params); + TEST_ID_PROVIDER, NULL); assert_non_null(test_ctx->tctx); *state = test_ctx; diff --git a/src/tests/cmocka/test_sysdb_ts_cache.c b/src/tests/cmocka/test_sysdb_ts_cache.c index e950f88..f5aab73 100644 --- a/src/tests/cmocka/test_sysdb_ts_cache.c +++ b/src/tests/cmocka/test_sysdb_ts_cache.c @@ -74,9 +74,6 @@ const char *domains[] = { TEST_DOM1_NAME, static int test_sysdb_ts_setup(void **state) { struct sysdb_ts_test_ctx *test_ctx; - struct sss_test_conf_param params[] = { - { NULL, NULL }, /* Sentinel */ - }; assert_true(leak_check_setup()); @@ -88,7 +85,7 @@ static int test_sysdb_ts_setup(void **state) test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH, TEST_CONF_DB, domains, - TEST_ID_PROVIDER, params); + TEST_ID_PROVIDER, NULL); assert_non_null(test_ctx->tctx); check_leaks_push(test_ctx); diff --git a/src/tests/common.h b/src/tests/common.h index b49cfea..c06568d 100644 --- a/src/tests/common.h +++ b/src/tests/common.h @@ -92,7 +92,7 @@ create_multidom_test_ctx(TALLOC_CTX *mem_ctx, const char *cdb_file, const char **domains, const char *id_provider, - struct sss_test_conf_param *params); + struct sss_test_conf_param **params); struct sss_test_ctx * create_dom_test_ctx(TALLOC_CTX *mem_ctx, diff --git a/src/tests/common_dom.c b/src/tests/common_dom.c index f1a92cc..def28d5 100644 --- a/src/tests/common_dom.c +++ b/src/tests/common_dom.c @@ -231,7 +231,7 @@ create_multidom_test_ctx(TALLOC_CTX *mem_ctx, const char *cdb_file, const char **domains, const char *id_provider, - struct sss_test_conf_param *params) + struct sss_test_conf_param **params) { struct sss_domain_info *domain = NULL; struct sss_test_ctx *test_ctx = NULL; @@ -255,7 +255,7 @@ create_multidom_test_ctx(TALLOC_CTX *mem_ctx, /* create confdb objects for the domains */ for (i = 0; domains[i] != NULL; i++) { ret = mock_confdb_domain(test_ctx, test_ctx->confdb, tests_path, - domains[i], id_provider, params, + domains[i], id_provider, params != NULL ? params[i] : NULL, (cdb_path == NULL ? &cdb_path : NULL)); if (ret != EOK) { DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize confdb domain " @@ -302,7 +302,7 @@ create_dom_test_ctx(TALLOC_CTX *mem_ctx, const char *domains[] = {domain_name, NULL}; return create_multidom_test_ctx(mem_ctx, tests_path, confdb_path, domains, - id_provider, params); + id_provider, ¶ms); } void test_multidom_suite_cleanup(const char *tests_path, From 2e1245d9c35e55d71837176fb8bc0187deb3976b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com> Date: Tue, 10 Jan 2017 14:01:45 +0100 Subject: [PATCH 4/4] TESTS: Tests for sdap_search_initgr_user_in_batch This patch provides tests for core logic of sdap_search_initgr_user_in_batch() function. This function replaces old approach with sysdb_try_to_find_expected_dn() function. Resolves: https://fedorahosted.org/sssd/ticket/3230 --- Makefile.am | 22 ++ src/tests/cmocka/test_sdap_initgr.c | 540 ++++++++++++++++++++++++++++++++++++ 2 files changed, 562 insertions(+) create mode 100644 src/tests/cmocka/test_sdap_initgr.c diff --git a/Makefile.am b/Makefile.am index 95be640..6916ae3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -278,6 +278,7 @@ non_interactive_cmocka_based_tests += \ ad_access_filter_tests \ ad_gpo_tests \ ad_common_tests \ + test_sdap_initgr \ test_ad_subdom \ test_ipa_subdom_server \ $(NULL) @@ -2810,6 +2811,27 @@ test_fo_srv_LDADD = \ libsss_test_common.la \ $(NULL) +test_sdap_initgr_SOURCES = \ + src/tests/cmocka/common_mock_sdap.c \ + src/tests/cmocka/common_mock_sysdb_objects.c \ + src/tests/cmocka/test_sdap_initgr.c \ + $(NULL) +test_sdap_initgr_CFLAGS = \ + $(AM_CFLAGS) \ + $(NDR_NBT_CFLAGS) \ + $(NULL) +test_sdap_initgr_LDADD = \ + $(CMOCKA_LIBS) \ + $(POPT_LIBS) \ + $(TALLOC_LIBS) \ + $(SSSD_INTERNAL_LTLIBS) \ + libsss_ldap_common.la \ + libsss_ad_tests.la \ + libsss_idmap.la \ + libsss_test_common.la \ + libdlopen_test_providers.la \ + $(NULL) + test_ad_subdom_SOURCES = \ src/tests/cmocka/test_ad_subdomains.c \ $(NULL) diff --git a/src/tests/cmocka/test_sdap_initgr.c b/src/tests/cmocka/test_sdap_initgr.c new file mode 100644 index 0000000..28c6ae3 --- /dev/null +++ b/src/tests/cmocka/test_sdap_initgr.c @@ -0,0 +1,540 @@ +/* + Authors: + Petr Čech <pc...@redhat.com> + + Copyright (C) 2017 Red Hat + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see <http://www.gnu.org/licenses/>. +*/ + +#include <talloc.h> +#include <tevent.h> +#include <errno.h> +#include <popt.h> +#include <arpa/inet.h> +#include <netinet/in.h> +#include <sys/types.h> +#include <stdarg.h> +#include <stdlib.h> +#include <pwd.h> + +#include "tests/cmocka/common_mock.h" +#include "tests/cmocka/common_mock_sysdb_objects.h" +#include "tests/cmocka/common_mock_sdap.h" +#include "providers/ad/ad_common.h" + +#include "providers/ad/ad_opts.c" +#include "providers/ldap/sdap_async_initgroups.c" + +/* Declarations from providers/ldap/sdap_async_initgroups.c */ +struct sdap_get_initgr_state; +static int sdap_search_initgr_user_in_batch(struct sdap_get_initgr_state *state, + struct sysdb_attrs **users, + size_t count); + +#define TESTS_PATH "tp_" BASE_FILE_STEM +#define TEST_CONF_DB "test_sdap_initgr_conf.ldb" +#define TEST_ID_PROVIDER "ldap" + +#define TEST_DOM1_NAME "domain.test.com" +#define TEST_DOM2_NAME "subdom1.domain.test.com" +#define TEST_DOM3_NAME "another_domain.test.com" + +#define OBJECT_BASE_DN1 "dc=domain,dc=test,dc=com,cn=sysdb" +#define OBJECT_BASE_DN2 "dc=subdom1,dc=domain,dc=test,dc=com,cn=sysdb" +#define OBJECT_BASE_DN3 "dc=another_domain,dc=test,dc=com,cn=sysdb" + +#define TEST_USER_1 "test_user_1" +#define TEST_USER_2 "test_user_2" +#define TEST_USER_3 "test_user_3" + +const char *domains[] = { TEST_DOM1_NAME, + TEST_DOM2_NAME, + TEST_DOM3_NAME, + NULL }; + +const char *object_bases[] = { OBJECT_BASE_DN1, + OBJECT_BASE_DN2, + OBJECT_BASE_DN3, + NULL }; + +const char *test_users[] = { TEST_USER_1, + TEST_USER_2, + TEST_USER_3, + NULL }; + +/* ====================== Utilities =============================== */ + +struct test_sdap_initgr_ctx { + struct sss_test_ctx *tctx; +}; + +static struct passwd **get_users(TALLOC_CTX *ctx) +{ + struct passwd **passwds = NULL; + char *homedir = NULL; + size_t user_count = 0; + + for (int i = 0; test_users[i] != NULL; i++) { + user_count++; + } + passwds = talloc_array(ctx, struct passwd *, user_count); + assert_non_null(passwds); + + for (int i = 0; i < user_count; i++) { + passwds[i] = talloc(passwds, struct passwd); + assert_non_null(passwds[i]); + + homedir = talloc_strdup_append(homedir, "/home/"); + homedir = talloc_strdup_append(homedir, test_users[i]); + + passwds[i]->pw_name = discard_const(test_users[i]); + passwds[i]->pw_uid = 567 + i; + passwds[i]->pw_gid = 890 + i; + passwds[i]->pw_dir = talloc_strdup(passwds[i], homedir); + passwds[i]->pw_gecos = discard_const(test_users[i]); + passwds[i]->pw_shell = discard_const("/bin/sh"); + passwds[i]->pw_passwd = discard_const("*"); + + talloc_zfree(homedir); + } + + return passwds; +} + +static struct sss_test_conf_param **get_params(TALLOC_CTX *ctx) +{ + struct sss_test_conf_param **params; + char *user_base_dn = NULL; + char *group_base_dn = NULL; + size_t base_count = 0; + + for (int i = 0; object_bases[i] != NULL; i++) { + base_count++; + } + + params = talloc_array(ctx, struct sss_test_conf_param *, base_count + 1); + assert_non_null(params); + + for (int i = 0; i < base_count; i++) { + params[i] = talloc(params, struct sss_test_conf_param); + assert_non_null(params[i]); + + user_base_dn = talloc_strdup_append(user_base_dn, "cn=users,"); + user_base_dn = talloc_strdup_append(user_base_dn, object_bases[i]); + + group_base_dn = talloc_strdup_append(group_base_dn, "cn=groups,"); + group_base_dn = talloc_strdup_append(group_base_dn, object_bases[i]); + + params[i] = talloc_array(params[i], struct sss_test_conf_param, 5); + params[i][0].key = "ldap_schema"; + params[i][0].value = "rfc2307bis"; + params[i][1].key = "ldap_search_base"; + params[i][1].value = talloc_strdup(params[i], object_bases[i]); + params[i][2].key = "ldap_user_search_base"; + params[i][2].value = talloc_strdup(params[i], user_base_dn); + params[i][3].key = "ldap_group_search_base"; + params[i][3].value = talloc_strdup(params[i], group_base_dn); + params[i][4].key = NULL; + params[i][4].value = NULL; + + talloc_zfree(user_base_dn); + talloc_zfree(group_base_dn); + } + + return params; +} + +struct sss_domain_info *get_domain_info(struct sss_domain_info *domain, + const char *domain_name) +{ + struct sss_domain_info *dom = domain; + + while(dom != NULL) { + if (strcmp(dom->name, domain_name) == 0) { + break; + } + dom = dom->next; + } + + return dom; +} + +struct sdap_get_initgr_state *prepare_state(struct test_sdap_initgr_ctx *ctx, + const char **domain_names) +{ + struct sdap_get_initgr_state *state; + struct sss_domain_info *dom_info = NULL; + struct sss_domain_info *recent_dom_info = NULL; + + state = talloc_zero(ctx->tctx, struct sdap_get_initgr_state); + assert_non_null(state); + + for (int i=0; domain_names[i] != NULL; i++) { + dom_info = get_domain_info(ctx->tctx->dom, domain_names[i]); + assert_non_null(dom_info); + + if (i == 0) { + state->dom = dom_info; + recent_dom_info = state->dom; + } else { + recent_dom_info->next = dom_info; + recent_dom_info = recent_dom_info->next; + } + } + assert_non_null(state->dom); + assert_non_null(recent_dom_info); + recent_dom_info->next = NULL; + + state->opts = mock_sdap_options_ldap(state, state->dom, + ctx->tctx->confdb, + ctx->tctx->conf_dom_path); + assert_non_null(state->opts); + + return state; +} + +/* TODO: This function is copied from test_nss_srv.c + * It could be fine move both to one place, + * for example src/tests/common_sysdb.c + */ +static errno_t store_user(TALLOC_CTX *ctx, + struct sss_domain_info *dom, + struct passwd *user, + struct sysdb_attrs *attrs, + time_t cache_update) +{ + errno_t ret; + char *fqname; + + fqname = sss_create_internal_fqname(ctx, + user->pw_name, + dom->name); + if (fqname == NULL) { + return ENOMEM; + } + + /* Prime the cache with a valid user */ + ret = sysdb_store_user(dom, + fqname, + user->pw_passwd, + user->pw_uid, + user->pw_gid, + user->pw_gecos, + user->pw_dir, + user->pw_shell, + NULL, attrs, + NULL, 300, cache_update); + talloc_free(fqname); + + return ret; +} + +/* ====================== Setup =============================== */ + +static int test_sdap_initgr_setup_one_domain(void **state) +{ + struct test_sdap_initgr_ctx *test_ctx; + struct sss_test_conf_param **params; + + assert_true(leak_check_setup()); + + test_ctx = talloc_zero(global_talloc_context, struct test_sdap_initgr_ctx); + assert_non_null(test_ctx); + + params = get_params(test_ctx); + assert_non_null(params); + + test_ctx->tctx = create_dom_test_ctx(test_ctx, TESTS_PATH, + TEST_CONF_DB, domains[0], + TEST_ID_PROVIDER, params[0]); + assert_non_null(test_ctx->tctx); + + check_leaks_push(test_ctx); + *state = test_ctx; + return 0; +} + +static int test_sdap_initgr_setup_multi_domains(void **state) +{ + struct test_sdap_initgr_ctx *test_ctx; + struct sss_test_conf_param **params; + + assert_true(leak_check_setup()); + + test_ctx = talloc_zero(global_talloc_context, struct test_sdap_initgr_ctx); + assert_non_null(test_ctx); + + params = get_params(test_ctx); + assert_non_null(params); + + test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH, + TEST_CONF_DB, domains, + TEST_ID_PROVIDER, params); + assert_non_null(test_ctx->tctx); + + check_leaks_push(test_ctx); + *state = test_ctx; + return 0; +} + +static int test_sdap_initgr_setup_other_multi_domains(void **state) +{ + struct test_sdap_initgr_ctx *test_ctx; + struct sss_test_conf_param **params; + const char *domains_vith_other[] = { TEST_DOM1_NAME, + TEST_DOM3_NAME, + NULL }; + + assert_true(leak_check_setup()); + + test_ctx = talloc_zero(global_talloc_context, struct test_sdap_initgr_ctx); + assert_non_null(test_ctx); + + params = get_params(test_ctx); + assert_non_null(params); + + test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH, + TEST_CONF_DB, domains_vith_other, + TEST_ID_PROVIDER, params); + assert_non_null(test_ctx->tctx); + + check_leaks_push(test_ctx); + *state = test_ctx; + return 0; +} + +static int test_sdap_initgr_teardown(void **state) +{ + struct test_sdap_initgr_ctx *test_ctx; + + test_ctx = talloc_get_type(*state, struct test_sdap_initgr_ctx); + assert_non_null(test_ctx); + + assert_true(check_leaks_pop(test_ctx) == true); + talloc_free(test_ctx); + assert_true(leak_check_teardown()); + return 0; +} + +/* ====================== The tests =============================== */ + +static void test_user_is_on_batch(void **state) +{ + struct test_sdap_initgr_ctx *test_ctx; + struct sdap_get_initgr_state *initgr_state; + const char *domains_set[] = { domains[0], NULL }; + struct sss_domain_info *dom1_info = NULL; + struct sss_domain_info *dom2_info = NULL; + struct passwd **passwd_users; + struct sysdb_attrs **users; + const char *user_name; + errno_t ret; + + test_ctx = talloc_get_type(*state, struct test_sdap_initgr_ctx); + assert_non_null(test_ctx); + + dom1_info = get_domain_info(test_ctx->tctx->dom, domains[0]); + assert_non_null(dom1_info); + dom2_info = get_domain_info(test_ctx->tctx->dom, domains[1]); + assert_non_null(dom2_info); + + initgr_state = prepare_state(test_ctx, domains_set); + assert_non_null(initgr_state); + + passwd_users = get_users(test_ctx); + assert_non_null(passwd_users); + + ret = store_user(test_ctx, dom1_info, passwd_users[0], NULL, 0); + assert_int_equal(ret, 0); + ret = store_user(test_ctx, dom2_info, passwd_users[1], NULL, 0); + assert_int_equal(ret, 0); + + users = talloc_array(test_ctx, struct sysdb_attrs *, 2); + users[0] = mock_sysdb_user(users, object_bases[0], + passwd_users[0]->pw_uid, + passwd_users[0]->pw_name); + users[1] = mock_sysdb_user(users, object_bases[1], + passwd_users[1]->pw_uid, + passwd_users[1]->pw_name); + + ret = sdap_search_initgr_user_in_batch(initgr_state, users, 2); + assert_int_equal(ret, 0); + + ret = sysdb_attrs_get_string(initgr_state->orig_user, "name", &user_name); + assert_int_equal(ret, 0); + assert_string_equal(user_name, passwd_users[0]->pw_name); + + talloc_zfree(initgr_state); + talloc_zfree(passwd_users); + talloc_zfree(users); +} + +static void test_user_is_from_subdomain(void **state) +{ + struct test_sdap_initgr_ctx *test_ctx; + struct sdap_get_initgr_state *initgr_state; + const char *domains_set[] = { domains[0], NULL }; + struct sss_domain_info *dom_info = NULL; + struct passwd **passwd_users; + struct sysdb_attrs **users; + const char *user_name; + errno_t ret; + + test_ctx = talloc_get_type(*state, struct test_sdap_initgr_ctx); + assert_non_null(test_ctx); + + dom_info = get_domain_info(test_ctx->tctx->dom, domains[0]); + assert_non_null(dom_info); + + initgr_state = prepare_state(test_ctx, domains_set); + assert_non_null(initgr_state); + + passwd_users = get_users(test_ctx); + assert_non_null(passwd_users); + + ret = store_user(test_ctx, dom_info, passwd_users[0], NULL, 0); + assert_int_equal(ret, 0); + + users = talloc_array(test_ctx, struct sysdb_attrs *, 1); + users[0] = mock_sysdb_user(users, object_bases[1], + passwd_users[1]->pw_uid, + passwd_users[1]->pw_name); + + const char *original_dn = NULL; + ret = sysdb_attrs_get_string(users[0], SYSDB_ORIG_DN, &original_dn); + + ret = sdap_search_initgr_user_in_batch(initgr_state, users, 1); + assert_int_equal(ret, 0); + + ret = sysdb_attrs_get_string(initgr_state->orig_user, "name", &user_name); + assert_int_equal(ret, 0); + assert_string_equal(user_name, passwd_users[1]->pw_name); + + talloc_zfree(initgr_state); + talloc_zfree(passwd_users); + talloc_zfree(users); +} + +static void test_user_is_from_another_domain(void **state) +{ + struct test_sdap_initgr_ctx *test_ctx; + struct sdap_get_initgr_state *initgr_state; + const char *domains_set[] = { domains[0], domains[2], NULL }; + struct sss_domain_info *dom_info = NULL; + struct sss_domain_info *other_dom_info = NULL; + struct sdap_domain *other_sdom = NULL; + struct passwd **passwd_users; + struct sysdb_attrs **users; + errno_t ret; + + test_ctx = talloc_get_type(*state, struct test_sdap_initgr_ctx); + assert_non_null(test_ctx); + + dom_info = get_domain_info(test_ctx->tctx->dom, domains[0]); + assert_non_null(dom_info); + + initgr_state = prepare_state(test_ctx, domains_set); + assert_non_null(initgr_state); + + other_dom_info = get_domain_info(test_ctx->tctx->dom, domains[2]); + assert_non_null(other_dom_info); + + ret = sdap_domain_add(initgr_state->opts, other_dom_info, &other_sdom); + assert_int_equal(ret, EOK); + + talloc_zfree(other_sdom->search_bases); + other_sdom->search_bases = talloc_array(other_sdom, + struct sdap_search_base *, 2); + assert_non_null(other_sdom->search_bases); + other_sdom->search_bases[1] = NULL; + + ret = sdap_create_search_base(other_sdom, object_bases[2], + LDAP_SCOPE_SUBTREE, NULL, + &other_sdom->search_bases[0]); + assert_int_equal(ret, EOK); + + passwd_users = get_users(test_ctx); + assert_non_null(passwd_users); + + ret = store_user(test_ctx, dom_info, passwd_users[0], NULL, 0); + assert_int_equal(ret, 0); + + users = talloc_array(test_ctx, struct sysdb_attrs *, 1); + users[0] = mock_sysdb_user(users, object_bases[2], + passwd_users[2]->pw_uid, + passwd_users[2]->pw_name); + + ret = sdap_search_initgr_user_in_batch(initgr_state, users, 1); + assert_int_equal(ret, EINVAL); + + talloc_zfree(initgr_state); + talloc_zfree(passwd_users); + talloc_zfree(users); +} + +int main(int argc, const char *argv[]) +{ + int rv; + poptContext pc; + int opt; + struct poptOption long_options[] = { + POPT_AUTOHELP + SSSD_DEBUG_OPTS + POPT_TABLEEND + }; + + const struct CMUnitTest tests[] = { + cmocka_unit_test_setup_teardown(test_user_is_on_batch, + test_sdap_initgr_setup_multi_domains, + test_sdap_initgr_teardown), + cmocka_unit_test_setup_teardown(test_user_is_from_subdomain, + test_sdap_initgr_setup_one_domain, + test_sdap_initgr_teardown), + cmocka_unit_test_setup_teardown(test_user_is_from_another_domain, + test_sdap_initgr_setup_other_multi_domains, + test_sdap_initgr_teardown), + }; + + /* Set debug level to invalid value so we can deside if -d 0 was used. */ + debug_level = SSSDBG_INVALID; + + pc = poptGetContext(argv[0], argc, argv, long_options, 0); + while((opt = poptGetNextOpt(pc)) != -1) { + switch(opt) { + default: + fprintf(stderr, "\nInvalid option %s: %s\n\n", + poptBadOption(pc, 0), poptStrerror(opt)); + poptPrintUsage(pc, stderr, 0); + return 1; + } + } + poptFreeContext(pc); + + DEBUG_CLI_INIT(debug_level); + + /* Even though normally the tests should clean up after themselves + * they might not after a failed run. Remove the old db to be sure */ + tests_set_cwd(); + + test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains); + test_dom_suite_setup(TESTS_PATH); + + rv = cmocka_run_group_tests(tests, NULL, NULL); + if (rv == 0) { + test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains); + } + + return rv; +}
_______________________________________________ sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org