dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

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

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