Blame SOURCES/0119-AD-Make-ad_account_can_shortcut-reusable-by-SSSD-on-.patch

bb7cd1
From 54790675d0fd0627f7db8449ef97d59c0632006e Mon Sep 17 00:00:00 2001
bb7cd1
From: Jakub Hrozek <jhrozek@redhat.com>
bb7cd1
Date: Mon, 24 Apr 2017 10:13:44 +0200
bb7cd1
Subject: [PATCH 119/119] AD: Make ad_account_can_shortcut() reusable by SSSD
bb7cd1
 on an IPA server
bb7cd1
MIME-Version: 1.0
bb7cd1
Content-Type: text/plain; charset=UTF-8
bb7cd1
Content-Transfer-Encoding: 8bit
bb7cd1
bb7cd1
Resolves:
bb7cd1
    https://pagure.io/SSSD/sssd/issue/3318
bb7cd1
bb7cd1
The ad_account_can_shortcut() function is helpful to avoid unnecessary
bb7cd1
searches when SSSD is configured with an Active Directory domain that
bb7cd1
uses ID-mapping in the sense that if we find that an ID is outside our
bb7cd1
range, we can just abort the search in this domain and carry on.
bb7cd1
bb7cd1
This function was only used in the AD provider functions which are used
bb7cd1
when SSSD is enrolled direcly with an AD server. This patch moves the
bb7cd1
function to a codepath that is shared between directly enrolled SSSD and
bb7cd1
SSSD running on an IPA server.
bb7cd1
bb7cd1
Apart from moving the code, there are some minor changes to the function
bb7cd1
signature, namely the domain is passed as as struct (previously the
bb7cd1
domain name from the DP input was passed).
bb7cd1
bb7cd1
Reviewed-by: Michal Židek <mzidek@redhat.com>
bb7cd1
(cherry picked from commit dfe05f505dcfea16e7d66ca1a44206aa2570e861)
bb7cd1
---
bb7cd1
 src/providers/ad/ad_id.c | 162 ++++++++++++++++++++++++-----------------------
bb7cd1
 1 file changed, 84 insertions(+), 78 deletions(-)
bb7cd1
bb7cd1
diff --git a/src/providers/ad/ad_id.c b/src/providers/ad/ad_id.c
bb7cd1
index 8f26cb8744d2372c6180342c0d1bca025b16f52c..d1f6c444f5ddbcbbac6ff7f41fb6c8bf9ca976cb 100644
bb7cd1
--- a/src/providers/ad/ad_id.c
bb7cd1
+++ b/src/providers/ad/ad_id.c
bb7cd1
@@ -50,6 +50,77 @@ disable_gc(struct ad_options *ad_options)
bb7cd1
     }
bb7cd1
 }
bb7cd1
 
bb7cd1
+static bool ad_account_can_shortcut(struct sdap_idmap_ctx *idmap_ctx,
bb7cd1
+                                    struct sss_domain_info *domain,
bb7cd1
+                                    int filter_type,
bb7cd1
+                                    const char *filter_value)
bb7cd1
+{
bb7cd1
+    struct sss_domain_info *dom_head = NULL;
bb7cd1
+    struct sss_domain_info *sid_dom = NULL;
bb7cd1
+    enum idmap_error_code err;
bb7cd1
+    char *sid = NULL;
bb7cd1
+    const char *csid = NULL;
bb7cd1
+    uint32_t id;
bb7cd1
+    bool shortcut = false;
bb7cd1
+    errno_t ret;
bb7cd1
+
bb7cd1
+    if (!sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx, domain->name,
bb7cd1
+                                                   domain->domain_id)) {
bb7cd1
+        goto done;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    switch (filter_type) {
bb7cd1
+    case BE_FILTER_IDNUM:
bb7cd1
+        /* convert value to ID */
bb7cd1
+        errno = 0;
bb7cd1
+        id = strtouint32(filter_value, NULL, 10);
bb7cd1
+        if (errno != 0) {
bb7cd1
+            ret = errno;
bb7cd1
+            DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert filter value to "
bb7cd1
+                  "number [%d]: %s\n", ret, strerror(ret));
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+
bb7cd1
+        /* convert the ID to its SID equivalent */
bb7cd1
+        err = sss_idmap_unix_to_sid(idmap_ctx->map, id, &sid;;
bb7cd1
+        if (err != IDMAP_SUCCESS) {
bb7cd1
+            DEBUG(SSSDBG_MINOR_FAILURE, "Mapping ID [%s] to SID failed: "
bb7cd1
+                  "[%s]\n", filter_value, idmap_error_string(err));
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+        /* fall through */
bb7cd1
+        SSS_ATTRIBUTE_FALLTHROUGH;
bb7cd1
+    case BE_FILTER_SECID:
bb7cd1
+        csid = sid == NULL ? filter_value : sid;
bb7cd1
+
bb7cd1
+        dom_head = get_domains_head(domain);
bb7cd1
+        if (dom_head == NULL) {
bb7cd1
+            DEBUG(SSSDBG_CRIT_FAILURE, "Cannot find domain head\n");
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+
bb7cd1
+        sid_dom = find_domain_by_sid(dom_head, csid);
bb7cd1
+        if (sid_dom == NULL) {
bb7cd1
+            DEBUG(SSSDBG_OP_FAILURE, "Invalid domain for SID:%s\n", csid);
bb7cd1
+            goto done;
bb7cd1
+        }
bb7cd1
+
bb7cd1
+        if (strcasecmp(sid_dom->name, domain->name) != 0) {
bb7cd1
+            shortcut = true;
bb7cd1
+        }
bb7cd1
+        break;
bb7cd1
+    default:
bb7cd1
+        break;
bb7cd1
+    }
bb7cd1
+
bb7cd1
+done:
bb7cd1
+    if (sid != NULL) {
bb7cd1
+        sss_idmap_free_sid(idmap_ctx->map, sid);
bb7cd1
+    }
bb7cd1
+
bb7cd1
+    return shortcut;
bb7cd1
+}
bb7cd1
+
bb7cd1
 struct ad_handle_acct_info_state {
bb7cd1
     struct dp_id_data *ar;
bb7cd1
     struct sdap_id_ctx *ctx;
bb7cd1
@@ -78,6 +149,7 @@ ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
bb7cd1
     struct ad_handle_acct_info_state *state;
bb7cd1
     struct be_ctx *be_ctx = ctx->be;
bb7cd1
     errno_t ret;
bb7cd1
+    bool shortcut;
bb7cd1
 
bb7cd1
     req = tevent_req_create(mem_ctx, &state, struct ad_handle_acct_info_state);
bb7cd1
     if (req == NULL) {
bb7cd1
@@ -90,6 +162,18 @@ ad_handle_acct_info_send(TALLOC_CTX *mem_ctx,
bb7cd1
     state->ad_options = ad_options;
bb7cd1
     state->cindex = 0;
bb7cd1
 
bb7cd1
+    /* Try to shortcut if this is ID or SID search and it belongs to
bb7cd1
+     * other domain range than is in ar->domain. */
bb7cd1
+    shortcut = ad_account_can_shortcut(ctx->opts->idmap_ctx,
bb7cd1
+                                       sdom->dom,
bb7cd1
+                                       ar->filter_type,
bb7cd1
+                                       ar->filter_value);
bb7cd1
+    if (shortcut) {
bb7cd1
+        DEBUG(SSSDBG_TRACE_FUNC, "This ID is from different domain\n");
bb7cd1
+        ret = EOK;
bb7cd1
+        goto immediate;
bb7cd1
+    }
bb7cd1
+
bb7cd1
     if (sss_domain_get_state(sdom->dom) == DOM_INACTIVE) {
bb7cd1
         ret = ERR_SUBDOM_INACTIVE;
bb7cd1
         goto immediate;
bb7cd1
@@ -297,72 +381,6 @@ get_conn_list(TALLOC_CTX *mem_ctx, struct ad_id_ctx *ad_ctx,
bb7cd1
     return clist;
bb7cd1
 }
bb7cd1
 
bb7cd1
-static bool ad_account_can_shortcut(struct be_ctx *be_ctx,
bb7cd1
-                                    struct sdap_idmap_ctx *idmap_ctx,
bb7cd1
-                                    int filter_type,
bb7cd1
-                                    const char *filter_value,
bb7cd1
-                                    const char *filter_domain)
bb7cd1
-{
bb7cd1
-    struct sss_domain_info *domain = be_ctx->domain;
bb7cd1
-    struct sss_domain_info *req_dom = NULL;
bb7cd1
-    enum idmap_error_code err;
bb7cd1
-    char *sid = NULL;
bb7cd1
-    const char *csid = NULL;
bb7cd1
-    uint32_t id;
bb7cd1
-    bool shortcut = false;
bb7cd1
-    errno_t ret;
bb7cd1
-
bb7cd1
-    if (!sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx, domain->name,
bb7cd1
-                                                   domain->domain_id)) {
bb7cd1
-        goto done;
bb7cd1
-    }
bb7cd1
-
bb7cd1
-    switch (filter_type) {
bb7cd1
-    case BE_FILTER_IDNUM:
bb7cd1
-        /* convert value to ID */
bb7cd1
-        errno = 0;
bb7cd1
-        id = strtouint32(filter_value, NULL, 10);
bb7cd1
-        if (errno != 0) {
bb7cd1
-            ret = errno;
bb7cd1
-            DEBUG(SSSDBG_MINOR_FAILURE, "Unable to convert filter value to "
bb7cd1
-                  "number [%d]: %s\n", ret, strerror(ret));
bb7cd1
-            goto done;
bb7cd1
-        }
bb7cd1
-
bb7cd1
-        /* convert the ID to its SID equivalent */
bb7cd1
-        err = sss_idmap_unix_to_sid(idmap_ctx->map, id, &sid;;
bb7cd1
-        if (err != IDMAP_SUCCESS) {
bb7cd1
-            DEBUG(SSSDBG_MINOR_FAILURE, "Mapping ID [%s] to SID failed: "
bb7cd1
-                  "[%s]\n", filter_value, idmap_error_string(err));
bb7cd1
-            goto done;
bb7cd1
-        }
bb7cd1
-        /* fall through */
bb7cd1
-        SSS_ATTRIBUTE_FALLTHROUGH;
bb7cd1
-    case BE_FILTER_SECID:
bb7cd1
-        csid = sid == NULL ? filter_value : sid;
bb7cd1
-
bb7cd1
-        req_dom = find_domain_by_sid(domain, csid);
bb7cd1
-        if (req_dom == NULL) {
bb7cd1
-            DEBUG(SSSDBG_OP_FAILURE, "Invalid domain for SID:%s\n", csid);
bb7cd1
-            goto done;
bb7cd1
-        }
bb7cd1
-
bb7cd1
-        if (strcasecmp(req_dom->name, filter_domain) != 0) {
bb7cd1
-            shortcut = true;
bb7cd1
-        }
bb7cd1
-        break;
bb7cd1
-    default:
bb7cd1
-        break;
bb7cd1
-    }
bb7cd1
-
bb7cd1
-done:
bb7cd1
-    if (sid != NULL) {
bb7cd1
-        sss_idmap_free_sid(idmap_ctx->map, sid);
bb7cd1
-    }
bb7cd1
-
bb7cd1
-    return shortcut;
bb7cd1
-}
bb7cd1
-
bb7cd1
 struct ad_account_info_handler_state {
bb7cd1
     struct sss_domain_info *domain;
bb7cd1
     struct dp_reply_std reply;
bb7cd1
@@ -384,7 +402,6 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
bb7cd1
     struct tevent_req *subreq;
bb7cd1
     struct tevent_req *req;
bb7cd1
     struct be_ctx *be_ctx;
bb7cd1
-    bool shortcut;
bb7cd1
     errno_t ret;
bb7cd1
 
bb7cd1
     sdap_id_ctx = id_ctx->sdap_id_ctx;
bb7cd1
@@ -403,17 +420,6 @@ ad_account_info_handler_send(TALLOC_CTX *mem_ctx,
bb7cd1
         goto immediately;
bb7cd1
     }
bb7cd1
 
bb7cd1
-    /* Try to shortcut if this is ID or SID search and it belongs to
bb7cd1
-     * other domain range than is in ar->domain. */
bb7cd1
-    shortcut = ad_account_can_shortcut(be_ctx, sdap_id_ctx->opts->idmap_ctx,
bb7cd1
-                                       data->filter_type, data->filter_value,
bb7cd1
-                                       data->domain);
bb7cd1
-    if (shortcut) {
bb7cd1
-        DEBUG(SSSDBG_TRACE_FUNC, "This ID is from different domain\n");
bb7cd1
-        ret = EOK;
bb7cd1
-        goto immediately;
bb7cd1
-    }
bb7cd1
-
bb7cd1
     domain = be_ctx->domain;
bb7cd1
     if (strcasecmp(data->domain, be_ctx->domain->name) != 0) {
bb7cd1
         /* Subdomain request, verify subdomain. */
bb7cd1
-- 
bb7cd1
2.9.3
bb7cd1