URL: https://github.com/SSSD/sssd/pull/85
Author: celestian
 Title: #85: SYSDB: Removing of sysdb_try_to_find_expected_dn()
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/85/head:pr85
git checkout pr85
From f2aff7002cf62fe6487d0b6065c0c14359040891 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com>
Date: Wed, 4 Jan 2017 15:33:30 +0100
Subject: [PATCH 1/3] SYSDB: Removing of sysdb_try_to_find_expected_dn()

Currently in order to match multiple LDAP search results we
use two different functions - we have sysdb_try_to_find_expected_dn()
but also sdap_object_in_domain().

This patch removes sysdb_try_to_find_expected_dn() and add new
sdap_search_initgr_user_in_batch() based on sdap_object_in_domain().
This function covers necessary logic.

Resolves:
https://fedorahosted.org/sssd/ticket/3230
---
 src/db/sysdb.h                             |   6 -
 src/db/sysdb_subdomains.c                  | 332 -----------------------------
 src/providers/ldap/sdap.c                  |   6 +-
 src/providers/ldap/sdap.h                  |   4 +
 src/providers/ldap/sdap_async_initgroups.c |  28 ++-
 src/tests/cmocka/test_sysdb_subdomains.c   | 104 ---------
 6 files changed, 30 insertions(+), 450 deletions(-)

diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 407a197..ae3ff35 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -1309,10 +1309,4 @@ errno_t sysdb_handle_original_uuid(const char *orig_name,
                                    struct sysdb_attrs *dest_attrs,
                                    const char *dest_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);
 #endif /* __SYS_DB_H__ */
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 7801404..1f43bfc 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1144,335 +1144,3 @@ errno_t sysdb_subdomain_delete(struct sysdb_ctx *sysdb, const char *name)
     talloc_free(tmp_ctx);
     return ret;
 }
-
-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)
-{
-    errno_t ret;
-    const char *orig_dn;
-    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;
-
-    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);
-
-    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 > 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);
-                ret = EINVAL;
-                goto done;
-            }
-            result = usr_attrs[c];
-            result_dn_str = orig_dn;
-        }
-    }
-
-    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_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);
-}
-
-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)
-{
-    char *dom_basedn;
-    int ret;
-    TALLOC_CTX *tmp_ctx;
-    struct sysdb_attrs *result = NULL;
-
-    if (dom == NULL || domain_component_name == NULL
-            || domain_search_base == 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) {
-        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;
-    }
-
-    *exp_usr = result;
-
-    ret = EOK;
-done:
-    talloc_free(tmp_ctx);
-
-    return ret;
-}
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
index dc7d5e0..050c225 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -1673,9 +1673,9 @@ char *sdap_make_oc_list(TALLOC_CTX *mem_ctx, struct sdap_attr_map *map)
     }
 }
 
-static bool sdap_object_in_domain(struct sdap_options *opts,
-                                  struct sysdb_attrs *obj,
-                                  struct sss_domain_info *dom)
+bool sdap_object_in_domain(struct sdap_options *opts,
+                           struct sysdb_attrs *obj,
+                           struct sss_domain_info *dom)
 {
     errno_t ret;
     const char *original_dn = NULL;
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index e3cb846..6d4543e 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -616,4 +616,8 @@ size_t sdap_steal_objects_in_dom(struct sdap_options *opts,
                                  size_t count,
                                  bool filter);
 
+bool sdap_object_in_domain(struct sdap_options *opts,
+                           struct sysdb_attrs *obj,
+                           struct sss_domain_info *dom);
+
 #endif /* _SDAP_H_ */
diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c
index 9b505e7..edb2981 100644
--- a/src/providers/ldap/sdap_async_initgroups.c
+++ b/src/providers/ldap/sdap_async_initgroups.c
@@ -23,6 +23,7 @@
 
 #include "util/util.h"
 #include "db/sysdb.h"
+#include "providers/ldap/sdap.h"
 #include "providers/ldap/sdap_async_private.h"
 #include "providers/ldap/ldap_common.h"
 #include "providers/ldap/sdap_idmap.h"
@@ -2890,6 +2891,25 @@ static errno_t sdap_get_initgr_next_base(struct tevent_req *req)
     return EOK;
 }
 
+static int sdap_search_initgr_user_in_batch(struct sdap_get_initgr_state *state,
+                                            struct sysdb_attrs **users,
+                                            size_t count)
+{
+    int ret = EINVAL;
+
+    for (size_t i = 0; i < count; i++) {
+        if (sdap_object_in_domain(state->opts, users[i], state->dom) == false) {
+            continue;
+        }
+
+        state->orig_user = talloc_steal(state, users[i]);
+        ret = EOK;
+        break;
+    }
+
+    return ret;
+}
+
 static void sdap_get_initgr_user(struct tevent_req *subreq)
 {
     struct tevent_req *req = tevent_req_callback_data(subreq,
@@ -2951,13 +2971,11 @@ static void sdap_get_initgr_user(struct tevent_req *subreq)
          * 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);
+        ret = sdap_search_initgr_user_in_batch(state, usr_attrs, count);
         if (ret != EOK) {
             DEBUG(SSSDBG_OP_FAILURE,
-                  "try_to_find_expected_dn failed. No matching DN found.\n");
+                  "sdap_search_initgr_user_in_batch failed. "
+                  "No matching DN found.\n");
             tevent_req_error(req, EINVAL);
             return;
         }
diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
index 52056e0..52242e5 100644
--- a/src/tests/cmocka/test_sysdb_subdomains.c
+++ b/src/tests/cmocka/test_sysdb_subdomains.c
@@ -515,107 +515,6 @@ static void test_sysdb_link_ad_multidom(void **state)
 
 }
 
-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);
-
-    dom = find_domain_by_name(test_ctx->tctx->dom,
-                              "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]);
-
-    ret = sysdb_attrs_add_string(usr_attrs[0], SYSDB_ORIG_DN,
-                  "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, NULL, 0, NULL);
-    assert_int_equal(ret, EINVAL);
-
-    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", dom_basedn, usr_attrs, 1, &result);
-    assert_int_equal(ret, EOK);
-    assert_ptr_equal(result, usr_attrs[0]);
-
-    usr_attrs[1] = sysdb_new_attrs(test_ctx);
-    assert_non_null(usr_attrs[1]);
-
-    ret = sysdb_attrs_add_string(usr_attrs[1], SYSDB_ORIG_DN,
-                 "uid=user1,cn=abc,dc=child2,dc=test_sysdb_subdomains_2");
-    assert_int_equal(ret, EOK);
-
-    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, 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", dom_basedn, usr_attrs, 3, &result);
-    assert_int_equal(ret, EINVAL);
-
-    /* Make sure cn=users match is preferred */
-    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,cn=users,dc=child2,dc=test_sysdb_subdomains_2");
-    assert_int_equal(ret, EOK);
-
-    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]);
-    talloc_free(usr_attrs[2]);
-}
-
 int main(int argc, const char *argv[])
 {
     int rv;
@@ -649,9 +548,6 @@ int main(int argc, const char *argv[])
         cmocka_unit_test_setup_teardown(test_sysdb_link_ad_multidom,
                                         test_sysdb_subdom_setup,
                                         test_sysdb_subdom_teardown),
-        cmocka_unit_test_setup_teardown(test_try_to_find_expected_dn,
-                                        test_sysdb_subdom_setup,
-                                        test_sysdb_subdom_teardown),
     };
 
     /* Set debug level to invalid value so we can deside if -d 0 was used. */

From dbb21d756f5bbfaff54a8fe412651ec6c20950b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com>
Date: Thu, 12 Jan 2017 13:16:10 +0100
Subject: [PATCH 2/3] TEST: create_multidom_test_ctx() extending

Function create_multidom_test_ctx() prepares test environment for
multidomains. This patch enables setting of different params for
each domain.

Resolves:
https://fedorahosted.org/sssd/ticket/3230
---
 src/tests/cmocka/test_ad_common.c        | 5 +----
 src/tests/cmocka/test_sysdb_subdomains.c | 5 +----
 src/tests/cmocka/test_sysdb_ts_cache.c   | 5 +----
 src/tests/common.h                       | 2 +-
 src/tests/common_dom.c                   | 6 +++---
 5 files changed, 7 insertions(+), 16 deletions(-)

diff --git a/src/tests/cmocka/test_ad_common.c b/src/tests/cmocka/test_ad_common.c
index 7ec2920..ea99989 100644
--- a/src/tests/cmocka/test_ad_common.c
+++ b/src/tests/cmocka/test_ad_common.c
@@ -78,9 +78,6 @@ struct ad_sysdb_test_ctx {
 static int test_ad_sysdb_setup(void **state)
 {
     struct ad_sysdb_test_ctx *test_ctx;
-    struct sss_test_conf_param params[] = {
-        { NULL, NULL },             /* Sentinel */
-    };
 
     assert_true(leak_check_setup());
 
@@ -92,7 +89,7 @@ static int test_ad_sysdb_setup(void **state)
 
     test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH,
                                               TEST_CONF_DB, domains,
-                                              TEST_ID_PROVIDER, params);
+                                              TEST_ID_PROVIDER, NULL);
     assert_non_null(test_ctx->tctx);
 
     *state = test_ctx;
diff --git a/src/tests/cmocka/test_sysdb_subdomains.c b/src/tests/cmocka/test_sysdb_subdomains.c
index 52242e5..49f4499 100644
--- a/src/tests/cmocka/test_sysdb_subdomains.c
+++ b/src/tests/cmocka/test_sysdb_subdomains.c
@@ -60,9 +60,6 @@ struct subdom_test_ctx {
 static int test_sysdb_subdom_setup(void **state)
 {
     struct subdom_test_ctx *test_ctx;
-    struct sss_test_conf_param params[] = {
-        { NULL, NULL },             /* Sentinel */
-    };
 
     assert_true(leak_check_setup());
 
@@ -74,7 +71,7 @@ static int test_sysdb_subdom_setup(void **state)
 
     test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH,
                                               TEST_CONF_DB, domains,
-                                              TEST_ID_PROVIDER, params);
+                                              TEST_ID_PROVIDER, NULL);
     assert_non_null(test_ctx->tctx);
 
     *state = test_ctx;
diff --git a/src/tests/cmocka/test_sysdb_ts_cache.c b/src/tests/cmocka/test_sysdb_ts_cache.c
index e950f88..f5aab73 100644
--- a/src/tests/cmocka/test_sysdb_ts_cache.c
+++ b/src/tests/cmocka/test_sysdb_ts_cache.c
@@ -74,9 +74,6 @@ const char *domains[] = { TEST_DOM1_NAME,
 static int test_sysdb_ts_setup(void **state)
 {
     struct sysdb_ts_test_ctx *test_ctx;
-    struct sss_test_conf_param params[] = {
-        { NULL, NULL },             /* Sentinel */
-    };
 
     assert_true(leak_check_setup());
 
@@ -88,7 +85,7 @@ static int test_sysdb_ts_setup(void **state)
 
     test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH,
                                               TEST_CONF_DB, domains,
-                                              TEST_ID_PROVIDER, params);
+                                              TEST_ID_PROVIDER, NULL);
     assert_non_null(test_ctx->tctx);
 
     check_leaks_push(test_ctx);
diff --git a/src/tests/common.h b/src/tests/common.h
index b49cfea..c06568d 100644
--- a/src/tests/common.h
+++ b/src/tests/common.h
@@ -92,7 +92,7 @@ create_multidom_test_ctx(TALLOC_CTX *mem_ctx,
                          const char *cdb_file,
                          const char **domains,
                          const char *id_provider,
-                         struct sss_test_conf_param *params);
+                         struct sss_test_conf_param **params);
 
 struct sss_test_ctx *
 create_dom_test_ctx(TALLOC_CTX *mem_ctx,
diff --git a/src/tests/common_dom.c b/src/tests/common_dom.c
index f1a92cc..def28d5 100644
--- a/src/tests/common_dom.c
+++ b/src/tests/common_dom.c
@@ -231,7 +231,7 @@ create_multidom_test_ctx(TALLOC_CTX *mem_ctx,
                          const char *cdb_file,
                          const char **domains,
                          const char *id_provider,
-                         struct sss_test_conf_param *params)
+                         struct sss_test_conf_param **params)
 {
     struct sss_domain_info *domain = NULL;
     struct sss_test_ctx *test_ctx = NULL;
@@ -255,7 +255,7 @@ create_multidom_test_ctx(TALLOC_CTX *mem_ctx,
     /* create confdb objects for the domains */
     for (i = 0; domains[i] != NULL; i++) {
         ret = mock_confdb_domain(test_ctx, test_ctx->confdb, tests_path,
-                                 domains[i], id_provider, params,
+                                 domains[i], id_provider, params != NULL ? params[i] : NULL,
                                  (cdb_path == NULL ? &cdb_path : NULL));
         if (ret != EOK) {
             DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize confdb domain "
@@ -302,7 +302,7 @@ create_dom_test_ctx(TALLOC_CTX *mem_ctx,
     const char *domains[] = {domain_name, NULL};
 
     return create_multidom_test_ctx(mem_ctx, tests_path, confdb_path, domains,
-                                    id_provider, params);
+                                    id_provider, &params);
 }
 
 void test_multidom_suite_cleanup(const char *tests_path,

From 7b972639b0ba9edf1423ec354ed09376217605c2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Petr=20=C4=8Cech?= <pc...@redhat.com>
Date: Tue, 10 Jan 2017 14:01:45 +0100
Subject: [PATCH 3/3] WIP: TESTS: Tests for sdap_search_initgr_user_in_batch

This patch provides tests for core logic of
sdap_search_initgr_user_in_batch() function. This function replaces
old approach with sysdb_try_to_find_expected_dn() function.

Resolves:
https://fedorahosted.org/sssd/ticket/3230
---
 Makefile.am                         |  22 ++
 src/tests/cmocka/test_sdap_initgr.c | 410 ++++++++++++++++++++++++++++++++++++
 2 files changed, 432 insertions(+)
 create mode 100644 src/tests/cmocka/test_sdap_initgr.c

diff --git a/Makefile.am b/Makefile.am
index 95be640..6916ae3 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -278,6 +278,7 @@ non_interactive_cmocka_based_tests += \
     ad_access_filter_tests \
     ad_gpo_tests \
     ad_common_tests \
+    test_sdap_initgr \
     test_ad_subdom \
     test_ipa_subdom_server \
     $(NULL)
@@ -2810,6 +2811,27 @@ test_fo_srv_LDADD = \
     libsss_test_common.la \
     $(NULL)
 
+test_sdap_initgr_SOURCES = \
+    src/tests/cmocka/common_mock_sdap.c \
+    src/tests/cmocka/common_mock_sysdb_objects.c \
+    src/tests/cmocka/test_sdap_initgr.c \
+    $(NULL)
+test_sdap_initgr_CFLAGS = \
+    $(AM_CFLAGS) \
+    $(NDR_NBT_CFLAGS) \
+    $(NULL)
+test_sdap_initgr_LDADD = \
+    $(CMOCKA_LIBS) \
+    $(POPT_LIBS) \
+    $(TALLOC_LIBS) \
+    $(SSSD_INTERNAL_LTLIBS) \
+    libsss_ldap_common.la \
+    libsss_ad_tests.la \
+    libsss_idmap.la \
+    libsss_test_common.la \
+    libdlopen_test_providers.la \
+    $(NULL)
+
 test_ad_subdom_SOURCES = \
     src/tests/cmocka/test_ad_subdomains.c \
     $(NULL)
diff --git a/src/tests/cmocka/test_sdap_initgr.c b/src/tests/cmocka/test_sdap_initgr.c
new file mode 100644
index 0000000..1f3318c
--- /dev/null
+++ b/src/tests/cmocka/test_sdap_initgr.c
@@ -0,0 +1,410 @@
+/*
+    Authors:
+        Petr Čech <pc...@redhat.com>
+
+    Copyright (C) 2017 Red Hat
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 3 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program.  If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <talloc.h>
+#include <tevent.h>
+#include <errno.h>
+#include <popt.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <sys/types.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <pwd.h>
+
+#include "tests/cmocka/common_mock.h"
+#include "tests/cmocka/common_mock_sysdb_objects.h"
+#include "tests/cmocka/common_mock_sdap.h"
+#include "providers/ad/ad_common.h"
+
+#include "providers/ad/ad_opts.c"
+#include "providers/ldap/sdap_async_initgroups.c"
+
+#define TESTS_PATH "tp_" BASE_FILE_STEM
+#define TEST_CONF_DB "test_sdap_initgr_conf.ldb"
+#define TEST_ID_PROVIDER "ldap"
+
+#define TEST_DOM1_NAME "domain.test.com"
+#define TEST_DOM2_NAME "subdom1.domain.test.com"
+#define TEST_DOM3_NAME "subdom2.domain.test.com"
+
+#define OBJECT_BASE_DN1 "dc=domain,dc=test,dc=com,cn=sysdb"
+#define OBJECT_BASE_DN2 "dc=subdom1,dc=domain,dc=test,dc=com,cn=sysdb"
+#define OBJECT_BASE_DN3 "dc=subdom2,dc=domain,dc=test,dc=com,cn=sysdb"
+
+#define TEST_USER_1 "test_user_1"
+#define TEST_USER_2 "test_user_2"
+#define TEST_USER_3 "test_user_3"
+
+const char *domains[] = { TEST_DOM1_NAME,
+                          TEST_DOM2_NAME,
+                          TEST_DOM3_NAME,
+                          NULL };
+
+const char *object_bases[] = { OBJECT_BASE_DN1,
+                               OBJECT_BASE_DN2,
+                               OBJECT_BASE_DN3,
+                               NULL };
+
+const char *test_users[] = { TEST_USER_1,
+                             TEST_USER_2,
+                             TEST_USER_3,
+                             NULL };
+
+static struct passwd **get_users(TALLOC_CTX *ctx)
+{
+    struct passwd **passwds = NULL;
+    char *homedir = NULL;
+    size_t user_count = 0;
+
+    for (int i = 0; test_users[i] != NULL; i++) {
+        user_count++;
+    }
+    passwds = talloc_array(ctx, struct passwd *, user_count);
+    assert_non_null(passwds);
+
+    for (int i = 0; i < user_count; i++) {
+        passwds[i] = talloc(passwds, struct passwd);
+        assert_non_null(passwds[i]);
+
+        homedir = talloc_strdup_append(homedir, "/home/");
+        homedir = talloc_strdup_append(homedir, test_users[i]);
+
+        passwds[i]->pw_name = discard_const(test_users[i]);
+        passwds[i]->pw_uid = 567 + i;
+        passwds[i]->pw_gid = 890 + i;
+        passwds[i]->pw_dir = talloc_strdup(passwds[i], homedir);
+        passwds[i]->pw_gecos = discard_const(test_users[i]);
+        passwds[i]->pw_shell = discard_const("/bin/sh");
+        passwds[i]->pw_passwd = discard_const("*");
+
+        talloc_zfree(homedir);
+    }
+
+    return passwds;
+}
+
+static struct sss_test_conf_param **get_params(TALLOC_CTX *ctx)
+{
+    struct sss_test_conf_param **params;
+    char *user_base_dn = NULL;
+    char *group_base_dn = NULL;
+    size_t base_count = 0;
+
+    for (int i = 0; object_bases[i] != NULL; i++) {
+        base_count++;
+    }
+
+    params = talloc_array(ctx, struct sss_test_conf_param *, base_count + 1);
+    assert_non_null(params);
+
+    for (int i = 0; i < base_count; i++) {
+        params[i] = talloc(params, struct sss_test_conf_param);
+        assert_non_null(params[i]);
+
+        user_base_dn = talloc_strdup_append(user_base_dn, "cn=users,");
+        user_base_dn = talloc_strdup_append(user_base_dn, object_bases[i]);
+
+        group_base_dn = talloc_strdup_append(group_base_dn, "cn=groups,");
+        group_base_dn = talloc_strdup_append(group_base_dn, object_bases[i]);
+
+        params[i] = talloc_array(params[i], struct sss_test_conf_param, 5);
+        params[i][0].key = "ldap_schema";
+        params[i][0].value = "rfc2307bis";
+        params[i][1].key = "ldap_search_base";
+        params[i][1].value = talloc_strdup(params[i], object_bases[i]);
+        params[i][2].key = "ldap_user_search_base";
+        params[i][2].value = talloc_strdup(params[i], user_base_dn);
+        params[i][3].key = "ldap_group_search_base";
+        params[i][3].value = talloc_strdup(params[i], group_base_dn);
+        params[i][4].key = NULL;
+        params[i][4].value = NULL;
+
+        talloc_zfree(user_base_dn);
+        talloc_zfree(group_base_dn);
+    }
+
+    return params;
+}
+
+/* Declarations from providers/ldap/sdap_async_initgroups.c */
+struct sdap_get_initgr_state;
+static int sdap_search_initgr_user_in_batch(struct sdap_get_initgr_state *state,
+                                            struct sysdb_attrs **users,
+                                            size_t count);
+
+struct test_sdap_initgr_ctx {
+    struct sss_test_ctx *tctx;
+};
+
+struct sss_domain_info *get_domain_info(struct sss_domain_info *domain,
+                                        const char *domain_name)
+{
+    struct sss_domain_info *dom = domain;
+
+    while(dom != NULL) {
+        if (strcmp(dom->name, domain_name) == 0) {
+            break;
+        }
+        dom = dom->next;
+    }
+    return dom;
+}
+
+
+struct sdap_get_initgr_state *prepare_state(struct test_sdap_initgr_ctx *ctx,
+                                            const char *domain_name)
+{
+    struct sdap_get_initgr_state *state;
+
+    state = talloc_zero(ctx->tctx, struct sdap_get_initgr_state);
+    assert_non_null(state);
+
+    state->dom = get_domain_info(ctx->tctx->dom, domain_name);
+    assert_non_null(state->dom);
+
+    state->opts = mock_sdap_options_ldap(state, state->dom,
+                                         ctx->tctx->confdb,
+                                         ctx->tctx->conf_dom_path);
+    assert_non_null(state->opts);
+
+    return state;
+}
+
+// TODO: Replace this duplication to common
+static errno_t store_user(TALLOC_CTX *ctx,
+                          struct sss_domain_info *dom,
+                          struct passwd *user,
+                          struct sysdb_attrs *attrs,
+                          time_t cache_update)
+{
+    errno_t ret;
+    char *fqname;
+
+    fqname = sss_create_internal_fqname(ctx,
+                                        user->pw_name,
+                                        dom->name);
+    if (fqname == NULL) {
+        return ENOMEM;
+    }
+
+    /* Prime the cache with a valid user */
+    ret = sysdb_store_user(dom,
+                           fqname,
+                           user->pw_passwd,
+                           user->pw_uid,
+                           user->pw_gid,
+                           user->pw_gecos,
+                           user->pw_dir,
+                           user->pw_shell,
+                           NULL, attrs,
+                           NULL, 300, cache_update);
+    talloc_free(fqname);
+    return ret;
+}
+
+static int test_sdap_initgr_setup(void **state)
+{
+    struct test_sdap_initgr_ctx *test_ctx;
+    struct sss_test_conf_param **params;
+
+    assert_true(leak_check_setup());
+
+    test_ctx = talloc_zero(global_talloc_context, struct test_sdap_initgr_ctx);
+    assert_non_null(test_ctx);
+
+    params = get_params(test_ctx);
+    assert_non_null(params);
+
+//    test_dom_suite_setup(TESTS_PATH);
+
+    test_ctx->tctx = create_multidom_test_ctx(test_ctx, TESTS_PATH,
+                                              TEST_CONF_DB, domains,
+                                              TEST_ID_PROVIDER, params);
+    assert_non_null(test_ctx->tctx);
+
+
+    check_leaks_push(test_ctx);
+    *state = test_ctx;
+    return 0;
+}
+
+static int test_sdap_initgr_teardown(void **state)
+{
+    struct test_sdap_initgr_ctx *test_ctx;
+
+    test_ctx = talloc_get_type(*state, struct test_sdap_initgr_ctx);
+    assert_non_null(test_ctx);
+
+//    test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains);
+
+    assert_true(check_leaks_pop(test_ctx) == true);
+    talloc_free(test_ctx);
+    assert_true(leak_check_teardown());
+    return 0;
+}
+
+static void test_user_is_on_batch(void **state)
+{
+    struct test_sdap_initgr_ctx *test_ctx;
+    struct sdap_get_initgr_state *initgr_state;
+    struct sss_domain_info *dom1_info = NULL;
+    struct sss_domain_info *dom2_info = NULL;
+    struct passwd **passwd_users;
+    struct sysdb_attrs **users;
+    const char *user_name;
+    errno_t ret;
+
+    test_ctx = talloc_get_type(*state, struct test_sdap_initgr_ctx);
+    assert_non_null(test_ctx);
+
+    dom1_info = get_domain_info(test_ctx->tctx->dom, domains[0]);
+    assert_non_null(dom1_info);
+    dom2_info = get_domain_info(test_ctx->tctx->dom, domains[1]);
+    assert_non_null(dom2_info);
+
+    initgr_state = prepare_state(test_ctx, domains[0]);
+    assert_non_null(initgr_state);
+
+    passwd_users = get_users(test_ctx);
+    assert_non_null(passwd_users);
+
+    users = talloc_array(test_ctx, struct sysdb_attrs *, 2);
+    users[0] = mock_sysdb_user(users, object_bases[0],
+                               passwd_users[0]->pw_uid,
+                               passwd_users[0]->pw_name);
+    users[1] = mock_sysdb_user(users, object_bases[1],
+                               passwd_users[1]->pw_uid,
+                               passwd_users[1]->pw_name);
+
+    ret = store_user(initgr_state, dom1_info, passwd_users[0], users[0], 0);
+    assert_int_equal(ret, 0);
+    ret = store_user(initgr_state, dom2_info, passwd_users[1], users[1], 0);
+    assert_int_equal(ret, 0);
+
+    ret = sdap_search_initgr_user_in_batch(initgr_state, users, 2);
+    assert_int_equal(ret, 0);
+
+    ret = sysdb_attrs_get_string(initgr_state->orig_user, "name", &user_name);
+    assert_int_equal(ret, 0);
+
+    assert_string_equal(user_name, test_users[0]);
+    printf(">>> result = [%s]\n", user_name);
+
+    talloc_zfree(initgr_state);
+    talloc_zfree(passwd_users);
+    talloc_zfree(users);
+}
+
+static void test_user_is_not_on_batch(void **state)
+{
+    struct test_sdap_initgr_ctx *test_ctx;
+    struct sdap_get_initgr_state *initgr_state;
+    struct sss_domain_info *dom_info = NULL;
+    struct passwd **passwd_users;
+    struct sysdb_attrs **users;
+    const char *user_name;
+    errno_t ret;
+
+    test_ctx = talloc_get_type(*state, struct test_sdap_initgr_ctx);
+    assert_non_null(test_ctx);
+
+    dom_info = get_domain_info(test_ctx->tctx->dom, domains[2]);
+    assert_non_null(dom_info);
+
+    initgr_state = prepare_state(test_ctx, domains[0]);
+    assert_non_null(initgr_state);
+
+    passwd_users = get_users(test_ctx);
+    assert_non_null(passwd_users);
+
+    users = talloc_array(test_ctx, struct sysdb_attrs *, 1);
+    users[0] = mock_sysdb_user(users, object_bases[2],
+                               passwd_users[2]->pw_uid,
+                               passwd_users[2]->pw_name);
+
+    ret = store_user(initgr_state, dom_info, passwd_users[2], users[0], 0);
+    assert_int_equal(ret, 0);
+
+    ret = sdap_search_initgr_user_in_batch(initgr_state, users, 1);
+    assert_int_equal(ret, 0);
+
+    ret = sysdb_attrs_get_string(initgr_state->orig_user, "name", &user_name);
+    assert_int_equal(ret, 0);
+
+//    assert_string_equal(user_name, test_users[0]);
+    printf(">>> result = [%s]\n", user_name);
+
+    talloc_zfree(initgr_state);
+    talloc_zfree(passwd_users);
+    talloc_zfree(users);
+}
+
+int main(int argc, const char *argv[])
+{
+    int rv;
+    poptContext pc;
+    int opt;
+    struct poptOption long_options[] = {
+        POPT_AUTOHELP
+        SSSD_DEBUG_OPTS
+        POPT_TABLEEND
+    };
+
+    const struct CMUnitTest tests[] = {
+        cmocka_unit_test_setup_teardown(test_user_is_on_batch,
+                                        test_sdap_initgr_setup,
+                                        test_sdap_initgr_teardown),
+        cmocka_unit_test_setup_teardown(test_user_is_not_on_batch,
+                                        test_sdap_initgr_setup,
+                                        test_sdap_initgr_teardown),
+    };
+
+    /* Set debug level to invalid value so we can deside if -d 0 was used. */
+    debug_level = SSSDBG_INVALID;
+
+    pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+    while((opt = poptGetNextOpt(pc)) != -1) {
+        switch(opt) {
+        default:
+            fprintf(stderr, "\nInvalid option %s: %s\n\n",
+                    poptBadOption(pc, 0), poptStrerror(opt));
+            poptPrintUsage(pc, stderr, 0);
+            return 1;
+        }
+    }
+    poptFreeContext(pc);
+
+    DEBUG_CLI_INIT(debug_level);
+
+    /* Even though normally the tests should clean up after themselves
+     * they might not after a failed run. Remove the old db to be sure */
+    tests_set_cwd();
+
+    test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains);
+    test_dom_suite_setup(TESTS_PATH);
+
+    rv = cmocka_run_group_tests(tests, NULL, NULL);
+    if (rv == 0) {
+        test_multidom_suite_cleanup(TESTS_PATH, TEST_CONF_DB, domains);
+    }
+
+    return rv;
+}
_______________________________________________
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