From 2ea937af47c529ca827bcdd307a47e2b96690d38 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Sep 20 2019 08:24:54 +0000 Subject: utils: extend some find_domain_* calls to search disabled domain This extension is needed to support disabled domains since it is now important to know if a domain is really unknown or only disabled. While an unknown domain might typically lead to an error, a caller might just ignore requests for disabled domains or objects from disabled domains. Related to https://pagure.io/SSSD/sssd/issue/4078 Reviewed-by: Pavel Březina --- diff --git a/src/providers/ipa/ipa_id.c b/src/providers/ipa/ipa_id.c index 9abee34..f34692a 100644 --- a/src/providers/ipa/ipa_id.c +++ b/src/providers/ipa/ipa_id.c @@ -138,7 +138,8 @@ static errno_t ipa_resolve_user_list_get_user_step(struct tevent_req *req) state->user_domain = find_domain_by_object_name_ex( state->ipa_ctx->sdap_id_ctx->be->domain, - ar->filter_value, true); + ar->filter_value, true, + SSS_GND_DESCEND); /* Use provided domain as fallback because no known domain was found in the * user name. */ if (state->user_domain == NULL) { diff --git a/src/responder/sudo/sudosrv_get_sudorules.c b/src/responder/sudo/sudosrv_get_sudorules.c index d928a5e..c9c11bf 100644 --- a/src/responder/sudo/sudosrv_get_sudorules.c +++ b/src/responder/sudo/sudosrv_get_sudorules.c @@ -147,7 +147,8 @@ static errno_t sudosrv_format_runas(struct resp_ctx *rctx, continue; } - dom = find_domain_by_object_name_ex(rctx->domains, value, true); + dom = find_domain_by_object_name_ex(rctx->domains, value, true, + SSS_GND_DESCEND); if (dom == NULL) { continue; } diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c index 1a8699a..d49eb9f 100644 --- a/src/tests/cmocka/test_utils.c +++ b/src/tests/cmocka/test_utils.c @@ -400,6 +400,92 @@ void test_find_domain_by_name_disabled(void **state) } } +void test_find_domain_by_name_ex_disabled(void **state) +{ + struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, + struct dom_list_test_ctx); + struct sss_domain_info *dom; + struct sss_domain_info *disabled_dom; + size_t c; + size_t mis; + + mis = test_ctx->dom_count/2; + assert_true((mis >= 1 && mis < test_ctx->dom_count)); + + dom = test_ctx->dom_list; + for (c = 0; c < mis; c++) { + assert_non_null(dom); + dom = dom->next; + } + assert_non_null(dom); + sss_domain_set_state(dom, DOM_DISABLED); + disabled_dom = dom; + + dom = find_domain_by_name(test_ctx->dom_list, disabled_dom->name, true); + assert_null(dom); + + dom = find_domain_by_name_ex(test_ctx->dom_list, disabled_dom->name, true, + SSS_GND_DESCEND); + assert_null(dom); + + dom = find_domain_by_name_ex(test_ctx->dom_list, disabled_dom->name, true, + SSS_GND_DESCEND | SSS_GND_INCLUDE_DISABLED); + assert_non_null(dom); + assert_ptr_equal(disabled_dom, dom); + + dom = find_domain_by_name_ex(test_ctx->dom_list, disabled_dom->name, true, + SSS_GND_ALL_DOMAINS); + assert_non_null(dom); + assert_ptr_equal(disabled_dom, dom); +} + +void test_find_domain_by_object_name_ex(void **state) +{ + struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, + struct dom_list_test_ctx); + struct sss_domain_info *dom; + struct sss_domain_info *disabled_dom; + size_t c; + size_t mis; + char *obj_name; + + mis = test_ctx->dom_count/2; + assert_true((mis >= 1 && mis < test_ctx->dom_count)); + + dom = test_ctx->dom_list; + for (c = 0; c < mis; c++) { + assert_non_null(dom); + dom = dom->next; + } + assert_non_null(dom); + sss_domain_set_state(dom, DOM_DISABLED); + disabled_dom = dom; + + obj_name = talloc_asprintf(global_talloc_context, "myname@%s", + disabled_dom->name); + assert_non_null(obj_name); + + + dom = find_domain_by_object_name(test_ctx->dom_list, obj_name); + assert_null(dom); + + dom = find_domain_by_object_name_ex(test_ctx->dom_list, obj_name, true, + SSS_GND_DESCEND); + assert_null(dom); + + dom = find_domain_by_object_name_ex(test_ctx->dom_list, obj_name, true, + SSS_GND_DESCEND | SSS_GND_INCLUDE_DISABLED); + assert_non_null(dom); + assert_ptr_equal(disabled_dom, dom); + + dom = find_domain_by_object_name_ex(test_ctx->dom_list, obj_name, true, + SSS_GND_ALL_DOMAINS); + assert_non_null(dom); + assert_ptr_equal(disabled_dom, dom); + + talloc_free(obj_name); +} + void test_find_domain_by_sid_null(void **state) { struct dom_list_test_ctx *test_ctx = talloc_get_type(*state, @@ -1877,6 +1963,10 @@ int main(int argc, const char *argv[]) setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_find_domain_by_name_disabled, setup_dom_list, teardown_dom_list), + cmocka_unit_test_setup_teardown(test_find_domain_by_name_ex_disabled, + setup_dom_list, teardown_dom_list), + cmocka_unit_test_setup_teardown(test_find_domain_by_object_name_ex, + setup_dom_list, teardown_dom_list), cmocka_unit_test_setup_teardown(test_sss_names_init, confdb_test_setup, diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c index 4b1c9df..c56a061 100644 --- a/src/util/domain_info_utils.c +++ b/src/util/domain_info_utils.c @@ -93,9 +93,10 @@ bool subdomain_enumerates(struct sss_domain_info *parent, return false; } -struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain, - const char *name, - bool match_any) +struct sss_domain_info *find_domain_by_name_ex(struct sss_domain_info *domain, + const char *name, + bool match_any, + uint32_t gnd_flags) { struct sss_domain_info *dom = domain; @@ -103,21 +104,31 @@ struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain, return NULL; } - while (dom && sss_domain_get_state(dom) == DOM_DISABLED) { - dom = get_next_domain(dom, SSS_GND_DESCEND); + if (!(gnd_flags & SSS_GND_INCLUDE_DISABLED)) { + while (dom && sss_domain_get_state(dom) == DOM_DISABLED) { + dom = get_next_domain(dom, gnd_flags); + } } + while (dom) { if (strcasecmp(dom->name, name) == 0 || ((match_any == true) && (dom->flat_name != NULL) && (strcasecmp(dom->flat_name, name) == 0))) { return dom; } - dom = get_next_domain(dom, SSS_GND_DESCEND); + dom = get_next_domain(dom, gnd_flags); } return NULL; } +struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain, + const char *name, + bool match_any) +{ + return find_domain_by_name_ex(domain, name, match_any, SSS_GND_DESCEND); +} + struct sss_domain_info *find_domain_by_sid(struct sss_domain_info *domain, const char *sid) { @@ -175,7 +186,8 @@ sss_get_domain_by_sid_ldap_fallback(struct sss_domain_info *domain, struct sss_domain_info * find_domain_by_object_name_ex(struct sss_domain_info *domain, - const char *object_name, bool strict) + const char *object_name, bool strict, + uint32_t gnd_flags) { TALLOC_CTX *tmp_ctx; struct sss_domain_info *dom = NULL; @@ -203,7 +215,7 @@ find_domain_by_object_name_ex(struct sss_domain_info *domain, dom = domain; } } else { - dom = find_domain_by_name(domain, domainname, true); + dom = find_domain_by_name_ex(domain, domainname, true, gnd_flags); } done: @@ -215,7 +227,8 @@ struct sss_domain_info * find_domain_by_object_name(struct sss_domain_info *domain, const char *object_name) { - return find_domain_by_object_name_ex(domain, object_name, false); + return find_domain_by_object_name_ex(domain, object_name, false, + SSS_GND_DESCEND); } errno_t sssd_domain_init(TALLOC_CTX *mem_ctx, diff --git a/src/util/util.h b/src/util/util.h index fce7e42..8a754db 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -542,6 +542,10 @@ struct sss_domain_info *get_next_domain(struct sss_domain_info *domain, struct sss_domain_info *find_domain_by_name(struct sss_domain_info *domain, const char *name, bool match_any); +struct sss_domain_info *find_domain_by_name_ex(struct sss_domain_info *domain, + const char *name, + bool match_any, + uint32_t gnd_flags); struct sss_domain_info *find_domain_by_sid(struct sss_domain_info *domain, const char *sid); enum sss_domain_state sss_domain_get_state(struct sss_domain_info *dom); @@ -560,7 +564,8 @@ find_domain_by_object_name(struct sss_domain_info *domain, struct sss_domain_info * find_domain_by_object_name_ex(struct sss_domain_info *domain, - const char *object_name, bool strict); + const char *object_name, bool strict, + uint32_t gnd_flags); bool subdomain_enumerates(struct sss_domain_info *parent, const char *sd_name);