dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

Blame SOURCES/0175-IPA-properly-handle-mixed-case-trusted-domains.patch

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