Blame SOURCES/0018-ad-add-ad_check_domain_-send-recv.patch

8aada9
From 3ae3286d61ed796f0be7a1d72157af3687bc04a5 Mon Sep 17 00:00:00 2001
8aada9
From: Sumit Bose <sbose@redhat.com>
8aada9
Date: Thu, 7 May 2020 21:26:16 +0200
8aada9
Subject: [PATCH 18/19] ad: add ad_check_domain_{send|recv}
8aada9
MIME-Version: 1.0
8aada9
Content-Type: text/plain; charset=UTF-8
8aada9
Content-Transfer-Encoding: 8bit
8aada9
8aada9
This new request tries to get the basic domain information like domain
8aada9
SID and NetBIOS domain name for a domain given by the name. To achieve
8aada9
this the needed data is added to general domain structure and the SDAP
8aada9
domain structure. If the domain data cannot be looked up the data is
8aada9
removed again.
8aada9
8aada9
Resolves: https://github.com/SSSD/sssd/issues/5151
8aada9
8aada9
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
8aada9
---
8aada9
 src/providers/ad/ad_subdomains.c | 251 +++++++++++++++++++++++++++++++
8aada9
 1 file changed, 251 insertions(+)
8aada9
8aada9
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
8aada9
index 198f5c916..299aa7391 100644
8aada9
--- a/src/providers/ad/ad_subdomains.c
8aada9
+++ b/src/providers/ad/ad_subdomains.c
8aada9
@@ -2143,3 +2143,254 @@ errno_t ad_subdomains_init(TALLOC_CTX *mem_ctx,
8aada9
 
8aada9
     return EOK;
8aada9
 }
8aada9
+
8aada9
+struct ad_check_domain_state {
8aada9
+    struct tevent_context *ev;
8aada9
+    struct be_ctx *be_ctx;
8aada9
+    struct sdap_id_op *sdap_op;
8aada9
+    struct ad_id_ctx *dom_id_ctx;
8aada9
+    struct sdap_options *opts;
8aada9
+
8aada9
+    const char *dom_name;
8aada9
+    struct sss_domain_info *dom;
8aada9
+    struct sss_domain_info *parent;
8aada9
+    struct sdap_domain *sdom;
8aada9
+
8aada9
+    char *flat;
8aada9
+    char *site;
8aada9
+    char *forest;
8aada9
+    char *sid;
8aada9
+};
8aada9
+
8aada9
+static void ad_check_domain_connect_done(struct tevent_req *subreq);
8aada9
+static void ad_check_domain_done(struct tevent_req *subreq);
8aada9
+
8aada9
+static int ad_check_domain_destructor(void *mem)
8aada9
+{
8aada9
+    struct ad_check_domain_state *state = talloc_get_type(mem,
8aada9
+                                                  struct ad_check_domain_state);
8aada9
+
8aada9
+    if (state->sdom != NULL) {
8aada9
+        DEBUG(SSSDBG_TRACE_ALL, "Removing sdap domain [%s].\n",
8aada9
+                                state->dom->name);
8aada9
+        sdap_domain_remove(state->opts, state->dom);
8aada9
+        /* terminate all requests for this subdomain so we can free it */
8aada9
+        dp_terminate_domain_requests(state->be_ctx->provider, state->dom->name);
8aada9
+        talloc_zfree(state->sdom);
8aada9
+    }
8aada9
+
8aada9
+    if (state->dom != NULL) {
8aada9
+        DEBUG(SSSDBG_TRACE_ALL, "Removing domain [%s].\n", state->dom->name);
8aada9
+        sss_domain_set_state(state->dom, DOM_DISABLED);
8aada9
+        DLIST_REMOVE(state->be_ctx->domain->subdomains, state->dom);
8aada9
+        talloc_zfree(state->dom);
8aada9
+    }
8aada9
+
8aada9
+    return 0;
8aada9
+}
8aada9
+
8aada9
+struct tevent_req *
8aada9
+ad_check_domain_send(TALLOC_CTX *mem_ctx,
8aada9
+                     struct tevent_context *ev,
8aada9
+                     struct be_ctx *be_ctx,
8aada9
+                     struct ad_id_ctx *ad_id_ctx,
8aada9
+                     const char *dom_name,
8aada9
+                     const char *parent_dom_name)
8aada9
+{
8aada9
+    errno_t ret;
8aada9
+    struct tevent_req *req;
8aada9
+    struct tevent_req *subreq;
8aada9
+    struct ad_check_domain_state *state;
8aada9
+
8aada9
+    req = tevent_req_create(mem_ctx, &state, struct ad_check_domain_state);
8aada9
+    if (req == NULL) {
8aada9
+        DEBUG(SSSDBG_OP_FAILURE, "tevent_req_create failed.\n");
8aada9
+        return NULL;
8aada9
+    }
8aada9
+
8aada9
+    state->ev = ev;
8aada9
+    state->be_ctx = be_ctx;
8aada9
+    state->opts = ad_id_ctx->sdap_id_ctx->opts;
8aada9
+    state->dom_name = dom_name;
8aada9
+    state->parent = NULL;
8aada9
+    state->sdom = NULL;
8aada9
+
8aada9
+    state->dom = find_domain_by_name(be_ctx->domain, dom_name, true);
8aada9
+    if (state->dom == NULL) {
8aada9
+        state->parent = find_domain_by_name(be_ctx->domain, parent_dom_name,
8aada9
+                                            true);
8aada9
+        if (state->parent == NULL) {
8aada9
+            DEBUG(SSSDBG_OP_FAILURE,
8aada9
+                  "Failed to find domain object for domain [%s].\n",
8aada9
+                  parent_dom_name);
8aada9
+            ret = ENOENT;
8aada9
+            goto immediately;
8aada9
+        }
8aada9
+
8aada9
+        state->dom = new_subdomain(state->parent, state->parent, dom_name,
8aada9
+                                   dom_name, NULL, NULL, MPG_DISABLED, false,
8aada9
+                                   state->parent->forest,
8aada9
+                                   NULL, 0, be_ctx->cdb, true);
8aada9
+        if (state->dom == NULL) {
8aada9
+            DEBUG(SSSDBG_OP_FAILURE, "new_subdomain() failed.\n");
8aada9
+            ret = EINVAL;
8aada9
+            goto immediately;
8aada9
+        }
8aada9
+
8aada9
+        talloc_set_destructor((TALLOC_CTX *) state, ad_check_domain_destructor);
8aada9
+
8aada9
+        DLIST_ADD_END(state->parent->subdomains, state->dom,
8aada9
+                      struct sss_domain_info *);
8aada9
+
8aada9
+        ret = sdap_domain_add(state->opts, state->dom, &state->sdom);
8aada9
+        if (ret != EOK) {
8aada9
+            DEBUG(SSSDBG_OP_FAILURE, "sdap_domain_subdom_add failed.\n");
8aada9
+            goto immediately;
8aada9
+        }
8aada9
+
8aada9
+        ret = ad_set_search_bases(ad_id_ctx->ad_options->id, state->sdom);
8aada9
+        if (ret != EOK) {
8aada9
+            DEBUG(SSSDBG_MINOR_FAILURE, "failed to set ldap search bases for "
8aada9
+                  "domain '%s'. Will try to use automatically detected search "
8aada9
+                  "bases.", state->sdom->dom->name);
8aada9
+        }
8aada9
+
8aada9
+    }
8aada9
+
8aada9
+    state->dom_id_ctx = ads_get_dom_id_ctx(be_ctx, ad_id_ctx, state->dom,
8aada9
+                                           state->opts);
8aada9
+    if (state->dom_id_ctx == NULL) {
8aada9
+        DEBUG(SSSDBG_OP_FAILURE, "ads_get_dom_id_ctx() failed.\n");
8aada9
+        ret = EINVAL;
8aada9
+        goto immediately;
8aada9
+    }
8aada9
+
8aada9
+    state->sdap_op = sdap_id_op_create(state,
8aada9
+                             state->dom_id_ctx->sdap_id_ctx->conn->conn_cache);
8aada9
+    if (state->sdap_op == NULL) {
8aada9
+        DEBUG(SSSDBG_OP_FAILURE, "sdap_id_op_create() failed\n");
8aada9
+         ret = ENOMEM;
8aada9
+         goto immediately;
8aada9
+    }
8aada9
+
8aada9
+    subreq = sdap_id_op_connect_send(state->sdap_op, state, &ret;;
8aada9
+    if (subreq == NULL) {
8aada9
+        DEBUG(SSSDBG_CRIT_FAILURE, "sdap_id_op_connect_send() failed "
8aada9
+              "[%d]: %s\n", ret, sss_strerror(ret));
8aada9
+         goto immediately;
8aada9
+    }
8aada9
+
8aada9
+    tevent_req_set_callback(subreq, ad_check_domain_connect_done, req);
8aada9
+
8aada9
+    return req;
8aada9
+
8aada9
+immediately:
8aada9
+    if (ret == EOK) {
8aada9
+        tevent_req_done(req);
8aada9
+    } else {
8aada9
+        tevent_req_error(req, ret);
8aada9
+    }
8aada9
+    tevent_req_post(req, ev);
8aada9
+
8aada9
+    return req;
8aada9
+}
8aada9
+
8aada9
+static void ad_check_domain_connect_done(struct tevent_req *subreq)
8aada9
+{
8aada9
+    struct tevent_req *req;
8aada9
+    struct ad_check_domain_state *state;
8aada9
+    int ret;
8aada9
+    int dp_error;
8aada9
+
8aada9
+    req = tevent_req_callback_data(subreq, struct tevent_req);
8aada9
+    state = tevent_req_data(req, struct ad_check_domain_state);
8aada9
+
8aada9
+    ret = sdap_id_op_connect_recv(subreq, &dp_error);
8aada9
+    talloc_zfree(subreq);
8aada9
+
8aada9
+    if (ret != EOK) {
8aada9
+        DEBUG(SSSDBG_CRIT_FAILURE, "Unable to connect to LDAP "
8aada9
+              "[%d]: %s\n", ret, sss_strerror(ret));
8aada9
+        if (dp_error == DP_ERR_OFFLINE) {
8aada9
+            DEBUG(SSSDBG_MINOR_FAILURE, "No AD server is available, "
8aada9
+                  "cannot get the subdomain list while offline\n");
8aada9
+            ret = ERR_OFFLINE;
8aada9
+        }
8aada9
+        tevent_req_error(req, ret);
8aada9
+        return;
8aada9
+    }
8aada9
+
8aada9
+    subreq = ad_domain_info_send(state, state->ev,
8aada9
+                                 state->dom_id_ctx->sdap_id_ctx->conn,
8aada9
+                                 state->sdap_op, state->dom_name);
8aada9
+
8aada9
+    tevent_req_set_callback(subreq, ad_check_domain_done, req);
8aada9
+
8aada9
+    return;
8aada9
+}
8aada9
+
8aada9
+static void ad_check_domain_done(struct tevent_req *subreq)
8aada9
+{
8aada9
+    struct tevent_req *req;
8aada9
+    struct ad_check_domain_state *state;
8aada9
+    errno_t ret;
8aada9
+
8aada9
+
8aada9
+    req = tevent_req_callback_data(subreq, struct tevent_req);
8aada9
+    state = tevent_req_data(req, struct ad_check_domain_state);
8aada9
+
8aada9
+    ret = ad_domain_info_recv(subreq, state, &state->flat, &state->sid,
8aada9
+                              &state->site, &state->forest);
8aada9
+    talloc_zfree(subreq);
8aada9
+    if (ret != EOK) {
8aada9
+        DEBUG(SSSDBG_OP_FAILURE, "Unable to lookup domain information "
8aada9
+              "[%d]: %s\n", ret, sss_strerror(ret));
8aada9
+        goto done;
8aada9
+    }
8aada9
+    DEBUG(SSSDBG_TRACE_ALL, "%s %s %s %s.\n", state->flat, state->sid,
8aada9
+                                              state->site, state->forest);
8aada9
+
8aada9
+    /* New domain was successfully checked, remove destructor. */
8aada9
+    talloc_set_destructor(state, NULL);
8aada9
+
8aada9
+    ret = EOK;
8aada9
+
8aada9
+done:
8aada9
+    if (ret != EOK) {
8aada9
+        tevent_req_error(req, ret);
8aada9
+        return;
8aada9
+    }
8aada9
+
8aada9
+    tevent_req_done(req);
8aada9
+}
8aada9
+
8aada9
+errno_t ad_check_domain_recv(TALLOC_CTX *mem_ctx,
8aada9
+                             struct tevent_req *req,
8aada9
+                             char **_flat,
8aada9
+                             char **_id,
8aada9
+                             char **_site,
8aada9
+                             char **_forest)
8aada9
+{
8aada9
+    struct ad_check_domain_state *state = tevent_req_data(req,
8aada9
+                                                  struct ad_check_domain_state);
8aada9
+
8aada9
+    TEVENT_REQ_RETURN_ON_ERROR(req);
8aada9
+
8aada9
+    if (_flat) {
8aada9
+        *_flat = talloc_steal(mem_ctx, state->flat);
8aada9
+    }
8aada9
+
8aada9
+    if (_site) {
8aada9
+        *_site = talloc_steal(mem_ctx, state->site);
8aada9
+    }
8aada9
+
8aada9
+    if (_forest) {
8aada9
+        *_forest = talloc_steal(mem_ctx, state->forest);
8aada9
+    }
8aada9
+
8aada9
+    if (_id) {
8aada9
+        *_id = talloc_steal(mem_ctx, state->sid);
8aada9
+    }
8aada9
+
8aada9
+    return EOK;
8aada9
+}
8aada9
-- 
8aada9
2.21.3
8aada9