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

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