|
|
905b4d |
From f3ddfba05798b694768316c82d609dec29e31642 Mon Sep 17 00:00:00 2001
|
|
|
905b4d |
From: Sumit Bose <sbose@redhat.com>
|
|
|
905b4d |
Date: Thu, 22 Jan 2015 17:03:00 +0100
|
|
|
905b4d |
Subject: [PATCH 175/176] IPA: properly handle mixed-case trusted domains
|
|
|
905b4d |
|
|
|
905b4d |
In the SSSD cache domain names are handled case-sensitive. As a result
|
|
|
905b4d |
fully-qualified names in RDN contain the domain part in the original
|
|
|
905b4d |
spelling. When IPA client lookup up group-memberships on the IPA server
|
|
|
905b4d |
via the extdom plugin the names returned are all lower case. To make
|
|
|
905b4d |
sure new DNs are generated correctly the domain part must adjusted.
|
|
|
905b4d |
|
|
|
905b4d |
Related to https://fedorahosted.org/sssd/ticket/2159
|
|
|
905b4d |
|
|
|
905b4d |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
905b4d |
---
|
|
|
905b4d |
src/providers/ipa/ipa_s2n_exop.c | 16 +++++++--
|
|
|
905b4d |
src/tests/cmocka/test_utils.c | 44 ++++++++++++++++++++++++
|
|
|
905b4d |
src/util/domain_info_utils.c | 72 ++++++++++++++++++++++++++++++++++++++++
|
|
|
905b4d |
src/util/util.h | 3 ++
|
|
|
905b4d |
4 files changed, 133 insertions(+), 2 deletions(-)
|
|
|
905b4d |
|
|
|
905b4d |
diff --git a/src/providers/ipa/ipa_s2n_exop.c b/src/providers/ipa/ipa_s2n_exop.c
|
|
|
905b4d |
index a9c2f1ae3955bc3d2707bbcd186609a8d76b6169..997d0dce8d3225f83bbce506d349e4a8705e1e95 100644
|
|
|
905b4d |
--- a/src/providers/ipa/ipa_s2n_exop.c
|
|
|
905b4d |
+++ b/src/providers/ipa/ipa_s2n_exop.c
|
|
|
905b4d |
@@ -1749,6 +1749,7 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
|
|
|
905b4d |
bool in_transaction = false;
|
|
|
905b4d |
int tret;
|
|
|
905b4d |
struct sysdb_attrs *gid_override_attrs = NULL;
|
|
|
905b4d |
+ char ** exop_grouplist;
|
|
|
905b4d |
|
|
|
905b4d |
tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
if (tmp_ctx == NULL) {
|
|
|
905b4d |
@@ -2000,8 +2001,19 @@ static errno_t ipa_s2n_save_objects(struct sss_domain_info *dom,
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
- ret = diff_string_lists(tmp_ctx, attrs->groups, sysdb_grouplist,
|
|
|
905b4d |
- &add_groups, &del_groups, NULL);
|
|
|
905b4d |
+ /* names returned by extdom exop will be all lower case, since
|
|
|
905b4d |
+ * we handle domain names case sensitve in the cache we have
|
|
|
905b4d |
+ * to make sure we use the right case. */
|
|
|
905b4d |
+ ret = fix_domain_in_name_list(tmp_ctx, dom, attrs->groups,
|
|
|
905b4d |
+ &exop_grouplist);
|
|
|
905b4d |
+ if (ret != EOK) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "fix_domain_name failed.\n");
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = diff_string_lists(tmp_ctx, exop_grouplist,
|
|
|
905b4d |
+ sysdb_grouplist, &add_groups,
|
|
|
905b4d |
+ &del_groups, NULL);
|
|
|
905b4d |
if (ret != EOK) {
|
|
|
905b4d |
DEBUG(SSSDBG_OP_FAILURE, "diff_string_lists failed.\n");
|
|
|
905b4d |
goto done;
|
|
|
905b4d |
diff --git a/src/tests/cmocka/test_utils.c b/src/tests/cmocka/test_utils.c
|
|
|
905b4d |
index 5dc00c4cc9707776fabda50ad1eab8e582b16c0f..dc6e35dc02204714c5befbf4d67e7e7cbd8f4af1 100644
|
|
|
905b4d |
--- a/src/tests/cmocka/test_utils.c
|
|
|
905b4d |
+++ b/src/tests/cmocka/test_utils.c
|
|
|
905b4d |
@@ -1030,6 +1030,48 @@ void test_sss_write_krb5_conf_snippet(void **state)
|
|
|
905b4d |
free(path);
|
|
|
905b4d |
}
|
|
|
905b4d |
|
|
|
905b4d |
+
|
|
|
905b4d |
+void test_fix_domain_in_name_list(void **state)
|
|
|
905b4d |
+{
|
|
|
905b4d |
+ struct name_init_test_ctx *test_ctx;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ int ret;
|
|
|
905b4d |
+ struct sss_domain_info *sd;
|
|
|
905b4d |
+ struct sss_domain_info *dom;
|
|
|
905b4d |
+ const char *in[] = { "abc@test.case.dom", "def@TEST.case.DOM", NULL};
|
|
|
905b4d |
+ char **out = NULL;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ test_ctx = talloc_get_type(*state, struct name_init_test_ctx);
|
|
|
905b4d |
+ assert_non_null(test_ctx);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = confdb_get_domains(test_ctx->confdb, &dom;;
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = sss_names_init(dom, test_ctx->confdb, NULL, &dom->names);
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ sd = talloc_zero(test_ctx, struct sss_domain_info);
|
|
|
905b4d |
+ assert_non_null(sd);
|
|
|
905b4d |
+ sd->name = talloc_strdup(sd, "TesT.CasE.DoM");
|
|
|
905b4d |
+ assert_non_null(sd->name);
|
|
|
905b4d |
+ sd->names = dom->names;
|
|
|
905b4d |
+ DLIST_ADD(dom->subdomains, sd);
|
|
|
905b4d |
+ sd->parent = dom;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = fix_domain_in_name_list(test_ctx, dom, discard_const(in), &out;;
|
|
|
905b4d |
+ assert_int_equal(ret, EOK);
|
|
|
905b4d |
+ assert_non_null(out);
|
|
|
905b4d |
+ assert_non_null(out[0]);
|
|
|
905b4d |
+ assert_string_equal(out[0], "abc@TesT.CasE.DoM");
|
|
|
905b4d |
+ assert_non_null(out[1]);
|
|
|
905b4d |
+ assert_string_equal(out[1], "def@TesT.CasE.DoM");
|
|
|
905b4d |
+ assert_null(out[2]);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ talloc_free(out);
|
|
|
905b4d |
+ talloc_free(sd);
|
|
|
905b4d |
+ talloc_free(dom);
|
|
|
905b4d |
+}
|
|
|
905b4d |
+
|
|
|
905b4d |
int main(int argc, const char *argv[])
|
|
|
905b4d |
{
|
|
|
905b4d |
poptContext pc;
|
|
|
905b4d |
@@ -1078,6 +1120,8 @@ int main(int argc, const char *argv[])
|
|
|
905b4d |
setup_add_strings_lists,
|
|
|
905b4d |
teardown_add_strings_lists),
|
|
|
905b4d |
unit_test(test_sss_write_krb5_conf_snippet),
|
|
|
905b4d |
+ unit_test_setup_teardown(test_fix_domain_in_name_list,
|
|
|
905b4d |
+ confdb_test_setup, confdb_test_teardown),
|
|
|
905b4d |
};
|
|
|
905b4d |
|
|
|
905b4d |
/* Set debug level to invalid value so we can deside if -d 0 was used. */
|
|
|
905b4d |
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
|
|
|
905b4d |
index e04b905768078c503168f27327f974c0f19a6775..e0f1120e3c96757b0ad623b7dd6d43af2e643589 100644
|
|
|
905b4d |
--- a/src/util/domain_info_utils.c
|
|
|
905b4d |
+++ b/src/util/domain_info_utils.c
|
|
|
905b4d |
@@ -777,3 +777,75 @@ done:
|
|
|
905b4d |
|
|
|
905b4d |
return ret;
|
|
|
905b4d |
}
|
|
|
905b4d |
+
|
|
|
905b4d |
+errno_t fix_domain_in_name_list(TALLOC_CTX *mem_ctx,
|
|
|
905b4d |
+ struct sss_domain_info *dom,
|
|
|
905b4d |
+ char **in, char ***_out)
|
|
|
905b4d |
+{
|
|
|
905b4d |
+ int ret;
|
|
|
905b4d |
+ size_t c;
|
|
|
905b4d |
+ TALLOC_CTX *tmp_ctx;
|
|
|
905b4d |
+ char **out;
|
|
|
905b4d |
+ struct sss_domain_info *head;
|
|
|
905b4d |
+ struct sss_domain_info *out_domain;
|
|
|
905b4d |
+ char *in_name;
|
|
|
905b4d |
+ char *in_domain;
|
|
|
905b4d |
+
|
|
|
905b4d |
+ head = get_domains_head(dom);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ tmp_ctx = talloc_new(NULL);
|
|
|
905b4d |
+ if (tmp_ctx == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
|
|
|
905b4d |
+ return ENOMEM;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ /* count elements */
|
|
|
905b4d |
+ for (c = 0; in[c] != NULL; c++);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ out = talloc_zero_array(tmp_ctx, char *, c + 1);
|
|
|
905b4d |
+ if (out == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_array failed.\n");
|
|
|
905b4d |
+ ret = ENOMEM;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ for (c = 0; in[c] != NULL; c++) {
|
|
|
905b4d |
+ ret = sss_parse_name(tmp_ctx, head->names, in[c], &in_domain,
|
|
|
905b4d |
+ &in_name);
|
|
|
905b4d |
+ if (ret != EOK) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "sss_parse_name failed for [%s].\n",
|
|
|
905b4d |
+ in[c]);
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ if (in_domain == NULL) {
|
|
|
905b4d |
+ out[c] = talloc_strdup(out, in_name);
|
|
|
905b4d |
+ } else {
|
|
|
905b4d |
+ out_domain = find_domain_by_name(head, in_domain, true);
|
|
|
905b4d |
+ if (out_domain == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
905b4d |
+ "Cannot find domain with name [%s].\n", in_domain);
|
|
|
905b4d |
+ ret = EINVAL;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ out[c] = sss_tc_fqname(out, head->names, out_domain, in_name);
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ if (out[c] == NULL) {
|
|
|
905b4d |
+ DEBUG(SSSDBG_OP_FAILURE, "%s failed.\n",
|
|
|
905b4d |
+ in_domain == NULL ? "talloc_strdup" : "sss_tc_fqname");
|
|
|
905b4d |
+ ret = ENOMEM;
|
|
|
905b4d |
+ goto done;
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+ }
|
|
|
905b4d |
+
|
|
|
905b4d |
+ *_out = talloc_steal(mem_ctx, out);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ ret = EOK;
|
|
|
905b4d |
+
|
|
|
905b4d |
+done:
|
|
|
905b4d |
+ talloc_free(tmp_ctx);
|
|
|
905b4d |
+
|
|
|
905b4d |
+ return ret;
|
|
|
905b4d |
+}
|
|
|
905b4d |
diff --git a/src/util/util.h b/src/util/util.h
|
|
|
905b4d |
index 45efd1aef94c2e058a435933e7c41adaecc676e2..23624c8156a053bc6c30bda9796029af3da62d3a 100644
|
|
|
905b4d |
--- a/src/util/util.h
|
|
|
905b4d |
+++ b/src/util/util.h
|
|
|
905b4d |
@@ -589,6 +589,9 @@ errno_t get_dom_names(TALLOC_CTX *mem_ctx,
|
|
|
905b4d |
char ***_dom_names,
|
|
|
905b4d |
int *_dom_names_count);
|
|
|
905b4d |
|
|
|
905b4d |
+errno_t fix_domain_in_name_list(TALLOC_CTX *mem_ctx,
|
|
|
905b4d |
+ struct sss_domain_info *dom,
|
|
|
905b4d |
+ char **in, char ***_out);
|
|
|
905b4d |
/* from util_lock.c */
|
|
|
905b4d |
errno_t sss_br_lock_file(int fd, size_t start, size_t len,
|
|
|
905b4d |
int num_tries, useconds_t wait);
|
|
|
905b4d |
--
|
|
|
905b4d |
2.1.0
|
|
|
905b4d |
|