URL: https://github.com/SSSD/sssd/pull/49
Author: jhrozek
 Title: #49: Try to match multiple results from an AD initgroups request 
against domain's search bases, too
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/49/head:pr49
git checkout pr49
From 846d269d350e1968480f3ad92fe72a6f11dd3c52 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Fri, 28 Oct 2016 13:46:02 +0200
Subject: [PATCH 1/2] SYSDB: Split sysdb_try_to_find_expected_dn() into smaller
 functions

The function sysdb_try_to_find_expected_dn was performing several matching
algorithms and thus it was getting big and hard to extend. This patch
doesn't contain any functional changes, only shuffles the code around
and splits the monolithic sysdb_try_to_find_expected_dn function into
smaller blocks.
---
 src/db/sysdb_subdomains.c | 278 +++++++++++++++++++++++++++++-----------------
 1 file changed, 179 insertions(+), 99 deletions(-)

diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index ff83f91..b011bad 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1145,74 +1145,29 @@ errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name)
     return ret;
 }
 
-errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
-                                      const char *domain_component_name,
-                                      struct sysdb_attrs **usr_attrs,
-                                      size_t count,
-                                      struct sysdb_attrs **exp_usr)
+static errno_t match_cn_users(TALLOC_CTX *tmp_ctx,
+                              struct sysdb_attrs **usr_attrs,
+                              size_t count,
+                              const char *dom_basedn,
+                              struct sysdb_attrs **_result)
 {
-    char *dom_basedn;
-    size_t dom_basedn_len;
-    char *expected_basedn;
-    size_t expected_basedn_len;
-    size_t dn_len;
+    errno_t ret;
     const char *orig_dn;
-    size_t c = 0;
-    int ret;
-    TALLOC_CTX *tmp_ctx;
-    struct ldb_context *ldb_ctx;
-    struct ldb_dn *ldb_dom_basedn;
-    int dom_basedn_comp_num;
-    struct ldb_dn *ldb_dn;
-    int dn_comp_num;
-    const char *component_name;
+    size_t dn_len;
     struct sysdb_attrs *result = NULL;
     const char *result_dn_str = NULL;
+    char *cn_users_basedn;
+    size_t cn_users_basedn_len;
 
-    if (dom == NULL || domain_component_name == NULL || usr_attrs == NULL
-            || count == 0) {
-        return EINVAL;
-    }
-
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
-        return ENOMEM;
-    }
-
-    ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
-    if (ret != EOK) {
-        DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
-        goto done;
-    }
-    expected_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
-    if (expected_basedn == NULL) {
-        ret = ENOMEM;
-        goto done;
-    }
-
-    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
-    if (ldb_ctx == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
-        ret = EINVAL;
-        goto done;
-    }
-
-    ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
-    if (ldb_dom_basedn == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+    cn_users_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
+    if (cn_users_basedn == NULL) {
         ret = ENOMEM;
         goto done;
     }
+    cn_users_basedn_len = strlen(cn_users_basedn);
+    DEBUG(SSSDBG_TRACE_ALL, "cn=users baseDN is [%s].\n", cn_users_basedn);
 
-    dom_basedn_comp_num = ldb_dn_get_comp_num(ldb_dom_basedn);
-    dom_basedn_comp_num++;
-
-    DEBUG(SSSDBG_TRACE_ALL, "Expected BaseDN is [%s].\n", expected_basedn);
-    expected_basedn_len = strlen(expected_basedn);
-    dom_basedn_len = strlen(dom_basedn);
-
-    for (c = 0; c < count; c++) {
+    for (size_t c = 0; c < count; c++) {
         ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
         if (ret != EOK) {
             DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
@@ -1220,9 +1175,9 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
         }
         dn_len = strlen(orig_dn);
 
-        if (dn_len > expected_basedn_len
-                && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
-                              expected_basedn) == 0) {
+        if (dn_len > cn_users_basedn_len
+                && strcasecmp(orig_dn + (dn_len - cn_users_basedn_len),
+                              cn_users_basedn) == 0) {
             DEBUG(SSSDBG_TRACE_ALL,
                   "Found matching dn [%s].\n", orig_dn);
             if (result != NULL) {
@@ -1237,52 +1192,177 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
         }
     }
 
-    if (result == NULL) {
-        for (c = 0; c < count; c++) {
-            ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
-            if (ret != EOK) {
-                DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+    ret = EOK;
+done:
+    *_result = result;
+    return ret;
+}
+
+static errno_t match_non_dc_comp(TALLOC_CTX *tmp_ctx,
+                                 struct sss_domain_info *dom,
+                                 struct sysdb_attrs **usr_attrs,
+                                 size_t count,
+                                 struct ldb_dn *ldb_basedn,
+                                 const char *basedn,
+                                 const char *domain_component_name,
+                                 struct sysdb_attrs **_result)
+{
+    errno_t ret;
+    const char *orig_dn;
+    size_t orig_dn_len;
+    size_t basedn_len;
+    struct ldb_context *ldb_ctx;
+    struct ldb_dn *ldb_orig_dn;
+    int dn_comp_num;
+    int basedn_comp_num;
+    const char *component_name;
+    struct sysdb_attrs *result = NULL;
+    const char *result_dn_str = NULL;
+
+    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
+    if (ldb_ctx == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
+        ret = EINVAL;
+        goto done;
+    }
+
+    basedn_len = strlen(basedn);
+
+    basedn_comp_num = ldb_dn_get_comp_num(ldb_basedn);
+    basedn_comp_num++;
+
+    for (size_t c = 0; c < count; c++) {
+        ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
+        if (ret != EOK) {
+            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+            goto done;
+        }
+        orig_dn_len = strlen(orig_dn);
+
+        if (orig_dn_len > basedn_len
+                /* Does the user's original DN with the non-domain part
+                 * stripped match the domain base DN?
+                 */
+                && strcasecmp(orig_dn + (orig_dn_len - basedn_len),
+                              basedn) == 0) {
+            ldb_orig_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
+            if (ldb_orig_dn == NULL) {
+                DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
+                ret = ENOMEM;
                 goto done;
             }
-            dn_len = strlen(orig_dn);
-
-            if (dn_len > dom_basedn_len
-                    && strcasecmp(orig_dn + (dn_len - dom_basedn_len),
-                                  dom_basedn) == 0) {
-                ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
-                if (ldb_dn == NULL) {
-                    DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
-                    ret = ENOMEM;
-                    goto done;
-                }
 
-                dn_comp_num = ldb_dn_get_comp_num(ldb_dn);
-                if (dn_comp_num > dom_basedn_comp_num) {
-                    component_name = ldb_dn_get_component_name(ldb_dn,
-                                           (dn_comp_num - dom_basedn_comp_num));
-                    DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
-                                            component_name,
-                                            domain_component_name);
-                    if (component_name != NULL
-                            && strcasecmp(component_name,
-                                          domain_component_name) != 0) {
-                        DEBUG(SSSDBG_TRACE_ALL,
-                              "Found matching dn [%s].\n", orig_dn);
-                        if (result != NULL) {
-                            DEBUG(SSSDBG_OP_FAILURE,
-                                 "Found 2 matching DN [%s] and [%s], "
-                                 "expecting only 1.\n", result_dn_str, orig_dn);
-                            ret = EINVAL;
-                            goto done;
-                        }
-                        result = usr_attrs[c];
-                        result_dn_str = orig_dn;
+            dn_comp_num = ldb_dn_get_comp_num(ldb_orig_dn);
+            if (dn_comp_num > basedn_comp_num) {
+                component_name = ldb_dn_get_component_name(ldb_orig_dn,
+                        (dn_comp_num - basedn_comp_num));
+                DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
+                      component_name,
+                      domain_component_name);
+                /* If the component is NOT a DC component, then the entry
+                 * must come from our domain, perhaps from a child container.
+                 * If it matched the DC component, the entry was from a child
+                 * subdomain different from this one.
+                 */
+                if (component_name != NULL
+                        && strcasecmp(component_name,
+                                      domain_component_name) != 0) {
+                    DEBUG(SSSDBG_TRACE_ALL,
+                            "Found matching dn [%s].\n", orig_dn);
+                    if (result != NULL) {
+                        DEBUG(SSSDBG_OP_FAILURE,
+                                "Found 2 matching DN [%s] and [%s], "
+                                "expecting only 1.\n", result_dn_str, orig_dn);
+                        ret = EINVAL;
+                        goto done;
                     }
+                    result = usr_attrs[c];
+                    result_dn_str = orig_dn;
                 }
             }
         }
     }
 
+    ret = EOK;
+    *_result = result;
+done:
+    return ret;
+}
+
+static errno_t match_basedn(TALLOC_CTX *tmp_ctx,
+                            struct sss_domain_info *dom,
+                            struct sysdb_attrs **usr_attrs,
+                            size_t count,
+                            const char *dom_basedn,
+                            const char *domain_component_name,
+                            struct sysdb_attrs **_result)
+{
+    struct ldb_context *ldb_ctx;
+    struct ldb_dn *ldb_dom_basedn;
+
+    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
+    if (ldb_ctx == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
+        return EINVAL;
+    }
+
+
+    ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
+    if (ldb_dom_basedn == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+        return ENOMEM;
+    }
+
+    return match_non_dc_comp(tmp_ctx, dom,
+                             usr_attrs, count,
+                             ldb_dom_basedn, dom_basedn,
+                             domain_component_name,
+                             _result);
+}
+
+errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
+                                      const char *domain_component_name,
+                                      struct sysdb_attrs **usr_attrs,
+                                      size_t count,
+                                      struct sysdb_attrs **exp_usr)
+{
+    char *dom_basedn;
+    int ret;
+    TALLOC_CTX *tmp_ctx;
+    struct sysdb_attrs *result = NULL;
+
+    if (dom == NULL || domain_component_name == NULL
+            || usr_attrs == NULL || count == 0) {
+        return EINVAL;
+    }
+
+    tmp_ctx = talloc_new(NULL);
+    if (tmp_ctx == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
+        return ENOMEM;
+    }
+
+    ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
+        ret = EINVAL;
+        goto done;
+    }
+
+    ret = match_cn_users(tmp_ctx, usr_attrs, count, dom_basedn, &result);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    if (result == NULL) {
+        ret = match_basedn(tmp_ctx, dom, usr_attrs,
+                           count, dom_basedn, domain_component_name,
+                           &result);
+        if (ret != EOK) {
+            goto done;
+        }
+    }
+
     if (result == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
         ret = ENOENT;

From 959d66e7d0dca7fc515fcdd3bd0ef22b5e84b41c Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Mon, 31 Oct 2016 21:39:57 +0100
Subject: [PATCH 2/2] SYSDB: Augment sysdb_try_to_find_expected_dn to match
 search base as well

In cases where the domain name in sssd.conf does not match the AD
domain, our previous matching process wouldn't match. This patch
augments the matching as follows:
    - the search base is known to sysdb_try_to_find_expected_dn and is
      expected to be non-NULL
    - the existing matching is ran first
    - during the search base, matching, all the non-DC components are
      stripped from the search base to 'canonicalize' the search base
    - if only a single entry that matches with a non-DC DN component
      (matching with a DC component would mean the DN comes from a
      different domain) then this entry is a match and is returned

Resolves:
https://fedorahosted.org/sssd/ticket/3199
---
 src/db/sysdb.h                             |  1 +
 src/db/sysdb_subdomains.c                  | 99 ++++++++++++++++++++++++++++++
 src/providers/ldap/sdap_async_initgroups.c |  8 ++-
 src/tests/cmocka/test_sysdb_subdomains.c   | 43 +++++++++++--
 4 files changed, 144 insertions(+), 7 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 9012683..5dedd97 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -1297,6 +1297,7 @@ errno_t sysdb_handle_original_uuid(const char *orig_name,
 
 errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
                                       const char *domain_component_name,
+                                      const char *ldap_search_base,
                                       struct sysdb_attrs **usr_attrs,
                                       size_t count,
                                       struct sysdb_attrs **exp_usr);
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index b011bad..7801404 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1320,8 +1320,97 @@ static errno_t match_basedn(TALLOC_CTX *tmp_ctx,
                              _result);
 }
 
+static errno_t match_search_base(TALLOC_CTX *tmp_ctx,
+                                 struct sss_domain_info *dom,
+                                 const char *domain_component_name,
+                                 const char *domain_search_base,
+                                 struct sysdb_attrs **usr_attrs,
+                                 size_t count,
+                                 struct sysdb_attrs **_result)
+{
+    errno_t ret;
+    bool ok;
+    const char *search_base;
+    struct ldb_context *ldb_ctx;
+    struct sysdb_attrs *result = NULL;
+    struct ldb_dn *ldb_search_base;
+    int search_base_comp_num;
+    int non_dc_comp_num;
+    const char *component_name;
+
+    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
+    if (ldb_ctx == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
+        ret = EINVAL;
+        goto done;
+    }
+
+    ldb_search_base = ldb_dn_new(tmp_ctx, ldb_ctx, domain_search_base);
+    if (ldb_search_base == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
+        ret = ENOMEM;
+        goto done;
+    }
+
+    /* strip non-DC components from the search base */
+    search_base_comp_num = ldb_dn_get_comp_num(ldb_search_base);
+    for (non_dc_comp_num = 0;
+         non_dc_comp_num < search_base_comp_num;
+         non_dc_comp_num++) {
+
+        component_name = ldb_dn_get_component_name(ldb_search_base,
+                                                   non_dc_comp_num);
+        if (strcasecmp(domain_component_name, component_name) == 0) {
+            break;
+        }
+    }
+
+    if (non_dc_comp_num == search_base_comp_num) {
+        /* The search base does not have any non-DC components, the search wouldn't
+         * match anyway
+         */
+        ret = EOK;
+        *_result = NULL;
+        goto done;
+    }
+
+    ok = ldb_dn_remove_child_components(ldb_search_base, non_dc_comp_num);
+    if (!ok) {
+        ret = EINVAL;
+        goto done;
+    }
+
+    search_base = ldb_dn_get_linearized(ldb_search_base);
+    if (search_base == NULL) {
+        ret = ENOMEM;
+        goto done;
+    }
+
+    ret = match_cn_users(tmp_ctx, usr_attrs, count, search_base, &result);
+    if (ret != EOK) {
+        goto done;
+    }
+
+    if (result == NULL) {
+        ret = match_non_dc_comp(tmp_ctx, dom,
+                                usr_attrs, count,
+                                ldb_search_base, search_base,
+                                domain_component_name,
+                                &result);
+        if (ret != EOK) {
+            goto done;
+        }
+    }
+
+    ret = EOK;
+    *_result = result;
+done:
+    return ret;
+}
+
 errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
                                       const char *domain_component_name,
+                                      const char *domain_search_base,
                                       struct sysdb_attrs **usr_attrs,
                                       size_t count,
                                       struct sysdb_attrs **exp_usr)
@@ -1332,6 +1421,7 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
     struct sysdb_attrs *result = NULL;
 
     if (dom == NULL || domain_component_name == NULL
+            || domain_search_base == NULL
             || usr_attrs == NULL || count == 0) {
         return EINVAL;
     }
@@ -1364,6 +1454,15 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
     }
 
     if (result == NULL) {
+        ret = match_search_base(tmp_ctx, dom, domain_component_name,
+                                   domain_search_base, usr_attrs, count,
+                                   &result);
+        if (ret != EOK) {
+            goto done;
+        }
+    }
+
+    if (result == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
         ret = ENOENT;
         goto done;
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 45fc007..9b505e7 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2947,7 +2947,13 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
         DEBUG(SSSDBG_OP_FAILURE,
               "Expected one user entry and got %zu\n", count);
 
-        ret = sysdb_try_to_find_expected_dn(state->dom, "dc", usr_attrs, count,
+        /* When matching against a search base, it's sufficient to pick only
+         * the first search base because all bases in a single domain would
+         * have the same DC= components
+         */
+        ret = sysdb_try_to_find_expected_dn(state->dom, "dc",
+                                            state->sdom->search_bases[0]->basedn,
+                                            usr_attrs, count,
                                             &state->orig_user);
         if (ret != EOK) {
             DEBUG(SSSDBG_OP_FAILURE,
diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
index c9db568..52056e0 100644
--- a/src/tests/cmocka/test_sysdb_subdomains.c
+++ b/src/tests/cmocka/test_sysdb_subdomains.c
@@ -520,7 +520,9 @@ static void test_try_to_find_expected_dn(void **state)
     int ret;
     struct sysdb_attrs *result;
     struct sysdb_attrs *usr_attrs[10] = { NULL };
+    struct sysdb_attrs *dom_usr_attrs[10] = { NULL };
     struct sss_domain_info *dom;
+    char *dom_basedn;
     struct subdom_test_ctx *test_ctx =
         talloc_get_type(*state, struct subdom_test_ctx);
 
@@ -528,6 +530,9 @@ static void test_try_to_find_expected_dn(void **state)
                               "child2.test_sysdb_subdomains_2", true);
     assert_non_null(dom);
 
+    ret = domain_to_basedn(test_ctx, dom->name, &dom_basedn);
+    assert_int_equal(ret, EOK);
+
     usr_attrs[0] = sysdb_new_attrs(test_ctx);
     assert_non_null(usr_attrs[0]);
 
@@ -535,13 +540,13 @@ static void test_try_to_find_expected_dn(void **state)
                   "uid=user,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
     assert_int_equal(ret, EOK);
 
-    ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, 0, NULL);
+    ret = sysdb_try_to_find_expected_dn(NULL, NULL, NULL, NULL, 0, NULL);
     assert_int_equal(ret, EINVAL);
 
-    ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 1, &result);
+    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 1, &result);
     assert_int_equal(ret, ENOENT);
 
-    ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 1, &result);
+    ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 1, &result);
     assert_int_equal(ret, EOK);
     assert_ptr_equal(result, usr_attrs[0]);
 
@@ -559,11 +564,11 @@ static void test_try_to_find_expected_dn(void **state)
                  "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
     assert_int_equal(ret, EOK);
 
-    ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
+    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result);
     assert_int_equal(ret, EOK);
     assert_ptr_equal(result, usr_attrs[1]);
 
-    ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 3, &result);
+    ret = sysdb_try_to_find_expected_dn(dom, "xy", dom_basedn, usr_attrs, 3, &result);
     assert_int_equal(ret, EINVAL);
 
     /* Make sure cn=users match is preferred */
@@ -575,10 +580,36 @@ static void test_try_to_find_expected_dn(void **state)
                  "uid=user2,cn=abc,cn=users,dc=child2,dc=test_sysdb_subdomains_2");
     assert_int_equal(ret, EOK);
 
-    ret = sysdb_try_to_find_expected_dn(dom, "dc", usr_attrs, 3, &result);
+    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, usr_attrs, 3, &result);
     assert_int_equal(ret, EOK);
     assert_ptr_equal(result, usr_attrs[2]);
 
+    /* test a case where the domain name does not match the basedn */
+    dom->name = discard_const("default");
+    dom_usr_attrs[0] = usr_attrs[0];
+
+    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 1, &result);
+    assert_int_equal(ret, ENOENT);
+
+    dom_usr_attrs[1] = usr_attrs[1];
+    dom_usr_attrs[2] = usr_attrs[2];
+
+    /* Make sure cn=users match is preferred */
+    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result);
+    assert_int_equal(ret, EOK);
+    assert_ptr_equal(result, dom_usr_attrs[2]);
+
+    talloc_free(usr_attrs[2]);
+    usr_attrs[2] = sysdb_new_attrs(test_ctx);
+    assert_non_null(usr_attrs[2]);
+    ret = sysdb_attrs_add_string(usr_attrs[2], SYSDB_ORIG_DN,
+                 "uid=user2,cn=abc,dc=c2,dc=child2,dc=test_sysdb_subdomains_2");
+    assert_int_equal(ret, EOK);
+
+    dom_usr_attrs[2] = usr_attrs[2];
+    ret = sysdb_try_to_find_expected_dn(dom, "dc", dom_basedn, dom_usr_attrs, 3, &result);
+    assert_int_equal(ret, EOK);
+    assert_ptr_equal(result, usr_attrs[1]);
 
     talloc_free(usr_attrs[0]);
     talloc_free(usr_attrs[1]);
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to