summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2015-01-22 17:03:00 +0100
committerJakub Hrozek <jhrozek@redhat.com>2015-01-23 13:34:04 +0100
commitf3ddfba05798b694768316c82d609dec29e31642 (patch)
treeed184ad45e05d5fc665cf28f74d7854cf06156ce
parent4663b9a486964533183533046f7093e9a3a9b75b (diff)
downloadsssd-f3ddfba05798b694768316c82d609dec29e31642.tar.gz
sssd-f3ddfba05798b694768316c82d609dec29e31642.tar.xz
sssd-f3ddfba05798b694768316c82d609dec29e31642.zip
IPA: properly handle mixed-case trusted domains
In the SSSD cache domain names are handled case-sensitive. As a result fully-qualified names in RDN contain the domain part in the original spelling. When IPA client lookup up group-memberships on the IPA server via the extdom plugin the names returned are all lower case. To make sure new DNs are generated correctly the domain part must adjusted. Related to https://fedorahosted.org/sssd/ticket/2159 Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
-rw-r--r--src/providers/ipa/ipa_s2n_exop.c16
-rw-r--r--src/tests/cmocka/test_utils.c44
-rw-r--r--src/util/domain_info_utils.c72
-rw-r--r--src/util/util.h3
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);