|
|
9f2ebf |
From d56d41e76741f418e88e479b91193db3ee3f1688 Mon Sep 17 00:00:00 2001
|
|
|
9f2ebf |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
9f2ebf |
Date: Wed, 17 Jan 2018 21:59:24 +0100
|
|
|
9f2ebf |
Subject: [PATCH 101/101] AD: Use the right sdap_domain for the forest root
|
|
|
9f2ebf |
MIME-Version: 1.0
|
|
|
9f2ebf |
Content-Type: text/plain; charset=UTF-8
|
|
|
9f2ebf |
Content-Transfer-Encoding: 8bit
|
|
|
9f2ebf |
|
|
|
9f2ebf |
Each ad_id_ctx structure which represents a trusted AD domain contains a
|
|
|
9f2ebf |
list of sdap_domain structures representing all the other domains. This
|
|
|
9f2ebf |
is used to e.g. be able to reach another domain's ad_id_ctx and use its
|
|
|
9f2ebf |
LDAP connection.
|
|
|
9f2ebf |
|
|
|
9f2ebf |
However, the sdap search call that was searching for trusted domains in
|
|
|
9f2ebf |
the forest that the root domain knows about, was unconditionally using
|
|
|
9f2ebf |
the first sdap_domain structure in the list linked from the root_domain's
|
|
|
9f2ebf |
ad_id_ctx structure.
|
|
|
9f2ebf |
|
|
|
9f2ebf |
It should be noted that this search only happens in case the machine is
|
|
|
9f2ebf |
joined to one of the non-root domains in the forest and searches the root
|
|
|
9f2ebf |
domain explicitly.
|
|
|
9f2ebf |
|
|
|
9f2ebf |
In case sdap_domain structures linked from the ad_id_ctx representing
|
|
|
9f2ebf |
the root domain were ordered so that the first sdap_domain in the list
|
|
|
9f2ebf |
was representing a different domain than the one linked from the
|
|
|
9f2ebf |
ad_id_ctx, the sdap search would have used a wrong search base derived
|
|
|
9f2ebf |
from the unexpected sdap_domain which would result in a referral being
|
|
|
9f2ebf |
returned.
|
|
|
9f2ebf |
|
|
|
9f2ebf |
This patch explicitly looks up the sdap_domain structure that
|
|
|
9f2ebf |
corresponds to the root domain.
|
|
|
9f2ebf |
|
|
|
9f2ebf |
Resolves:
|
|
|
9f2ebf |
https://pagure.io/SSSD/sssd/issue/3594
|
|
|
9f2ebf |
|
|
|
9f2ebf |
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
|
9f2ebf |
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
|
|
9f2ebf |
(cherry picked from commit 9ac071272ce0152eb293d3181a5c12b395655521)
|
|
|
9f2ebf |
---
|
|
|
9f2ebf |
src/providers/ad/ad_subdomains.c | 110 +++++++++++++++++++++++++++------------
|
|
|
9f2ebf |
1 file changed, 77 insertions(+), 33 deletions(-)
|
|
|
9f2ebf |
|
|
|
9f2ebf |
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
|
|
|
9f2ebf |
index 1b9483a5dce937d6acdd813486a1e8c18210d35f..bd94ba8ea93679df8d01508b3d4d85217d9c1c87 100644
|
|
|
9f2ebf |
--- a/src/providers/ad/ad_subdomains.c
|
|
|
9f2ebf |
+++ b/src/providers/ad/ad_subdomains.c
|
|
|
9f2ebf |
@@ -57,6 +57,71 @@
|
|
|
9f2ebf |
/* do not refresh more often than every 5 seconds for now */
|
|
|
9f2ebf |
#define AD_SUBDOMAIN_REFRESH_LIMIT 5
|
|
|
9f2ebf |
|
|
|
9f2ebf |
+static struct sss_domain_info *
|
|
|
9f2ebf |
+ads_get_root_domain(struct be_ctx *be_ctx, struct sysdb_attrs *attrs)
|
|
|
9f2ebf |
+{
|
|
|
9f2ebf |
+ struct sss_domain_info *dom;
|
|
|
9f2ebf |
+ const char *name;
|
|
|
9f2ebf |
+ errno_t ret;
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+ if (attrs == NULL) {
|
|
|
9f2ebf |
+ /* Clients joined to the forest root directly don't even discover
|
|
|
9f2ebf |
+ * the root domain, so the attrs are expected to be NULL in this
|
|
|
9f2ebf |
+ * case
|
|
|
9f2ebf |
+ */
|
|
|
9f2ebf |
+ return be_ctx->domain;
|
|
|
9f2ebf |
+ }
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+ ret = sysdb_attrs_get_string(attrs, AD_AT_TRUST_PARTNER, &name);
|
|
|
9f2ebf |
+ if (ret != EOK) {
|
|
|
9f2ebf |
+ DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
|
|
|
9f2ebf |
+ return NULL;
|
|
|
9f2ebf |
+ }
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+ /* With a subsequent run, the root should already be known */
|
|
|
9f2ebf |
+ for (dom = be_ctx->domain; dom != NULL;
|
|
|
9f2ebf |
+ dom = get_next_domain(dom, SSS_GND_ALL_DOMAINS)) {
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+ if (strcasecmp(dom->name, name) == 0) {
|
|
|
9f2ebf |
+ /* The forest root is special, although it might be disabled for
|
|
|
9f2ebf |
+ * general lookups we still want to try to get the domains in the
|
|
|
9f2ebf |
+ * forest from a DC of the forest root */
|
|
|
9f2ebf |
+ if (sss_domain_get_state(dom) == DOM_DISABLED
|
|
|
9f2ebf |
+ && !sss_domain_is_forest_root(dom)) {
|
|
|
9f2ebf |
+ return NULL;
|
|
|
9f2ebf |
+ }
|
|
|
9f2ebf |
+ return dom;
|
|
|
9f2ebf |
+ }
|
|
|
9f2ebf |
+ }
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+ return NULL;
|
|
|
9f2ebf |
+}
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+static struct sdap_domain *
|
|
|
9f2ebf |
+ads_get_root_sdap_domain(struct be_ctx *be_ctx,
|
|
|
9f2ebf |
+ struct sdap_options *opts,
|
|
|
9f2ebf |
+ struct sysdb_attrs *attrs)
|
|
|
9f2ebf |
+{
|
|
|
9f2ebf |
+ struct sdap_domain *root_sdom;
|
|
|
9f2ebf |
+ struct sss_domain_info *root_dom;
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+ root_dom = ads_get_root_domain(be_ctx, attrs);
|
|
|
9f2ebf |
+ if (root_dom == NULL) {
|
|
|
9f2ebf |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
9f2ebf |
+ "ads_get_root_domain did not find the domain\n");
|
|
|
9f2ebf |
+ return NULL;
|
|
|
9f2ebf |
+ }
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+ root_sdom = sdap_domain_get(opts, root_dom);
|
|
|
9f2ebf |
+ if (root_sdom == NULL) {
|
|
|
9f2ebf |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
9f2ebf |
+ "Failed to find sdap_domain for the root domain\n");
|
|
|
9f2ebf |
+ return NULL;
|
|
|
9f2ebf |
+ }
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
+ return root_sdom;
|
|
|
9f2ebf |
+}
|
|
|
9f2ebf |
+
|
|
|
9f2ebf |
static errno_t ad_get_enabled_domains(TALLOC_CTX *mem_ctx,
|
|
|
9f2ebf |
struct ad_id_ctx *ad_id_ctx,
|
|
|
9f2ebf |
const char *ad_domain,
|
|
|
9f2ebf |
@@ -755,6 +820,7 @@ struct ad_get_slave_domain_state {
|
|
|
9f2ebf |
struct sdap_options *opts;
|
|
|
9f2ebf |
struct sdap_idmap_ctx *idmap_ctx;
|
|
|
9f2ebf |
struct sysdb_attrs *root_attrs;
|
|
|
9f2ebf |
+ struct sdap_domain *root_sdom;
|
|
|
9f2ebf |
struct sdap_id_op *sdap_op;
|
|
|
9f2ebf |
};
|
|
|
9f2ebf |
|
|
|
9f2ebf |
@@ -786,6 +852,13 @@ ad_get_slave_domain_send(TALLOC_CTX *mem_ctx,
|
|
|
9f2ebf |
state->opts = root_id_ctx->sdap_id_ctx->opts;
|
|
|
9f2ebf |
state->idmap_ctx = root_id_ctx->sdap_id_ctx->opts->idmap_ctx;
|
|
|
9f2ebf |
state->root_attrs = root_attrs;
|
|
|
9f2ebf |
+ state->root_sdom = ads_get_root_sdap_domain(state->be_ctx,
|
|
|
9f2ebf |
+ state->opts,
|
|
|
9f2ebf |
+ state->root_attrs);
|
|
|
9f2ebf |
+ if (state->root_sdom == NULL) {
|
|
|
9f2ebf |
+ ret = ERR_DOMAIN_NOT_FOUND;
|
|
|
9f2ebf |
+ goto immediately;
|
|
|
9f2ebf |
+ }
|
|
|
9f2ebf |
|
|
|
9f2ebf |
state->sdap_op = sdap_id_op_create(state, root_id_ctx->ldap_ctx->conn_cache);
|
|
|
9f2ebf |
if (state->sdap_op == NULL) {
|
|
|
9f2ebf |
@@ -861,7 +934,7 @@ static void ad_get_slave_domain_connect_done(struct tevent_req *subreq)
|
|
|
9f2ebf |
|
|
|
9f2ebf |
subreq = sdap_search_bases_send(state, state->ev, state->opts,
|
|
|
9f2ebf |
sdap_id_op_handle(state->sdap_op),
|
|
|
9f2ebf |
- state->opts->sdom->search_bases,
|
|
|
9f2ebf |
+ state->root_sdom->search_bases,
|
|
|
9f2ebf |
NULL, false, 0,
|
|
|
9f2ebf |
SLAVE_DOMAIN_FILTER, attrs);
|
|
|
9f2ebf |
if (subreq == NULL) {
|
|
|
9f2ebf |
@@ -965,38 +1038,6 @@ static errno_t ad_get_slave_domain_recv(struct tevent_req *req)
|
|
|
9f2ebf |
return EOK;
|
|
|
9f2ebf |
}
|
|
|
9f2ebf |
|
|
|
9f2ebf |
-static struct sss_domain_info *
|
|
|
9f2ebf |
-ads_get_root_domain(struct be_ctx *be_ctx, struct sysdb_attrs *attrs)
|
|
|
9f2ebf |
-{
|
|
|
9f2ebf |
- struct sss_domain_info *dom;
|
|
|
9f2ebf |
- const char *name;
|
|
|
9f2ebf |
- errno_t ret;
|
|
|
9f2ebf |
-
|
|
|
9f2ebf |
- ret = sysdb_attrs_get_string(attrs, AD_AT_TRUST_PARTNER, &name);
|
|
|
9f2ebf |
- if (ret != EOK) {
|
|
|
9f2ebf |
- DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
|
|
|
9f2ebf |
- return NULL;
|
|
|
9f2ebf |
- }
|
|
|
9f2ebf |
-
|
|
|
9f2ebf |
- /* With a subsequent run, the root should already be known */
|
|
|
9f2ebf |
- for (dom = be_ctx->domain; dom != NULL;
|
|
|
9f2ebf |
- dom = get_next_domain(dom, SSS_GND_ALL_DOMAINS)) {
|
|
|
9f2ebf |
-
|
|
|
9f2ebf |
- if (strcasecmp(dom->name, name) == 0) {
|
|
|
9f2ebf |
- /* The forest root is special, although it might be disabled for
|
|
|
9f2ebf |
- * general lookups we still want to try to get the domains in the
|
|
|
9f2ebf |
- * forest from a DC of the forest root */
|
|
|
9f2ebf |
- if (sss_domain_get_state(dom) == DOM_DISABLED
|
|
|
9f2ebf |
- && !sss_domain_is_forest_root(dom)) {
|
|
|
9f2ebf |
- return NULL;
|
|
|
9f2ebf |
- }
|
|
|
9f2ebf |
- return dom;
|
|
|
9f2ebf |
- }
|
|
|
9f2ebf |
- }
|
|
|
9f2ebf |
-
|
|
|
9f2ebf |
- return NULL;
|
|
|
9f2ebf |
-}
|
|
|
9f2ebf |
-
|
|
|
9f2ebf |
static struct ad_id_ctx *
|
|
|
9f2ebf |
ads_get_root_id_ctx(struct be_ctx *be_ctx,
|
|
|
9f2ebf |
struct ad_id_ctx *ad_id_ctx,
|
|
|
9f2ebf |
@@ -1416,6 +1457,9 @@ static void ad_subdomains_refresh_root_done(struct tevent_req *subreq)
|
|
|
9f2ebf |
req = tevent_req_callback_data(subreq, struct tevent_req);
|
|
|
9f2ebf |
state = tevent_req_data(req, struct ad_subdomains_refresh_state);
|
|
|
9f2ebf |
|
|
|
9f2ebf |
+ /* Note: For clients joined to the root domain, root_attrs is NULL,
|
|
|
9f2ebf |
+ * see ad_get_root_domain_send()
|
|
|
9f2ebf |
+ */
|
|
|
9f2ebf |
ret = ad_get_root_domain_recv(state, subreq, &root_attrs, &root_id_ctx);
|
|
|
9f2ebf |
talloc_zfree(subreq);
|
|
|
9f2ebf |
if (ret != EOK) {
|
|
|
9f2ebf |
--
|
|
|
9f2ebf |
2.14.3
|
|
|
9f2ebf |
|