Blame SOURCES/0150-SYSDB-Split-sysdb_try_to_find_expected_dn-into-small.patch

45d81b
From 57a070724f42bb01b8bb3f866e906f40643e0421 Mon Sep 17 00:00:00 2001
45d81b
From: Jakub Hrozek <jhrozek@redhat.com>
45d81b
Date: Fri, 28 Oct 2016 13:46:02 +0200
45d81b
Subject: [PATCH 150/151] SYSDB: Split sysdb_try_to_find_expected_dn() into
45d81b
 smaller functions
45d81b
45d81b
The function sysdb_try_to_find_expected_dn was performing several matching
45d81b
algorithms and thus it was getting big and hard to extend. This patch
45d81b
doesn't contain any functional changes, only shuffles the code around
45d81b
and splits the monolithic sysdb_try_to_find_expected_dn function into
45d81b
smaller blocks.
45d81b
45d81b
Reviewed-by: Sumit Bose <sbose@redhat.com>
45d81b
(cherry picked from commit e5a984093ad7921c83da75272cede2b0e52ba2d6)
45d81b
---
45d81b
 src/db/sysdb_subdomains.c | 278 +++++++++++++++++++++++++++++-----------------
45d81b
 1 file changed, 179 insertions(+), 99 deletions(-)
45d81b
45d81b
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
45d81b
index ff83f914f31d566e050c74a3ef5f5745f8c93add..b011bad6c988db952622e7ddaabf015ec24e54ba 100644
45d81b
--- a/src/db/sysdb_subdomains.c
45d81b
+++ b/src/db/sysdb_subdomains.c
45d81b
@@ -1145,74 +1145,29 @@ done:
45d81b
     return ret;
45d81b
 }
45d81b
 
45d81b
-errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
45d81b
-                                      const char *domain_component_name,
45d81b
-                                      struct sysdb_attrs **usr_attrs,
45d81b
-                                      size_t count,
45d81b
-                                      struct sysdb_attrs **exp_usr)
45d81b
+static errno_t match_cn_users(TALLOC_CTX *tmp_ctx,
45d81b
+                              struct sysdb_attrs **usr_attrs,
45d81b
+                              size_t count,
45d81b
+                              const char *dom_basedn,
45d81b
+                              struct sysdb_attrs **_result)
45d81b
 {
45d81b
-    char *dom_basedn;
45d81b
-    size_t dom_basedn_len;
45d81b
-    char *expected_basedn;
45d81b
-    size_t expected_basedn_len;
45d81b
+    errno_t ret;
45d81b
+    const char *orig_dn;
45d81b
     size_t dn_len;
45d81b
-    const char *orig_dn;
45d81b
-    size_t c = 0;
45d81b
-    int ret;
45d81b
-    TALLOC_CTX *tmp_ctx;
45d81b
-    struct ldb_context *ldb_ctx;
45d81b
-    struct ldb_dn *ldb_dom_basedn;
45d81b
-    int dom_basedn_comp_num;
45d81b
-    struct ldb_dn *ldb_dn;
45d81b
-    int dn_comp_num;
45d81b
-    const char *component_name;
45d81b
     struct sysdb_attrs *result = NULL;
45d81b
     const char *result_dn_str = NULL;
45d81b
+    char *cn_users_basedn;
45d81b
+    size_t cn_users_basedn_len;
45d81b
 
45d81b
-    if (dom == NULL || domain_component_name == NULL || usr_attrs == NULL
45d81b
-            || count == 0) {
45d81b
-        return EINVAL;
45d81b
-    }
45d81b
-
45d81b
-    tmp_ctx = talloc_new(NULL);
45d81b
-    if (tmp_ctx == NULL) {
45d81b
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
45d81b
-        return ENOMEM;
45d81b
-    }
45d81b
-
45d81b
-    ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
45d81b
-    if (ret != EOK) {
45d81b
-        DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
45d81b
-        goto done;
45d81b
-    }
45d81b
-    expected_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
45d81b
-    if (expected_basedn == NULL) {
45d81b
+    cn_users_basedn = talloc_asprintf(tmp_ctx, "%s%s", "cn=users,", dom_basedn);
45d81b
+    if (cn_users_basedn == NULL) {
45d81b
         ret = ENOMEM;
45d81b
         goto done;
45d81b
     }
45d81b
+    cn_users_basedn_len = strlen(cn_users_basedn);
45d81b
+    DEBUG(SSSDBG_TRACE_ALL, "cn=users baseDN is [%s].\n", cn_users_basedn);
45d81b
 
45d81b
-    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
45d81b
-    if (ldb_ctx == NULL) {
45d81b
-        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
45d81b
-        ret = EINVAL;
45d81b
-        goto done;
45d81b
-    }
45d81b
-
45d81b
-    ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
45d81b
-    if (ldb_dom_basedn == NULL) {
45d81b
-        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
45d81b
-        ret = ENOMEM;
45d81b
-        goto done;
45d81b
-    }
45d81b
-
45d81b
-    dom_basedn_comp_num = ldb_dn_get_comp_num(ldb_dom_basedn);
45d81b
-    dom_basedn_comp_num++;
45d81b
-
45d81b
-    DEBUG(SSSDBG_TRACE_ALL, "Expected BaseDN is [%s].\n", expected_basedn);
45d81b
-    expected_basedn_len = strlen(expected_basedn);
45d81b
-    dom_basedn_len = strlen(dom_basedn);
45d81b
-
45d81b
-    for (c = 0; c < count; c++) {
45d81b
+    for (size_t c = 0; c < count; c++) {
45d81b
         ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
45d81b
         if (ret != EOK) {
45d81b
             DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
45d81b
@@ -1220,9 +1175,9 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
45d81b
         }
45d81b
         dn_len = strlen(orig_dn);
45d81b
 
45d81b
-        if (dn_len > expected_basedn_len
45d81b
-                && strcasecmp(orig_dn + (dn_len - expected_basedn_len),
45d81b
-                              expected_basedn) == 0) {
45d81b
+        if (dn_len > cn_users_basedn_len
45d81b
+                && strcasecmp(orig_dn + (dn_len - cn_users_basedn_len),
45d81b
+                              cn_users_basedn) == 0) {
45d81b
             DEBUG(SSSDBG_TRACE_ALL,
45d81b
                   "Found matching dn [%s].\n", orig_dn);
45d81b
             if (result != NULL) {
45d81b
@@ -1237,52 +1192,177 @@ errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
45d81b
         }
45d81b
     }
45d81b
 
45d81b
-    if (result == NULL) {
45d81b
-        for (c = 0; c < count; c++) {
45d81b
-            ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
45d81b
-            if (ret != EOK) {
45d81b
-                DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
45d81b
+    ret = EOK;
45d81b
+done:
45d81b
+    *_result = result;
45d81b
+    return ret;
45d81b
+}
45d81b
+
45d81b
+static errno_t match_non_dc_comp(TALLOC_CTX *tmp_ctx,
45d81b
+                                 struct sss_domain_info *dom,
45d81b
+                                 struct sysdb_attrs **usr_attrs,
45d81b
+                                 size_t count,
45d81b
+                                 struct ldb_dn *ldb_basedn,
45d81b
+                                 const char *basedn,
45d81b
+                                 const char *domain_component_name,
45d81b
+                                 struct sysdb_attrs **_result)
45d81b
+{
45d81b
+    errno_t ret;
45d81b
+    const char *orig_dn;
45d81b
+    size_t orig_dn_len;
45d81b
+    size_t basedn_len;
45d81b
+    struct ldb_context *ldb_ctx;
45d81b
+    struct ldb_dn *ldb_orig_dn;
45d81b
+    int dn_comp_num;
45d81b
+    int basedn_comp_num;
45d81b
+    const char *component_name;
45d81b
+    struct sysdb_attrs *result = NULL;
45d81b
+    const char *result_dn_str = NULL;
45d81b
+
45d81b
+    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
45d81b
+    if (ldb_ctx == NULL) {
45d81b
+        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
45d81b
+        ret = EINVAL;
45d81b
+        goto done;
45d81b
+    }
45d81b
+
45d81b
+    basedn_len = strlen(basedn);
45d81b
+
45d81b
+    basedn_comp_num = ldb_dn_get_comp_num(ldb_basedn);
45d81b
+    basedn_comp_num++;
45d81b
+
45d81b
+    for (size_t c = 0; c < count; c++) {
45d81b
+        ret = sysdb_attrs_get_string(usr_attrs[c], SYSDB_ORIG_DN, &orig_dn);
45d81b
+        if (ret != EOK) {
45d81b
+            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
45d81b
+            goto done;
45d81b
+        }
45d81b
+        orig_dn_len = strlen(orig_dn);
45d81b
+
45d81b
+        if (orig_dn_len > basedn_len
45d81b
+                /* Does the user's original DN with the non-domain part
45d81b
+                 * stripped match the domain base DN?
45d81b
+                 */
45d81b
+                && strcasecmp(orig_dn + (orig_dn_len - basedn_len),
45d81b
+                              basedn) == 0) {
45d81b
+            ldb_orig_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
45d81b
+            if (ldb_orig_dn == NULL) {
45d81b
+                DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
45d81b
+                ret = ENOMEM;
45d81b
                 goto done;
45d81b
             }
45d81b
-            dn_len = strlen(orig_dn);
45d81b
 
45d81b
-            if (dn_len > dom_basedn_len
45d81b
-                    && strcasecmp(orig_dn + (dn_len - dom_basedn_len),
45d81b
-                                  dom_basedn) == 0) {
45d81b
-                ldb_dn = ldb_dn_new(tmp_ctx, ldb_ctx, orig_dn);
45d81b
-                if (ldb_dn == NULL) {
45d81b
-                    DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed");
45d81b
-                    ret = ENOMEM;
45d81b
-                    goto done;
45d81b
-                }
45d81b
-
45d81b
-                dn_comp_num = ldb_dn_get_comp_num(ldb_dn);
45d81b
-                if (dn_comp_num > dom_basedn_comp_num) {
45d81b
-                    component_name = ldb_dn_get_component_name(ldb_dn,
45d81b
-                                           (dn_comp_num - dom_basedn_comp_num));
45d81b
-                    DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
45d81b
-                                            component_name,
45d81b
-                                            domain_component_name);
45d81b
-                    if (component_name != NULL
45d81b
-                            && strcasecmp(component_name,
45d81b
-                                          domain_component_name) != 0) {
45d81b
-                        DEBUG(SSSDBG_TRACE_ALL,
45d81b
-                              "Found matching dn [%s].\n", orig_dn);
45d81b
-                        if (result != NULL) {
45d81b
-                            DEBUG(SSSDBG_OP_FAILURE,
45d81b
-                                 "Found 2 matching DN [%s] and [%s], "
45d81b
-                                 "expecting only 1.\n", result_dn_str, orig_dn);
45d81b
-                            ret = EINVAL;
45d81b
-                            goto done;
45d81b
-                        }
45d81b
-                        result = usr_attrs[c];
45d81b
-                        result_dn_str = orig_dn;
45d81b
+            dn_comp_num = ldb_dn_get_comp_num(ldb_orig_dn);
45d81b
+            if (dn_comp_num > basedn_comp_num) {
45d81b
+                component_name = ldb_dn_get_component_name(ldb_orig_dn,
45d81b
+                        (dn_comp_num - basedn_comp_num));
45d81b
+                DEBUG(SSSDBG_TRACE_ALL, "Comparing [%s] and [%s].\n",
45d81b
+                      component_name,
45d81b
+                      domain_component_name);
45d81b
+                /* If the component is NOT a DC component, then the entry
45d81b
+                 * must come from our domain, perhaps from a child container.
45d81b
+                 * If it matched the DC component, the entry was from a child
45d81b
+                 * subdomain different from this one.
45d81b
+                 */
45d81b
+                if (component_name != NULL
45d81b
+                        && strcasecmp(component_name,
45d81b
+                                      domain_component_name) != 0) {
45d81b
+                    DEBUG(SSSDBG_TRACE_ALL,
45d81b
+                            "Found matching dn [%s].\n", orig_dn);
45d81b
+                    if (result != NULL) {
45d81b
+                        DEBUG(SSSDBG_OP_FAILURE,
45d81b
+                                "Found 2 matching DN [%s] and [%s], "
45d81b
+                                "expecting only 1.\n", result_dn_str, orig_dn);
45d81b
+                        ret = EINVAL;
45d81b
+                        goto done;
45d81b
                     }
45d81b
+                    result = usr_attrs[c];
45d81b
+                    result_dn_str = orig_dn;
45d81b
                 }
45d81b
             }
45d81b
         }
45d81b
     }
45d81b
 
45d81b
+    ret = EOK;
45d81b
+    *_result = result;
45d81b
+done:
45d81b
+    return ret;
45d81b
+}
45d81b
+
45d81b
+static errno_t match_basedn(TALLOC_CTX *tmp_ctx,
45d81b
+                            struct sss_domain_info *dom,
45d81b
+                            struct sysdb_attrs **usr_attrs,
45d81b
+                            size_t count,
45d81b
+                            const char *dom_basedn,
45d81b
+                            const char *domain_component_name,
45d81b
+                            struct sysdb_attrs **_result)
45d81b
+{
45d81b
+    struct ldb_context *ldb_ctx;
45d81b
+    struct ldb_dn *ldb_dom_basedn;
45d81b
+
45d81b
+    ldb_ctx = sysdb_ctx_get_ldb(dom->sysdb);
45d81b
+    if (ldb_ctx == NULL) {
45d81b
+        DEBUG(SSSDBG_OP_FAILURE, "Missing ldb context.\n");
45d81b
+        return EINVAL;
45d81b
+    }
45d81b
+
45d81b
+
45d81b
+    ldb_dom_basedn = ldb_dn_new(tmp_ctx, ldb_ctx, dom_basedn);
45d81b
+    if (ldb_dom_basedn == NULL) {
45d81b
+        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new failed.\n");
45d81b
+        return ENOMEM;
45d81b
+    }
45d81b
+
45d81b
+    return match_non_dc_comp(tmp_ctx, dom,
45d81b
+                             usr_attrs, count,
45d81b
+                             ldb_dom_basedn, dom_basedn,
45d81b
+                             domain_component_name,
45d81b
+                             _result);
45d81b
+}
45d81b
+
45d81b
+errno_t sysdb_try_to_find_expected_dn(struct sss_domain_info *dom,
45d81b
+                                      const char *domain_component_name,
45d81b
+                                      struct sysdb_attrs **usr_attrs,
45d81b
+                                      size_t count,
45d81b
+                                      struct sysdb_attrs **exp_usr)
45d81b
+{
45d81b
+    char *dom_basedn;
45d81b
+    int ret;
45d81b
+    TALLOC_CTX *tmp_ctx;
45d81b
+    struct sysdb_attrs *result = NULL;
45d81b
+
45d81b
+    if (dom == NULL || domain_component_name == NULL
45d81b
+            || usr_attrs == NULL || count == 0) {
45d81b
+        return EINVAL;
45d81b
+    }
45d81b
+
45d81b
+    tmp_ctx = talloc_new(NULL);
45d81b
+    if (tmp_ctx == NULL) {
45d81b
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_new failed.\n");
45d81b
+        return ENOMEM;
45d81b
+    }
45d81b
+
45d81b
+    ret = domain_to_basedn(tmp_ctx, dom->name, &dom_basedn);
45d81b
+    if (ret != EOK) {
45d81b
+        DEBUG(SSSDBG_OP_FAILURE, "domain_to_basedn failed.\n");
45d81b
+        ret = EINVAL;
45d81b
+        goto done;
45d81b
+    }
45d81b
+
45d81b
+    ret = match_cn_users(tmp_ctx, usr_attrs, count, dom_basedn, &result);
45d81b
+    if (ret != EOK) {
45d81b
+        goto done;
45d81b
+    }
45d81b
+
45d81b
+    if (result == NULL) {
45d81b
+        ret = match_basedn(tmp_ctx, dom, usr_attrs,
45d81b
+                           count, dom_basedn, domain_component_name,
45d81b
+                           &result);
45d81b
+        if (ret != EOK) {
45d81b
+            goto done;
45d81b
+        }
45d81b
+    }
45d81b
+
45d81b
     if (result == NULL) {
45d81b
         DEBUG(SSSDBG_OP_FAILURE, "No matching DN found.\n");
45d81b
         ret = ENOENT;
45d81b
-- 
45d81b
2.7.4
45d81b