Blame SOURCES/0041-AD-replace-ad_get_client_site_parse_ndr-with-netlogo.patch

b2d430
From b0873f4a99f44eabae11e1cc62f6ec49c07466f0 Mon Sep 17 00:00:00 2001
b2d430
From: Sumit Bose <sbose@redhat.com>
b2d430
Date: Mon, 18 Jul 2016 11:25:47 +0200
b2d430
Subject: [PATCH 41/44] AD: replace ad_get_client_site_parse_ndr() with
b2d430
 netlogon_get_domain_info()
b2d430
b2d430
netlogon_get_domain_info() does not fail if only the site is missing in
b2d430
the CLDAP ping respond. If the site is not available a Global Catalog
b2d430
can still be looked up with the forest name. Only if the forest name is
b2d430
missing as well we fall back to the configured domain name.
b2d430
b2d430
Resolves:
b2d430
https://fedorahosted.org/sssd/ticket/3104
b2d430
b2d430
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
b2d430
---
b2d430
 src/providers/ad/ad_srv.c | 153 ++++++++++------------------------------------
b2d430
 1 file changed, 33 insertions(+), 120 deletions(-)
b2d430
b2d430
diff --git a/src/providers/ad/ad_srv.c b/src/providers/ad/ad_srv.c
b2d430
index 9602945e66aa0529938bdd63067f00971dbcbe89..ff01ee95c4d2c6875a989394489f1a0495cc3003 100644
b2d430
--- a/src/providers/ad/ad_srv.c
b2d430
+++ b/src/providers/ad/ad_srv.c
b2d430
@@ -405,93 +405,10 @@ done:
b2d430
     return;
b2d430
 }
b2d430
 
b2d430
-static errno_t ad_get_client_site_parse_ndr(TALLOC_CTX *mem_ctx,
b2d430
-                                            uint8_t *data,
b2d430
-                                            size_t length,
b2d430
-                                            char **_site_name,
b2d430
-                                            char **_forest_name)
b2d430
-{
b2d430
-    TALLOC_CTX *tmp_ctx = NULL;
b2d430
-    struct ndr_pull *ndr_pull = NULL;
b2d430
-    struct netlogon_samlogon_response response;
b2d430
-    enum ndr_err_code ndr_err;
b2d430
-    char *site = NULL;
b2d430
-    char *forest = NULL;
b2d430
-    DATA_BLOB blob;
b2d430
-    errno_t ret;
b2d430
-
b2d430
-    tmp_ctx = talloc_new(NULL);
b2d430
-    if (tmp_ctx == NULL) {
b2d430
-        DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
b2d430
-        return ENOMEM;
b2d430
-    }
b2d430
-
b2d430
-    blob.data = data;
b2d430
-    blob.length = length;
b2d430
-
b2d430
-    ndr_pull = ndr_pull_init_blob(&blob, mem_ctx);
b2d430
-    if (ndr_pull == NULL) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_init_blob() failed.\n");
b2d430
-        ret = ENOMEM;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    ndr_err = ndr_pull_netlogon_samlogon_response(ndr_pull, NDR_SCALARS,
b2d430
-                                                  &response);
b2d430
-    if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "ndr_pull_netlogon_samlogon_response() "
b2d430
-                                  "failed [%d]\n", ndr_err);
b2d430
-        ret = EBADMSG;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    if (!(response.ntver & NETLOGON_NT_VERSION_5EX)) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "This NT version does not provide site "
b2d430
-                                  "information [%x]\n", response.ntver);
b2d430
-        ret = EBADMSG;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    if (response.data.nt5_ex.client_site != NULL
b2d430
-        && response.data.nt5_ex.client_site[0] != '\0') {
b2d430
-        site = talloc_strdup(tmp_ctx, response.data.nt5_ex.client_site);
b2d430
-    } else if (response.data.nt5_ex.next_closest_site != NULL
b2d430
-               && response.data.nt5_ex.next_closest_site[0] != '\0') {
b2d430
-        site = talloc_strdup(tmp_ctx, response.data.nt5_ex.next_closest_site);
b2d430
-    } else {
b2d430
-        ret = ENOENT;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    if (response.data.nt5_ex.forest != NULL
b2d430
-            && response.data.nt5_ex.forest[0] != '\0') {
b2d430
-        forest = talloc_strdup(tmp_ctx, response.data.nt5_ex.forest);
b2d430
-    } else {
b2d430
-        ret = ENOENT;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-
b2d430
-    if (site == NULL || forest == NULL) {
b2d430
-        ret = ENOMEM;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    *_site_name = talloc_steal(mem_ctx, site);
b2d430
-    *_forest_name = talloc_steal(mem_ctx, forest);
b2d430
-
b2d430
-    ret = EOK;
b2d430
-
b2d430
-done:
b2d430
-    talloc_free(tmp_ctx);
b2d430
-    return ret;
b2d430
-}
b2d430
-
b2d430
 static void ad_get_client_site_done(struct tevent_req *subreq)
b2d430
 {
b2d430
     struct ad_get_client_site_state *state = NULL;
b2d430
     struct tevent_req *req = NULL;
b2d430
-    struct ldb_message_element *el = NULL;
b2d430
     struct sysdb_attrs **reply = NULL;
b2d430
     size_t reply_count;
b2d430
     errno_t ret;
b2d430
@@ -520,25 +437,8 @@ static void ad_get_client_site_done(struct tevent_req *subreq)
b2d430
         goto done;
b2d430
     }
b2d430
 
b2d430
-    ret = sysdb_attrs_get_el(reply[0], AD_AT_NETLOGON, &el);
b2d430
-    if (ret != EOK) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_el() failed\n");
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    if (el->num_values == 0) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "netlogon has no value\n");
b2d430
-        ret = ENOENT;
b2d430
-        goto done;
b2d430
-    } else if (el->num_values > 1) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "More than one netlogon value?\n");
b2d430
-        ret = EIO;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    ret = ad_get_client_site_parse_ndr(state, el->values[0].data,
b2d430
-                                       el->values[0].length, &state->site,
b2d430
-                                       &state->forest);
b2d430
+    ret = netlogon_get_domain_info(state, reply[0], true, NULL, &state->site,
b2d430
+                                   &state->forest);
b2d430
     if (ret != EOK) {
b2d430
         DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve site name [%d]: %s\n",
b2d430
                                   ret, strerror(ret));
b2d430
@@ -547,6 +447,7 @@ static void ad_get_client_site_done(struct tevent_req *subreq)
b2d430
     }
b2d430
 
b2d430
     DEBUG(SSSDBG_TRACE_FUNC, "Found site: %s\n", state->site);
b2d430
+    DEBUG(SSSDBG_TRACE_FUNC, "Found forest: %s\n", state->forest);
b2d430
 
b2d430
 done:
b2d430
     if (ret != EOK) {
b2d430
@@ -803,30 +704,42 @@ static void ad_srv_plugin_site_done(struct tevent_req *subreq)
b2d430
 
b2d430
         ret = EOK;
b2d430
     }
b2d430
+
b2d430
+    primary_domain = state->discovery_domain;
b2d430
+    backup_domain = NULL;
b2d430
+
b2d430
     if (ret == EOK) {
b2d430
         if (strcmp(state->service, "gc") == 0) {
b2d430
-            primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
b2d430
-                                             state->site, state->forest);
b2d430
-            if (primary_domain == NULL) {
b2d430
-                ret = ENOMEM;
b2d430
-                goto done;
b2d430
-            }
b2d430
+            if (state->forest != NULL) {
b2d430
+                if (state->site != NULL) {
b2d430
+                    primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
b2d430
+                                                     state->site,
b2d430
+                                                     state->forest);
b2d430
+                    if (primary_domain == NULL) {
b2d430
+                        ret = ENOMEM;
b2d430
+                        goto done;
b2d430
+                    }
b2d430
 
b2d430
-            backup_domain = state->forest;
b2d430
+                    backup_domain = state->forest;
b2d430
+                } else {
b2d430
+                    primary_domain = state->forest;
b2d430
+                    backup_domain = NULL;
b2d430
+                }
b2d430
+            }
b2d430
         } else {
b2d430
-            primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
b2d430
-                                             state->site, state->discovery_domain);
b2d430
-            if (primary_domain == NULL) {
b2d430
-                ret = ENOMEM;
b2d430
-                goto done;
b2d430
-            }
b2d430
+            if (state->site != NULL) {
b2d430
+                primary_domain = talloc_asprintf(state, AD_SITE_DOMAIN_FMT,
b2d430
+                                                 state->site,
b2d430
+                                                 state->discovery_domain);
b2d430
+                if (primary_domain == NULL) {
b2d430
+                    ret = ENOMEM;
b2d430
+                    goto done;
b2d430
+                }
b2d430
 
b2d430
-            backup_domain = state->discovery_domain;
b2d430
+                backup_domain = state->discovery_domain;
b2d430
+            }
b2d430
         }
b2d430
-    } else if (ret == ENOENT) {
b2d430
-        primary_domain = state->discovery_domain;
b2d430
-        backup_domain = NULL;
b2d430
-    } else {
b2d430
+    } else if (ret != ENOENT && ret != EOK) {
b2d430
         goto done;
b2d430
     }
b2d430
 
b2d430
-- 
b2d430
2.4.11
b2d430