Blame SOURCES/0039-AD-netlogon_get_domain_info-allow-missing-arguments-.patch

b2d430
From df00f0d33874381fc36ee59eaf28a4918ae5dc56 Mon Sep 17 00:00:00 2001
b2d430
From: Sumit Bose <sbose@redhat.com>
b2d430
Date: Tue, 12 Jul 2016 13:29:33 +0200
b2d430
Subject: [PATCH 39/44] AD: netlogon_get_domain_info() allow missing arguments
b2d430
 and empty results
b2d430
b2d430
netlogon_get_domain_info() should not fail if not all parameters can be
b2d430
retrieved. It should be the responsibility of the caller to see if the
b2d430
needed data is available and act accordingly.
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_common.h      |   1 +
b2d430
 src/providers/ad/ad_domain_info.c | 108 +++++++++++++++++++++-----------------
b2d430
 src/providers/ad/ad_gpo.c         |   2 +-
b2d430
 src/providers/ad/ad_subdomains.c  |   3 +-
b2d430
 4 files changed, 64 insertions(+), 50 deletions(-)
b2d430
b2d430
diff --git a/src/providers/ad/ad_common.h b/src/providers/ad/ad_common.h
b2d430
index f4a90e4f0a3fe5910071d5fe690d0a356e2a0bd1..7e86faf1142d7be49eef01e1ddd7bfafea2fcedc 100644
b2d430
--- a/src/providers/ad/ad_common.h
b2d430
+++ b/src/providers/ad/ad_common.h
b2d430
@@ -187,6 +187,7 @@ errno_t ad_machine_account_password_renewal_init(struct be_ctx *be_ctx,
b2d430
 
b2d430
 errno_t netlogon_get_domain_info(TALLOC_CTX *mem_ctx,
b2d430
                                  struct sysdb_attrs *reply,
b2d430
+                                 bool check_next_nearest_site_as_well,
b2d430
                                  char **_flat_name,
b2d430
                                  char **_site,
b2d430
                                  char **_forest);
b2d430
diff --git a/src/providers/ad/ad_domain_info.c b/src/providers/ad/ad_domain_info.c
b2d430
index a06379c263878aa95741055636d0a12764f3ad8c..5302c8083bd832d0772829d9f3a4b8e9537d34b9 100644
b2d430
--- a/src/providers/ad/ad_domain_info.c
b2d430
+++ b/src/providers/ad/ad_domain_info.c
b2d430
@@ -37,6 +37,7 @@
b2d430
 
b2d430
 errno_t netlogon_get_domain_info(TALLOC_CTX *mem_ctx,
b2d430
                                  struct sysdb_attrs *reply,
b2d430
+                                 bool check_next_nearest_site_as_well,
b2d430
                                  char **_flat_name,
b2d430
                                  char **_site,
b2d430
                                  char **_forest)
b2d430
@@ -47,9 +48,6 @@ errno_t netlogon_get_domain_info(TALLOC_CTX *mem_ctx,
b2d430
     struct ndr_pull *ndr_pull = NULL;
b2d430
     enum ndr_err_code ndr_err;
b2d430
     struct netlogon_samlogon_response response;
b2d430
-    const char *flat_name;
b2d430
-    const char *site;
b2d430
-    const char *forest;
b2d430
     TALLOC_CTX *tmp_ctx;
b2d430
 
b2d430
     ret = sysdb_attrs_get_el(reply, AD_AT_NETLOGON, &el);
b2d430
@@ -102,57 +100,73 @@ errno_t netlogon_get_domain_info(TALLOC_CTX *mem_ctx,
b2d430
         goto done;
b2d430
     }
b2d430
 
b2d430
-    /* get flat name */
b2d430
-    if (response.data.nt5_ex.domain_name != NULL &&
b2d430
-        *response.data.nt5_ex.domain_name != '\0') {
b2d430
-        flat_name = response.data.nt5_ex.domain_name;
b2d430
-    } else {
b2d430
-        DEBUG(SSSDBG_MINOR_FAILURE,
b2d430
-              "No netlogon domain name data available\n");
b2d430
-        ret = ENOENT;
b2d430
-        goto done;
b2d430
+    /* get flat domain name */
b2d430
+    if (_flat_name != NULL) {
b2d430
+        if (response.data.nt5_ex.domain_name != NULL &&
b2d430
+            *response.data.nt5_ex.domain_name != '\0') {
b2d430
+            *_flat_name = talloc_strdup(mem_ctx,
b2d430
+                                        response.data.nt5_ex.domain_name);
b2d430
+            if (*_flat_name == NULL) {
b2d430
+                DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
b2d430
+                ret = ENOMEM;
b2d430
+                goto done;
b2d430
+            }
b2d430
+        } else {
b2d430
+            DEBUG(SSSDBG_MINOR_FAILURE,
b2d430
+                  "No netlogon flat domain name data available.\n");
b2d430
+            *_flat_name = NULL;
b2d430
+        }
b2d430
     }
b2d430
 
b2d430
-    *_flat_name = talloc_strdup(mem_ctx, flat_name);
b2d430
-    if (*_flat_name == NULL) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
b2d430
-        ret = ENOMEM;
b2d430
-        goto done;
b2d430
-    }
b2d430
 
b2d430
     /* get forest */
b2d430
-    if (response.data.nt5_ex.forest != NULL &&
b2d430
-        *response.data.nt5_ex.forest != '\0') {
b2d430
-        forest = response.data.nt5_ex.forest;
b2d430
-    } else {
b2d430
-        DEBUG(SSSDBG_MINOR_FAILURE, "No netlogon forest data available\n");
b2d430
-        ret = ENOENT;
b2d430
-        goto done;
b2d430
-    }
b2d430
-
b2d430
-    *_forest = talloc_strdup(mem_ctx, forest);
b2d430
-    if (*_forest == NULL) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
b2d430
-        ret = ENOMEM;
b2d430
-        goto done;
b2d430
+    if (_forest != NULL) {
b2d430
+        if (response.data.nt5_ex.forest != NULL &&
b2d430
+            *response.data.nt5_ex.forest != '\0') {
b2d430
+            *_forest = talloc_strdup(mem_ctx, response.data.nt5_ex.forest);
b2d430
+            if (*_forest == NULL) {
b2d430
+                DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
b2d430
+                ret = ENOMEM;
b2d430
+                goto done;
b2d430
+            }
b2d430
+        } else {
b2d430
+            DEBUG(SSSDBG_MINOR_FAILURE, "No netlogon forest data available.\n");
b2d430
+            *_forest = NULL;
b2d430
+        }
b2d430
     }
b2d430
 
b2d430
     /* get site name */
b2d430
-    if (response.data.nt5_ex.client_site != NULL
b2d430
-        && response.data.nt5_ex.client_site[0] != '\0') {
b2d430
-        site = response.data.nt5_ex.client_site;
b2d430
-    } else {
b2d430
-        DEBUG(SSSDBG_MINOR_FAILURE,
b2d430
-              "No netlogon site name data available\n");
b2d430
-        ret = ENOENT;
b2d430
-        goto done;
b2d430
-    }
b2d430
+    if (_site != NULL) {
b2d430
+        if (response.data.nt5_ex.client_site != NULL
b2d430
+            && response.data.nt5_ex.client_site[0] != '\0') {
b2d430
+            *_site = talloc_strdup(mem_ctx, response.data.nt5_ex.client_site);
b2d430
+            if (*_site == NULL) {
b2d430
+                DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
b2d430
+                ret = ENOMEM;
b2d430
+                goto done;
b2d430
+            }
b2d430
+        } else {
b2d430
+            DEBUG(SSSDBG_MINOR_FAILURE,
b2d430
+                  "No netlogon site name data available.\n");
b2d430
+            *_site = NULL;
b2d430
 
b2d430
-    *_site = talloc_strdup(mem_ctx, site);
b2d430
-    if (*_site == NULL) {
b2d430
-        DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
b2d430
-        ret = ENOMEM;
b2d430
-        goto done;
b2d430
+            if (check_next_nearest_site_as_well) {
b2d430
+                if (response.data.nt5_ex.next_closest_site != NULL
b2d430
+                        && response.data.nt5_ex.next_closest_site[0] != '\0') {
b2d430
+                    *_site = talloc_strdup(mem_ctx,
b2d430
+                                        response.data.nt5_ex.next_closest_site);
b2d430
+                    if (*_site == NULL) {
b2d430
+                        DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
b2d430
+                        ret = ENOMEM;
b2d430
+                        goto done;
b2d430
+                    }
b2d430
+                } else {
b2d430
+                    DEBUG(SSSDBG_MINOR_FAILURE,
b2d430
+                          "No netlogon next closest site name data "
b2d430
+                          "available.\n");
b2d430
+                }
b2d430
+            }
b2d430
+        }
b2d430
     }
b2d430
 
b2d430
     ret = EOK;
b2d430
@@ -388,7 +402,7 @@ ad_master_domain_netlogon_done(struct tevent_req *subreq)
b2d430
 
b2d430
     /* Exactly one flat name. Carry on */
b2d430
 
b2d430
-    ret = netlogon_get_domain_info(state, reply[0], &state->flat,
b2d430
+    ret = netlogon_get_domain_info(state, reply[0], false, &state->flat,
b2d430
                                    &state->site, &state->forest);
b2d430
     if (ret != EOK) {
b2d430
         DEBUG(SSSDBG_MINOR_FAILURE,
b2d430
diff --git a/src/providers/ad/ad_gpo.c b/src/providers/ad/ad_gpo.c
b2d430
index 3e54fd8b5932a97779e178c7d3c5b9f6d3b3277c..f609d28136918adfe6a8d5e95319b27ffcab79c0 100644
b2d430
--- a/src/providers/ad/ad_gpo.c
b2d430
+++ b/src/providers/ad/ad_gpo.c
b2d430
@@ -2801,7 +2801,7 @@ ad_gpo_site_name_retrieval_done(struct tevent_req *subreq)
b2d430
     ret = ad_master_domain_recv(subreq, state, NULL, NULL, &site, NULL);
b2d430
     talloc_zfree(subreq);
b2d430
 
b2d430
-    if (ret != EOK) {
b2d430
+    if (ret != EOK || site == NULL) {
b2d430
         DEBUG(SSSDBG_OP_FAILURE, "Cannot retrieve master domain info\n");
b2d430
         tevent_req_error(req, ENOENT);
b2d430
         return;
b2d430
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
b2d430
index 928c4fe93cc6afa5c3f69c14503896db820a4c0a..e9da04e384e598927f9c8c203a751bcccd29e895 100644
b2d430
--- a/src/providers/ad/ad_subdomains.c
b2d430
+++ b/src/providers/ad/ad_subdomains.c
b2d430
@@ -1108,14 +1108,13 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
b2d430
     char *master_sid;
b2d430
     char *flat_name;
b2d430
     char *forest;
b2d430
-    char *site;
b2d430
     errno_t ret;
b2d430
 
b2d430
     req = tevent_req_callback_data(subreq, struct tevent_req);
b2d430
     state = tevent_req_data(req, struct ad_subdomains_refresh_state);
b2d430
 
b2d430
     ret = ad_master_domain_recv(subreq, state, &flat_name, &master_sid,
b2d430
-                                &site, &forest);
b2d430
+                                NULL, &forest);
b2d430
     talloc_zfree(subreq);
b2d430
     if (ret != EOK) {
b2d430
         DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get master domain information "
b2d430
-- 
b2d430
2.4.11
b2d430