diff options
-rw-r--r-- | src/providers/ipa/ipa_s2n_exop.c | 16 | ||||
-rw-r--r-- | src/tests/cmocka/test_utils.c | 44 | ||||
-rw-r--r-- | src/util/domain_info_utils.c | 72 | ||||
-rw-r--r-- | src/util/util.h | 3 |
4 files changed, 133 insertions, 2 deletions
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c index a9c2f1ae3..997d0dce8 100644 --- a/src/providers/ipa/ipa_s2n_exop.c +++ b/src/providers/ipa/ipa_s2n_exop.c @@ -1749,6 +1749,7 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, bool in_transaction = false; int tret; struct sysdb_attrs *gid_override_attrs = NULL; + char ** exop_grouplist; tmp_ctx = talloc_new(NULL); if (tmp_ctx == NULL) { @@ -2000,8 +2001,19 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom, goto done; } - ret = diff_string_lists(tmp_ctx, attrs->groups, sysdb_grouplist, - &add_groups, &del_groups, NULL); + /* names returned by extdom exop will be all lower case, since + * we handle domain names case sensitve in the cache we have + * to make sure we use the right case. */ + ret = fix_domain_in_name_list(tmp_ctx, dom, attrs->groups, + &exop_grouplist); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "fix_domain_name failed.\n"); + goto done; + } + + ret = diff_string_lists(tmp_ctx, exop_grouplist, + sysdb_grouplist, &add_groups, + &del_groups, NULL); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "diff_string_lists failed.\n"); goto done; diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c index 5dc00c4cc..dc6e35dc0 100644 --- a/src/tests/cmocka/test_utils.c +++ b/src/tests/cmocka/test_utils.c @@ -1030,6 +1030,48 @@ void test_sss_write_krb5_conf_snippet(void **state) free(path); } + +void test_fix_domain_in_name_list(void **state) +{ + struct name_init_test_ctx *test_ctx; + + int ret; + struct sss_domain_info *sd; + struct sss_domain_info *dom; + const char *in[] = { "abc@test.case.dom", "def@TEST.case.DOM", NULL}; + char **out = NULL; + + test_ctx = talloc_get_type(*state, struct name_init_test_ctx); + assert_non_null(test_ctx); + + ret = confdb_get_domains(test_ctx->confdb, &dom); + assert_int_equal(ret, EOK); + + ret = sss_names_init(dom, test_ctx->confdb, NULL, &dom->names); + assert_int_equal(ret, EOK); + + sd = talloc_zero(test_ctx, struct sss_domain_info); + assert_non_null(sd); + sd->name = talloc_strdup(sd, "TesT.CasE.DoM"); + assert_non_null(sd->name); + sd->names = dom->names; + DLIST_ADD(dom->subdomains, sd); + sd->parent = dom; + + ret = fix_domain_in_name_list(test_ctx, dom, discard_const(in), &out); + assert_int_equal(ret, EOK); + assert_non_null(out); + assert_non_null(out[0]); + assert_string_equal(out[0], "abc@TesT.CasE.DoM"); + assert_non_null(out[1]); + assert_string_equal(out[1], "def@TesT.CasE.DoM"); + assert_null(out[2]); + + talloc_free(out); + talloc_free(sd); + talloc_free(dom); +} + int main(int argc, const char *argv[]) { poptContext pc; @@ -1078,6 +1120,8 @@ int main(int argc, const char *argv[]) setup_add_strings_lists, teardown_add_strings_lists), unit_test(test_sss_write_krb5_conf_snippet), + unit_test_setup_teardown(test_fix_domain_in_name_list, + confdb_test_setup, confdb_test_teardown), }; /* Set debug level to invalid value so we can deside if -d 0 was used. */ diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c index e04b90576..e0f1120e3 100644 --- a/src/util/domain_info_utils.c +++ b/src/util/domain_info_utils.c @@ -777,3 +777,75 @@ done: return ret; } + +errno_t fix_domain_in_name_list(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, + char **in, char ***_out) +{ + int ret; + size_t c; + TALLOC_CTX *tmp_ctx; + char **out; + struct sss_domain_info *head; + struct sss_domain_info *out_domain; + char *in_name; + char *in_domain; + + head = get_domains_head(dom); + + tmp_ctx = talloc_new(NULL); + if (tmp_ctx == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n"); + return ENOMEM; + } + + /* count elements */ + for (c = 0; in[c] != NULL; c++); + + out = talloc_zero_array(tmp_ctx, char *, c + 1); + if (out == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n"); + ret = ENOMEM; + goto done; + } + + for (c = 0; in[c] != NULL; c++) { + ret = sss_parse_name(tmp_ctx, head->names, in[c], &in_domain, + &in_name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sss_parse_name failed for [%s].\n", + in[c]); + goto done; + } + + if (in_domain == NULL) { + out[c] = talloc_strdup(out, in_name); + } else { + out_domain = find_domain_by_name(head, in_domain, true); + if (out_domain == NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Cannot find domain with name [%s].\n", in_domain); + ret = EINVAL; + goto done; + } + + out[c] = sss_tc_fqname(out, head->names, out_domain, in_name); + } + + if (out[c] == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "%s failed.\n", + in_domain == NULL ? "talloc_strdup" : "sss_tc_fqname"); + ret = ENOMEM; + goto done; + } + } + + *_out = talloc_steal(mem_ctx, out); + + ret = EOK; + +done: + talloc_free(tmp_ctx); + + return ret; +} diff --git a/src/util/util.h b/src/util/util.h index 45efd1aef..23624c815 100644 --- a/src/util/util.h +++ b/src/util/util.h @@ -589,6 +589,9 @@ errno_t get_dom_names(TALLOC_CTX *mem_ctx, char ***_dom_names, int *_dom_names_count); +errno_t fix_domain_in_name_list(TALLOC_CTX *mem_ctx, + struct sss_domain_info *dom, + char **in, char ***_out); /* from util_lock.c */ errno_t sss_br_lock_file(int fd, size_t start, size_t len, int num_tries, useconds_t wait); |