Blame SOURCES/0004-AD-Allow-configuring-auto_private_groups-per-subdoma.patch

5cd47f
From 6f6b3b1f4fcec79a1640a97fb3cd875f2cd8b83a Mon Sep 17 00:00:00 2001
5cd47f
From: Jakub Hrozek <jhrozek@redhat.com>
5cd47f
Date: Tue, 19 Mar 2019 11:01:10 +0100
5cd47f
Subject: [PATCH] AD: Allow configuring auto_private_groups per subdomain or
5cd47f
 with subdomain_inherit
5cd47f
MIME-Version: 1.0
5cd47f
Content-Type: text/plain; charset=UTF-8
5cd47f
Content-Transfer-Encoding: 8bit
5cd47f
5cd47f
Resolves:
5cd47f
https://pagure.io/SSSD/sssd/issue/3965
5cd47f
5cd47f
Previously, subdomains that used ID mapping always only used MPGs and
5cd47f
POSIX subdomains always inherited the parent domain settings. This patch
5cd47f
is a small RFE which allows to either set the auto_private_groups option
5cd47f
directly per subdomain or set it for all subdomains using the
5cd47f
subdomain_inherit option
5cd47f
5cd47f
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
5cd47f
(cherry picked from commit 41c497b8b9e6efb9f2aa8e4cc869d465c3b954b3)
5cd47f
---
5cd47f
 src/man/sssd.conf.5.xml               |  38 +++++----
5cd47f
 src/providers/ad/ad_subdomains.c      | 107 ++++++++++++++++++++++----
5cd47f
 src/providers/ldap/sdap_async_users.c |   2 +-
5cd47f
 src/util/domain_info_utils.c          |  14 +++-
5cd47f
 src/util/util.h                       |   3 +
5cd47f
 5 files changed, 130 insertions(+), 34 deletions(-)
5cd47f
5cd47f
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
5cd47f
index 41ba7b924..3d017f638 100644
5cd47f
--- a/src/man/sssd.conf.5.xml
5cd47f
+++ b/src/man/sssd.conf.5.xml
5cd47f
@@ -2995,6 +2995,13 @@ subdomain_inherit = ldap_purge_cache_timeout
5cd47f
                                             Create user's private group unconditionally from user's UID number.
5cd47f
                                             The GID number is ignored in this case.
5cd47f
                                         </para>
5cd47f
+                                        <para>
5cd47f
+                                            NOTE: Because the GID number and the user private group
5cd47f
+                                            are inferred from the UID number, it is not supported
5cd47f
+                                            to have multiple entries with the same UID or GID number
5cd47f
+                                            with this option. In other words, enabling this option
5cd47f
+                                            enforces uniqueness across the ID space.
5cd47f
+                                        </para>
5cd47f
                                     </listitem>
5cd47f
                                 </varlistentry>
5cd47f
                                 <varlistentry>
5cd47f
@@ -3041,24 +3048,25 @@ subdomain_inherit = ldap_purge_cache_timeout
5cd47f
                                 </varlistentry>
5cd47f
                             </variablelist>
5cd47f
                         </para>
5cd47f
-			<para>
5cd47f
-			    For POSIX subdomains, setting the option in the main
5cd47f
-			    domain is inherited in the subdomain.
5cd47f
-			</para>
5cd47f
-			<para>
5cd47f
-			    For ID-mapping subdomains, auto_private_groups is
5cd47f
-			    already enabled for the subdomains and setting it to
5cd47f
-			    false will not have any effect for the subdomain.
5cd47f
-			</para>
5cd47f
                         <para>
5cd47f
-                            NOTE: Because the GID number and the user private group
5cd47f
-                            are inferred from the UID number, it is not supported
5cd47f
-                            to have multiple entries with the same UID or GID number
5cd47f
-                            with this option. In other words, enabling this option
5cd47f
-                            enforces uniqueness across the ID space.
5cd47f
+                            For subdomains, the default value is False for
5cd47f
+                            subdomains that use assigned POSIX IDs and True
5cd47f
+                            for subdomains that use automatic ID-mapping.
5cd47f
                         </para>
5cd47f
                         <para>
5cd47f
-                            Default: False
5cd47f
+                            The value of auto_private_groups can either be set per subdomains
5cd47f
+                            in a subsection, for example:
5cd47f
+<programlisting>
5cd47f
+[domain/forest.domain/sub.domain]
5cd47f
+auto_private_groups = false
5cd47f
+</programlisting>
5cd47f
+                            or globally for all subdomains in the main domain section
5cd47f
+                            using the subdomain_inherit option:
5cd47f
+<programlisting>
5cd47f
+[domain/forest.domain]
5cd47f
+subdomain_inherit = auto_private_groups
5cd47f
+auto_private_groups = false
5cd47f
+</programlisting>
5cd47f
                         </para>
5cd47f
                     </listitem>
5cd47f
                 </varlistentry>
5cd47f
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
5cd47f
index 5b046773c..4fc4be094 100644
5cd47f
--- a/src/providers/ad/ad_subdomains.c
5cd47f
+++ b/src/providers/ad/ad_subdomains.c
5cd47f
@@ -436,8 +436,87 @@ static errno_t ad_subdom_enumerates(struct sss_domain_info *parent,
5cd47f
     return EOK;
5cd47f
 }
5cd47f
 
5cd47f
+static enum sss_domain_mpg_mode
5cd47f
+get_default_subdom_mpg_mode(struct sdap_idmap_ctx *idmap_ctx,
5cd47f
+                            struct sss_domain_info *parent,
5cd47f
+                            const char *subdom_name,
5cd47f
+                            char *subdom_sid_str)
5cd47f
+{
5cd47f
+    bool use_id_mapping;
5cd47f
+    bool inherit_option;
5cd47f
+    enum sss_domain_mpg_mode default_mpg_mode;
5cd47f
+
5cd47f
+    inherit_option = string_in_list(CONFDB_DOMAIN_AUTO_UPG,
5cd47f
+                                    parent->sd_inherit, false);
5cd47f
+    if (inherit_option) {
5cd47f
+        return get_domain_mpg_mode(parent);
5cd47f
+    }
5cd47f
+
5cd47f
+    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx,
5cd47f
+                                                               subdom_name,
5cd47f
+                                                               subdom_sid_str);
5cd47f
+    if (use_id_mapping == true) {
5cd47f
+        default_mpg_mode = MPG_ENABLED;
5cd47f
+    } else {
5cd47f
+        /* Domains that use the POSIX attributes set by the admin must
5cd47f
+         * inherit the MPG setting from the parent domain so that the
5cd47f
+         * auto_private_groups options works for trusted domains as well
5cd47f
+         */
5cd47f
+        default_mpg_mode = get_domain_mpg_mode(parent);
5cd47f
+    }
5cd47f
+
5cd47f
+    return default_mpg_mode;
5cd47f
+}
5cd47f
+
5cd47f
+static enum sss_domain_mpg_mode
5cd47f
+ad_subdom_mpg_mode(TALLOC_CTX *mem_ctx,
5cd47f
+                   struct confdb_ctx *cdb,
5cd47f
+                   struct sss_domain_info *parent,
5cd47f
+                   enum sss_domain_mpg_mode default_mpg_mode,
5cd47f
+                   const char *subdom_name)
5cd47f
+{
5cd47f
+    char *subdom_conf_path;
5cd47f
+    char *mpg_str_opt;
5cd47f
+    errno_t ret;
5cd47f
+    enum sss_domain_mpg_mode ret_mode;
5cd47f
+
5cd47f
+    subdom_conf_path = subdomain_create_conf_path_from_str(mem_ctx,
5cd47f
+                                                           parent->name,
5cd47f
+                                                           subdom_name);
5cd47f
+    if (subdom_conf_path == NULL) {
5cd47f
+        DEBUG(SSSDBG_OP_FAILURE,
5cd47f
+              "subdom_conf_path failed, will use %s mode as fallback\n",
5cd47f
+              str_domain_mpg_mode(default_mpg_mode));
5cd47f
+        return default_mpg_mode;
5cd47f
+    }
5cd47f
+
5cd47f
+    ret = confdb_get_string(cdb, mem_ctx, subdom_conf_path,
5cd47f
+                            CONFDB_DOMAIN_AUTO_UPG,
5cd47f
+                            NULL,
5cd47f
+                            &mpg_str_opt);
5cd47f
+    talloc_free(subdom_conf_path);
5cd47f
+    if (ret != EOK) {
5cd47f
+        DEBUG(SSSDBG_OP_FAILURE,
5cd47f
+              "condb_get_string failed, will use %s mode as fallback\n",
5cd47f
+              str_domain_mpg_mode(default_mpg_mode));
5cd47f
+        return default_mpg_mode;
5cd47f
+    }
5cd47f
+
5cd47f
+    if (mpg_str_opt == NULL) {
5cd47f
+        DEBUG(SSSDBG_CONF_SETTINGS,
5cd47f
+              "Subdomain MPG mode not set, using %s\n",
5cd47f
+              str_domain_mpg_mode(default_mpg_mode));
5cd47f
+        return default_mpg_mode;
5cd47f
+    }
5cd47f
+
5cd47f
+    ret_mode = str_to_domain_mpg_mode(mpg_str_opt);
5cd47f
+    talloc_free(mpg_str_opt);
5cd47f
+    return ret_mode;
5cd47f
+}
5cd47f
+
5cd47f
 static errno_t
5cd47f
-ad_subdom_store(struct sdap_idmap_ctx *idmap_ctx,
5cd47f
+ad_subdom_store(struct confdb_ctx *cdb,
5cd47f
+                struct sdap_idmap_ctx *idmap_ctx,
5cd47f
                 struct sss_domain_info *domain,
5cd47f
                 struct sysdb_attrs *subdom_attrs,
5cd47f
                 bool enumerate)
5cd47f
@@ -451,8 +530,8 @@ ad_subdom_store(struct sdap_idmap_ctx *idmap_ctx,
5cd47f
     struct ldb_message_element *el;
5cd47f
     char *sid_str = NULL;
5cd47f
     uint32_t trust_type;
5cd47f
-    bool use_id_mapping;
5cd47f
     enum sss_domain_mpg_mode mpg_mode;
5cd47f
+    enum sss_domain_mpg_mode default_mpg_mode;
5cd47f
 
5cd47f
     tmp_ctx = talloc_new(NULL);
5cd47f
     if (tmp_ctx == NULL) {
5cd47f
@@ -501,17 +580,13 @@ ad_subdom_store(struct sdap_idmap_ctx *idmap_ctx,
5cd47f
         goto done;
5cd47f
     }
5cd47f
 
5cd47f
-    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(idmap_ctx,
5cd47f
-                                                               name, sid_str);
5cd47f
-    if (use_id_mapping == true) {
5cd47f
-        mpg_mode = MPG_ENABLED;
5cd47f
-    } else {
5cd47f
-        /* Domains that use the POSIX attributes set by the admin must
5cd47f
-         * inherit the MPG setting from the parent domain so that the
5cd47f
-         * auto_private_groups options works for trusted domains as well
5cd47f
-         */
5cd47f
-        mpg_mode = get_domain_mpg_mode(domain);
5cd47f
-    }
5cd47f
+    default_mpg_mode = get_default_subdom_mpg_mode(idmap_ctx, domain,
5cd47f
+                                                   name, sid_str);
5cd47f
+
5cd47f
+    mpg_mode = ad_subdom_mpg_mode(tmp_ctx, cdb, domain,
5cd47f
+                                  default_mpg_mode, name);
5cd47f
+    DEBUG(SSSDBG_CONF_SETTINGS, "MPG mode of %s is %s\n",
5cd47f
+                                name, str_domain_mpg_mode(mpg_mode));
5cd47f
 
5cd47f
     ret = sysdb_subdomain_store(domain->sysdb, name, realm, flat, sid_str,
5cd47f
                                 mpg_mode, enumerate, domain->forest, 0, NULL);
5cd47f
@@ -625,7 +700,8 @@ static errno_t ad_subdomains_refresh(struct be_ctx *be_ctx,
5cd47f
                 goto done;
5cd47f
             }
5cd47f
 
5cd47f
-            ret = ad_subdom_store(idmap_ctx, domain, subdomains[c], enumerate);
5cd47f
+            ret = ad_subdom_store(be_ctx->cdb, idmap_ctx, domain,
5cd47f
+                                  subdomains[c], enumerate);
5cd47f
             if (ret) {
5cd47f
                 /* Nothing we can do about the error. Let's at least try
5cd47f
                  * to reuse the existing domains
5cd47f
@@ -660,7 +736,8 @@ static errno_t ad_subdomains_refresh(struct be_ctx *be_ctx,
5cd47f
             goto done;
5cd47f
         }
5cd47f
 
5cd47f
-        ret = ad_subdom_store(idmap_ctx, domain, subdomains[c], enumerate);
5cd47f
+        ret = ad_subdom_store(be_ctx->cdb, idmap_ctx, domain,
5cd47f
+                              subdomains[c], enumerate);
5cd47f
         if (ret) {
5cd47f
             DEBUG(SSSDBG_MINOR_FAILURE, "Failed to parse subdom data, "
5cd47f
                   "will try to use cached subdomain\n");
5cd47f
diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c
5cd47f
index 92eeda1d3..af4dc1a17 100644
5cd47f
--- a/src/providers/ldap/sdap_async_users.c
5cd47f
+++ b/src/providers/ldap/sdap_async_users.c
5cd47f
@@ -389,7 +389,7 @@ int sdap_save_user(TALLOC_CTX *memctx,
5cd47f
             goto done;
5cd47f
         }
5cd47f
 
5cd47f
-        if (IS_SUBDOMAIN(dom) || sss_domain_is_mpg(dom) == true) {
5cd47f
+        if (sss_domain_is_mpg(dom) == true) {
5cd47f
             /* For subdomain users, only create the private group as
5cd47f
              * the subdomain is an MPG domain.
5cd47f
              * But we have to save the GID of the original primary group
5cd47f
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
5cd47f
index 4896ef051..4b1c9df39 100644
5cd47f
--- a/src/util/domain_info_utils.c
5cd47f
+++ b/src/util/domain_info_utils.c
5cd47f
@@ -889,6 +889,14 @@ bool sss_domain_is_forest_root(struct sss_domain_info *dom)
5cd47f
     return (dom->forest_root == dom);
5cd47f
 }
5cd47f
 
5cd47f
+char *subdomain_create_conf_path_from_str(TALLOC_CTX *mem_ctx,
5cd47f
+                                          const char *parent_name,
5cd47f
+                                          const char *subdom_name)
5cd47f
+{
5cd47f
+    return talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL "/%s",
5cd47f
+                           parent_name, subdom_name);
5cd47f
+}
5cd47f
+
5cd47f
 char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx,
5cd47f
                                  struct sss_domain_info *subdomain)
5cd47f
 {
5cd47f
@@ -899,9 +907,9 @@ char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx,
5cd47f
         return NULL;
5cd47f
     }
5cd47f
 
5cd47f
-    return talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL "/%s",
5cd47f
-                           subdomain->parent->name,
5cd47f
-                           subdomain->name);
5cd47f
+    return subdomain_create_conf_path_from_str(mem_ctx,
5cd47f
+                                               subdomain->parent->name,
5cd47f
+                                               subdomain->name);
5cd47f
 }
5cd47f
 
5cd47f
 const char *sss_domain_type_str(struct sss_domain_info *dom)
5cd47f
diff --git a/src/util/util.h b/src/util/util.h
5cd47f
index 1e36bf02a..3003583b7 100644
5cd47f
--- a/src/util/util.h
5cd47f
+++ b/src/util/util.h
5cd47f
@@ -557,6 +557,9 @@ find_domain_by_object_name_ex(struct sss_domain_info *domain,
5cd47f
 bool subdomain_enumerates(struct sss_domain_info *parent,
5cd47f
                           const char *sd_name);
5cd47f
 
5cd47f
+char *subdomain_create_conf_path_from_str(TALLOC_CTX *mem_ctx,
5cd47f
+                                          const char *parent_name,
5cd47f
+                                          const char *subdom_name);
5cd47f
 char *subdomain_create_conf_path(TALLOC_CTX *mem_ctx,
5cd47f
                                  struct sss_domain_info *subdomain);
5cd47f
 
5cd47f
-- 
5cd47f
2.19.1
5cd47f