Blame SOURCES/0094-ipa-support-disabled-domains.patch

8d3578
From 698e27d8b465d1a507554532938058e053569b1b Mon Sep 17 00:00:00 2001
8d3578
From: Sumit Bose <sbose@redhat.com>
8d3578
Date: Wed, 7 Aug 2019 18:14:15 +0200
8d3578
Subject: [PATCH 94/97] ipa: support disabled domains
8d3578
MIME-Version: 1.0
8d3578
Content-Type: text/plain; charset=UTF-8
8d3578
Content-Transfer-Encoding: 8bit
8d3578
8d3578
IPA does not disable domains with the help of a flag in the domain
8d3578
objects but more general with the help of the SID blacklist. With this
8d3578
patch the blacklist is read with other data about trusted domains and if
8d3578
the domain SID of a trusted domain is found the domain is disabled. As a
8d3578
result uses and groups from this domain cannot be looked up anymore.
8d3578
8d3578
Related to https://pagure.io/SSSD/sssd/issue/4078
8d3578
8d3578
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
8d3578
---
8d3578
 src/providers/ipa/ipa_subdomains.c | 149 +++++++++++++++++++++++++++--
8d3578
 1 file changed, 139 insertions(+), 10 deletions(-)
8d3578
8d3578
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
8d3578
index 322420264..2ffc6bf7a 100644
8d3578
--- a/src/providers/ipa/ipa_subdomains.c
8d3578
+++ b/src/providers/ipa/ipa_subdomains.c
8d3578
@@ -43,6 +43,7 @@
8d3578
 #define IPA_TRUSTED_DOMAIN_SID "ipaNTTrustedDomainSID"
8d3578
 #define IPA_RANGE_TYPE "ipaRangeType"
8d3578
 #define IPA_ADDITIONAL_SUFFIXES "ipaNTAdditionalSuffixes"
8d3578
+#define IPA_SID_BLACKLIST_INCOMING "ipaNTSIDBlacklistIncoming"
8d3578
 
8d3578
 #define IPA_BASE_ID "ipaBaseID"
8d3578
 #define IPA_ID_RANGE_SIZE "ipaIDRangeSize"
8d3578
@@ -745,6 +746,129 @@ static void ipa_subdom_store_step(struct sss_domain_info *parent,
8d3578
     }
8d3578
 }
8d3578
 
8d3578
+static errno_t add_dom_sids_to_list(TALLOC_CTX *mem_ctx, const char **sids,
8d3578
+                                    char ***list)
8d3578
+{
8d3578
+    size_t c;
8d3578
+    errno_t ret;
8d3578
+
8d3578
+    for (c = 0; sids != NULL && sids[c] != NULL; c++) {
8d3578
+        if (is_domain_sid(sids[c])) {
8d3578
+            ret = add_string_to_list(mem_ctx, sids[c], list);
8d3578
+            if (ret != EOK) {
8d3578
+                DEBUG(SSSDBG_OP_FAILURE, "add_string_to_list failed.\n");
8d3578
+                return ret;
8d3578
+            }
8d3578
+        }
8d3578
+    }
8d3578
+
8d3578
+    return EOK;
8d3578
+}
8d3578
+
8d3578
+static errno_t ipa_get_disabled_domain_sids(TALLOC_CTX *mem_ctx, size_t count,
8d3578
+                                            struct sysdb_attrs **reply,
8d3578
+                                            char ***disabled_domain_sids)
8d3578
+{
8d3578
+    size_t c;
8d3578
+    char **dom_sid_list = NULL;
8d3578
+    const char **tmp_list;
8d3578
+    int ret;
8d3578
+
8d3578
+    for (c = 0; c < count; c++) {
8d3578
+        ret = sysdb_attrs_get_string_array(reply[c], IPA_SID_BLACKLIST_INCOMING,
8d3578
+                                           mem_ctx, &tmp_list);
8d3578
+        if (ret != EOK) {
8d3578
+            if (ret != ENOENT) {
8d3578
+                DEBUG(SSSDBG_OP_FAILURE,
8d3578
+                      "sysdb_attrs_get_string_array failed, list of disabled "
8d3578
+                      "domains might be incomplete.\n");
8d3578
+            }
8d3578
+            continue;
8d3578
+        }
8d3578
+
8d3578
+        ret = add_dom_sids_to_list(mem_ctx, tmp_list, &dom_sid_list);
8d3578
+        talloc_free(tmp_list);
8d3578
+        if (ret != EOK) {
8d3578
+            DEBUG(SSSDBG_OP_FAILURE, "add_dom_sids_to_list failed.\n");
8d3578
+            talloc_free(dom_sid_list);
8d3578
+            return ret;
8d3578
+        }
8d3578
+    }
8d3578
+
8d3578
+    *disabled_domain_sids = dom_sid_list;
8d3578
+
8d3578
+    return EOK;
8d3578
+}
8d3578
+
8d3578
+static errno_t ipa_subdomains_check_domain_state(struct sss_domain_info *dom,
8d3578
+                                                 char **disabled_domain_sids)
8d3578
+{
8d3578
+    int ret;
8d3578
+
8d3578
+    if (dom->domain_id == NULL) {
8d3578
+        return EINVAL;
8d3578
+    }
8d3578
+
8d3578
+    if (disabled_domain_sids != NULL
8d3578
+            && string_in_list(dom->domain_id, disabled_domain_sids, true)) {
8d3578
+        DEBUG(SSSDBG_TRACE_ALL, "Domain [%s] is disabled on the server.\n",
8d3578
+                                dom->name);
8d3578
+        /* disable domain if not already disabled */
8d3578
+        if (sss_domain_get_state(dom) != DOM_DISABLED) {
8d3578
+            sss_domain_set_state(dom, DOM_DISABLED);
8d3578
+            ret = sysdb_domain_set_enabled(dom->sysdb, dom->name, false);
8d3578
+            if (ret != EOK) {
8d3578
+                DEBUG(SSSDBG_OP_FAILURE, "sysdb_domain_set_enabled failed.\n");
8d3578
+                return ret;
8d3578
+            }
8d3578
+        }
8d3578
+    } else {
8d3578
+        /* enabled domain if it was disabled */
8d3578
+        DEBUG(SSSDBG_TRACE_ALL, "Domain [%s] is enabled on the server.\n",
8d3578
+                                dom->name);
8d3578
+        if (sss_domain_get_state(dom) == DOM_DISABLED) {
8d3578
+            sss_domain_set_state(dom, DOM_ACTIVE);
8d3578
+            ret = sysdb_domain_set_enabled(dom->sysdb, dom->name, true);
8d3578
+            if (ret != EOK) {
8d3578
+                DEBUG(SSSDBG_OP_FAILURE, "sysdb_domain_set_enabled failed.\n");
8d3578
+                return ret;
8d3578
+            }
8d3578
+        }
8d3578
+    }
8d3578
+
8d3578
+    return EOK;
8d3578
+}
8d3578
+
8d3578
+
8d3578
+static void ipa_subdomains_update_dom_state(struct sss_domain_info *parent,
8d3578
+                                               int count,
8d3578
+                                               struct sysdb_attrs **reply)
8d3578
+{
8d3578
+    int ret;
8d3578
+    struct sss_domain_info *dom;
8d3578
+    char **disabled_domain_sids = NULL;
8d3578
+
8d3578
+    ret = ipa_get_disabled_domain_sids(reply, count, reply,
8d3578
+                                       &disabled_domain_sids);
8d3578
+    if (ret != EOK) {
8d3578
+        DEBUG(SSSDBG_OP_FAILURE, "ipa_get_disabled_domain_sids failed, "
8d3578
+                                 "assuming no domain is disabled.\n");
8d3578
+        disabled_domain_sids = NULL;
8d3578
+    }
8d3578
+
8d3578
+    for (dom = get_next_domain(parent, SSS_GND_DESCEND|SSS_GND_INCLUDE_DISABLED);
8d3578
+         dom && IS_SUBDOMAIN(dom); /* if we get back to a parent, stop */
8d3578
+         dom = get_next_domain(dom, SSS_GND_INCLUDE_DISABLED)) {
8d3578
+
8d3578
+        /* check if domain should be disabled/enabled */
8d3578
+        ret = ipa_subdomains_check_domain_state(dom, disabled_domain_sids);
8d3578
+        if (ret != EOK) {
8d3578
+            DEBUG(SSSDBG_CRIT_FAILURE, "Failed to check domain state, "
8d3578
+                  "state of domain [%s] might be wrong.\n", dom->name);
8d3578
+        }
8d3578
+    }
8d3578
+}
8d3578
+
8d3578
 static errno_t ipa_subdomains_refresh(struct ipa_subdomains_ctx *ctx,
8d3578
                                       int count, struct sysdb_attrs **reply,
8d3578
                                       bool *changes)
8d3578
@@ -1376,7 +1500,7 @@ ipa_subdomains_slave_send(TALLOC_CTX *mem_ctx,
8d3578
     errno_t ret;
8d3578
     const char *attrs[] = { IPA_CN, IPA_FLATNAME, IPA_TRUSTED_DOMAIN_SID,
8d3578
                             IPA_TRUST_DIRECTION, IPA_ADDITIONAL_SUFFIXES,
8d3578
-                            NULL };
8d3578
+                            IPA_SID_BLACKLIST_INCOMING, NULL };
8d3578
 
8d3578
     req = tevent_req_create(mem_ctx, &state,
8d3578
                             struct ipa_subdomains_slave_state);
8d3578
@@ -1530,18 +1654,23 @@ static void ipa_subdomains_slave_search_done(struct tevent_req *subreq)
8d3578
                                  "expected.\n");
8d3578
     }
8d3578
 
8d3578
-    if (!has_changes) {
8d3578
-        ret = EOK;
8d3578
-        goto done;
8d3578
+    /* If there are no changes this step can be skipped, but
8d3578
+     * ipa_subdomains_update_dom_state() must be called after that in all case
8d3578
+     * to cover existing an newly added domains. Since the domain state is not
8d3578
+     * handled by a domain flag but by the blacklist has_changes does not
8d3578
+     * cover the state. */
8d3578
+    if (has_changes) {
8d3578
+        ret = ipa_subdom_reinit(state->sd_ctx);
8d3578
+        if (ret != EOK) {
8d3578
+            DEBUG(SSSDBG_OP_FAILURE, "Could not reinitialize subdomains\n");
8d3578
+            goto done;
8d3578
+        }
8d3578
     }
8d3578
 
8d3578
-    ret = ipa_subdom_reinit(state->sd_ctx);
8d3578
-    if (ret != EOK) {
8d3578
-        DEBUG(SSSDBG_OP_FAILURE, "Could not reinitialize subdomains\n");
8d3578
-        goto done;
8d3578
-    }
8d3578
+    ipa_subdomains_update_dom_state(state->sd_ctx->be_ctx->domain,
8d3578
+                                    reply_count, reply);
8d3578
 
8d3578
-    if (state->sd_ctx->ipa_id_ctx->server_mode == NULL) {
8d3578
+    if (!has_changes || state->sd_ctx->ipa_id_ctx->server_mode == NULL) {
8d3578
         ret = EOK;
8d3578
         goto done;
8d3578
     }
8d3578
-- 
8d3578
2.20.1
8d3578