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