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 28ef135c6e82b1ed0f345c72e686ec948c8b485b 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

---
 src/db/sysdb_subdomains.c                | 238 ++++++++++++++++++-------------
 src/tests/cmocka/test_sysdb_subdomains.c |   2 +-
 2 files changed, 136 insertions(+), 104 deletions(-)

diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index ff83f91..db6716e 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1145,144 +1145,176 @@ 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 struct sysdb_attrs *match_cn_users(TALLOC_CTX *tmp_ctx,
+                                          struct sysdb_attrs **usr_attrs,
+                                          size_t count,
+                                          char *dom_basedn)
 {
-    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;
+    cn_users_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
+    if (cn_users_basedn == NULL) {
+        return NULL;
     }
+    cn_users_basedn_len = strlen(cn_users_basedn);
+    DEBUG(SSSDBG_TRACE_ALL, "cn=users baseDN is [%s].\n", cn_users_basedn);
 
-    tmp_ctx = talloc_new(NULL);
-    if (tmp_ctx == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
-        return ENOMEM;
-    }
+    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");
+            return NULL;
+        }
+        dn_len = strlen(orig_dn);
 
-    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;
+        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) {
+                DEBUG(SSSDBG_OP_FAILURE,
+                      "Found 2 matching DN [%s] and [%s], expecting only 1.\n",
+                      result_dn_str, orig_dn);
+                return NULL;
+            }
+            result = usr_attrs[c];
+            result_dn_str = orig_dn;
+        }
     }
 
+    return result;
+}
+
+static struct sysdb_attrs *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)
+{
+    errno_t ret;
+    const char *orig_dn;
+    size_t orig_dn_len;
+    size_t dom_basedn_len;
+    struct ldb_dn *ldb_orig_dn;
+    struct ldb_context *ldb_ctx;
+    struct sysdb_attrs *result = NULL;
+    const char *result_dn_str = NULL;
+    struct ldb_dn *ldb_dom_basedn;
+    int dom_basedn_comp_num;
+    int dn_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;
+        return NULL;
     }
 
+    dom_basedn_len = strlen(dom_basedn);
+
     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");
-        ret = ENOMEM;
-        goto done;
+        return NULL;
     }
 
     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");
-            goto done;
-        }
-        dn_len = strlen(orig_dn);
-
-        if (dn_len > expected_basedn_len
-                && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
-                              expected_basedn) == 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;
+            return NULL;
         }
-    }
-
-    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");
-                goto done;
+        orig_dn_len = strlen(orig_dn);
+
+        if (orig_dn_len > dom_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 - dom_basedn_len),
+                              dom_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");
+                return NULL;
             }
-            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 > dom_basedn_comp_num) {
+                component_name = ldb_dn_get_component_name(ldb_orig_dn,
+                        (dn_comp_num - dom_basedn_comp_num));
+                DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
+                      component_name,
+                      domain_component_name);
+                /* Does the original DN's pre-base DN component match this
+                 * domain's component?
+                 */
+                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);
+                        return NULL;
                     }
+                    result = usr_attrs[c];
+                    result_dn_str = orig_dn;
                 }
             }
         }
     }
 
+    return 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;
+    }
+
+    result = match_cn_users(tmp_ctx, usr_attrs, count, dom_basedn);
+    if (result == NULL) {
+        result = match_basedn(tmp_ctx, dom, usr_attrs,
+                              count, dom_basedn, domain_component_name);
+    }
+
     if (result == NULL) {
         DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
         ret = ENOENT;
diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
index c9db568..bc34497 100644
--- a/src/tests/cmocka/test_sysdb_subdomains.c
+++ b/src/tests/cmocka/test_sysdb_subdomains.c
@@ -564,7 +564,7 @@ static void test_try_to_find_expected_dn(void **state)
     assert_ptr_equal(result, usr_attrs[1]);
 
     ret = sysdb_try_to_find_expected_dn(dom, "xy", usr_attrs, 3, &result);
-    assert_int_equal(ret, EINVAL);
+    assert_int_equal(ret, ENOENT);
 
     /* Make sure cn=users match is preferred */
     talloc_free(usr_attrs[2]);

From 05a0b756cc2d29e6a893572c5df81f8e879e8c8d Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhro...@redhat.com>
Date: Mon, 31 Oct 2016 21:24:10 +0100
Subject: [PATCH 2/2] SYSDB: Augment sysdb_try_to_find_expected_dn to match
 search base, too

---
 src/db/sysdb.h                             |   1 +
 src/db/sysdb_subdomains.c                  | 157 +++++++++++++++++++++++------
 src/providers/ldap/sdap_async_initgroups.c |   4 +-
 src/tests/cmocka/test_sysdb_subdomains.c   |  42 ++++++--
 4 files changed, 168 insertions(+), 36 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 db6716e..73d4633 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1148,7 +1148,7 @@ errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name)
 static struct sysdb_attrs *match_cn_users(TALLOC_CTX *tmp_ctx,
                                           struct sysdb_attrs **usr_attrs,
                                           size_t count,
-                                          char *dom_basedn)
+                                          const char *dom_basedn)
 {
     errno_t ret;
     const char *orig_dn;
@@ -1192,25 +1192,25 @@ static struct sysdb_attrs *match_cn_users(TALLOC_CTX *tmp_ctx,
     return result;
 }
 
-static struct sysdb_attrs *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)
+static struct sysdb_attrs *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)
 {
     errno_t ret;
     const char *orig_dn;
     size_t orig_dn_len;
-    size_t dom_basedn_len;
-    struct ldb_dn *ldb_orig_dn;
+    size_t basedn_len;
     struct ldb_context *ldb_ctx;
-    struct sysdb_attrs *result = NULL;
-    const char *result_dn_str = NULL;
-    struct ldb_dn *ldb_dom_basedn;
-    int dom_basedn_comp_num;
+    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) {
@@ -1218,16 +1218,10 @@ static struct sysdb_attrs *match_basedn(TALLOC_CTX *tmp_ctx,
         return NULL;
     }
 
-    dom_basedn_len = strlen(dom_basedn);
-
-    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 NULL;
-    }
+    basedn_len = strlen(basedn);
 
-    dom_basedn_comp_num = ldb_dn_get_comp_num(ldb_dom_basedn);
-    dom_basedn_comp_num++;
+    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);
@@ -1237,12 +1231,12 @@ static struct sysdb_attrs *match_basedn(TALLOC_CTX *tmp_ctx,
         }
         orig_dn_len = strlen(orig_dn);
 
-        if (orig_dn_len > dom_basedn_len
+        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 - dom_basedn_len),
-                              dom_basedn) == 0) {
+                && 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");
@@ -1250,14 +1244,16 @@ static struct sysdb_attrs *match_basedn(TALLOC_CTX *tmp_ctx,
             }
 
             dn_comp_num = ldb_dn_get_comp_num(ldb_orig_dn);
-            if (dn_comp_num > dom_basedn_comp_num) {
+            if (dn_comp_num > basedn_comp_num) {
                 component_name = ldb_dn_get_component_name(ldb_orig_dn,
-                        (dn_comp_num - dom_basedn_comp_num));
+                        (dn_comp_num - basedn_comp_num));
                 DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
                       component_name,
                       domain_component_name);
-                /* Does the original DN's pre-base DN component match this
-                 * domain's component?
+                /* 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,
@@ -1280,8 +1276,104 @@ static struct sysdb_attrs *match_basedn(TALLOC_CTX *tmp_ctx,
     return result;
 }
 
+static struct sysdb_attrs *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 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 NULL;
+    }
+
+
+    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 NULL;
+    }
+
+    return match_non_dc_comp(tmp_ctx, dom,
+                             usr_attrs, count,
+                             ldb_dom_basedn, dom_basedn,
+                             domain_component_name);
+}
+
+static struct sysdb_attrs *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)
+{
+    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");
+        return NULL;
+    }
+
+    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");
+        return NULL;
+    }
+
+    /* 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 (strcmp(domain_component_name, component_name) == 0) {
+            break;
+        }
+    }
+
+    if (non_dc_comp_num == search_base_comp_num) {
+        return NULL;
+    }
+
+    ok = ldb_dn_remove_child_components(ldb_search_base, non_dc_comp_num);
+    if (!ok) {
+        return NULL;
+    }
+
+    search_base = ldb_dn_get_linearized(ldb_search_base);
+    if (search_base == NULL) {
+        return NULL;
+    }
+
+    result = match_cn_users(tmp_ctx, usr_attrs, count, search_base);
+    if (result == NULL) {
+        result = match_non_dc_comp(tmp_ctx, dom,
+                                   usr_attrs, count,
+                                   ldb_search_base, search_base,
+                                   domain_component_name);
+    }
+
+    return result;
+}
+
 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)
@@ -1292,6 +1384,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;
     }
@@ -1310,12 +1403,18 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
     }
 
     result = match_cn_users(tmp_ctx, usr_attrs, count, dom_basedn);
+
     if (result == NULL) {
         result = match_basedn(tmp_ctx, dom, usr_attrs,
                               count, dom_basedn, domain_component_name);
     }
 
     if (result == NULL) {
+        result = match_search_base(tmp_ctx, dom, domain_component_name,
+                                   domain_search_base, usr_attrs, count);
+    }
+
+    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..2ed2c36 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -2947,7 +2947,9 @@ 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,
+        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 bc34497..67098e3 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, ENOENT);
 
     /* Make sure cn=users match is preferred */
@@ -575,10 +580,35 @@ 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);
+
+    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