URL: https://github.com/SSSD/sssd/pull/5613
Author: pbrezina
 Title: #5613: ipa: read auto_private_groups from id range if available
Action: opened

PR body:
"""
The functionality depends on new attribute in IPA:
* https://github.com/freeipa/freeipa/pull/5712 (already merged)

It defaults to current behavior if the attribute is not present.

Resolves: https://github.com/SSSD/sssd/issues/4216

:feature: `auto_private_groups` option can be set centrally through
  ID range setting in IPA (see `ipa idrange` commands family)
"""

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/5613/head:pr5613
git checkout pr5613
From 79e00e03e06dd029e4e5d904e883cc2174ffc057 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrez...@redhat.com>
Date: Wed, 28 Apr 2021 14:17:40 +0200
Subject: [PATCH] ipa: read auto_private_groups from id range if available

Resolves: https://github.com/SSSD/sssd/issues/4216

:feature: `auto_private_groups` option can be set centrally through
  ID range setting in IPA (see `ipa idrange` commands family)
---
 src/confdb/confdb.h                |  1 +
 src/db/sysdb.h                     |  6 ++++
 src/db/sysdb_ranges.c              | 46 ++++++++++++++++++++++++++++++
 src/db/sysdb_subdomains.c          |  5 ++++
 src/providers/ipa/ipa_common.h     |  1 +
 src/providers/ipa/ipa_idmap.c      | 10 +++++++
 src/providers/ipa/ipa_subdomains.c | 45 ++++++++++++++++++++---------
 src/util/domain_info_utils.c       |  5 ++++
 8 files changed, 106 insertions(+), 13 deletions(-)

diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
index c6c2514f83..60a2099999 100644
--- a/src/confdb/confdb.h
+++ b/src/confdb/confdb.h
@@ -345,6 +345,7 @@ enum sss_domain_mpg_mode {
     MPG_DISABLED,
     MPG_ENABLED,
     MPG_HYBRID,
+    MPG_DEFAULT, /* Use default value for given id mapping. */
 };
 
 /**
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 0043ca01d8..0069d8a670 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -165,6 +165,7 @@
 #define SYSDB_SECONDARY_BASE_RID "secondaryBaseRID"
 #define SYSDB_DOMAIN_ID "domainID"
 #define SYSDB_ID_RANGE_TYPE "idRangeType"
+#define SYSDB_ID_RANGE_MPG "idRangeMPG"
 
 #define SYSDB_CERTMAP_PRIORITY "priority"
 #define SYSDB_CERTMAP_MATCHING_RULE "matchingRule"
@@ -344,6 +345,7 @@ struct range_info {
     uint32_t secondary_base_rid;
     char *trusted_dom_sid;
     char *range_type;
+    enum sss_domain_mpg_mode mpg_mode;
 };
 
 struct certmap_info {
@@ -584,6 +586,10 @@ struct sss_domain_info *new_subdomain(TALLOC_CTX *mem_ctx,
 errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
                              size_t *range_count,
                              struct range_info ***range_list);
+errno_t sysdb_get_range(TALLOC_CTX *mem_ctx,
+                        struct sysdb_ctx *sysdb,
+                        const char *forest,
+                        struct range_info **_range);
 errno_t sysdb_range_create(struct sysdb_ctx *sysdb, struct range_info *range);
 errno_t sysdb_update_ranges(struct sysdb_ctx *sysdb,
                             struct range_info **ranges);
diff --git a/src/db/sysdb_ranges.c b/src/db/sysdb_ranges.c
index be3a0d3722..3172a64939 100644
--- a/src/db/sysdb_ranges.c
+++ b/src/db/sysdb_ranges.c
@@ -54,6 +54,7 @@ errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
                            SYSDB_SECONDARY_BASE_RID,
                            SYSDB_DOMAIN_ID,
                            SYSDB_ID_RANGE_TYPE,
+                           SYSDB_ID_RANGE_MPG,
                            NULL};
     struct range_info **list;
     struct ldb_dn *basedn;
@@ -152,6 +153,9 @@ errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
             }
         }
 
+        tmp_str = ldb_msg_find_attr_as_string(res->msgs[c], SYSDB_ID_RANGE_MPG,
+                                              "default");
+        list[c]->mpg_mode = str_to_domain_mpg_mode(tmp_str);
     }
     list[res->count] = NULL;
 
@@ -164,6 +168,44 @@ errno_t sysdb_get_ranges(TALLOC_CTX *mem_ctx, struct sysdb_ctx *sysdb,
     return ret;
 }
 
+errno_t sysdb_get_range(TALLOC_CTX *mem_ctx,
+                        struct sysdb_ctx *sysdb,
+                        const char *forest,
+                        struct range_info **_range)
+{
+    struct range_info **list;
+    struct range_info *range;
+    size_t count;
+    size_t i;
+    errno_t ret;
+
+    ret = sysdb_get_ranges(NULL, sysdb, &count, &list);
+    if (ret != EOK) {
+        return ret;
+    }
+
+    for (i = 0; i < count; i++) {
+        range = list[i];
+        if (range->trusted_dom_sid == NULL) {
+            continue;
+        }
+
+        if (strcmp(range->trusted_dom_sid, forest) != 0) {
+            continue;
+        }
+
+        *_range = talloc_steal(mem_ctx, range);
+        ret = EOK;
+        goto done;
+    }
+
+    ret = ENOENT;
+
+done:
+    talloc_free(list);
+    return ret;
+}
+
 errno_t sysdb_range_create(struct sysdb_ctx *sysdb, struct range_info *range)
 {
     struct ldb_message *msg;
@@ -239,6 +281,10 @@ errno_t sysdb_range_create(struct sysdb_ctx *sysdb, struct range_info *range)
     ret = sysdb_add_string(msg, SYSDB_ID_RANGE_TYPE, range->range_type);
     if (ret) goto done;
 
+    ret = sysdb_add_string(msg, SYSDB_ID_RANGE_MPG,
+                           str_domain_mpg_mode(range->mpg_mode));
+    if (ret) goto done;
+
     ret = ldb_add(sysdb->ldb, msg);
     if (ret) goto done;
 
diff --git a/src/db/sysdb_subdomains.c b/src/db/sysdb_subdomains.c
index 348f242d08..b57f6efbc3 100644
--- a/src/db/sysdb_subdomains.c
+++ b/src/db/sysdb_subdomains.c
@@ -1130,6 +1130,11 @@ errno_t sysdb_subdomain_store(struct sysdb_ctx *sysdb,
                 mpg_flags = LDB_FLAG_MOD_REPLACE;
             }
             break;
+        case MPG_DEFAULT:
+            if (strcasecmp(tmp_str, "default") != 0) {
+                mpg_flags = LDB_FLAG_MOD_REPLACE;
+            }
+            break;
         }
 
         tmp_bool = ldb_msg_find_attr_as_bool(res->msgs[0], SYSDB_SUBDOMAIN_ENUM,
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index db382ab8ba..480f7b6644 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -36,6 +36,7 @@
 #define IPA_ID_RANGE_SIZE "ipaIDRangeSize"
 #define IPA_BASE_RID "ipaBaseRID"
 #define IPA_SECONDARY_BASE_RID "ipaSecondaryBaseRID"
+#define IPA_ID_RANGE_MPG "ipaAutoPrivateGroups"
 
 struct ipa_service {
     struct sdap_service *sdap;
diff --git a/src/providers/ipa/ipa_idmap.c b/src/providers/ipa/ipa_idmap.c
index 7e65ed02a4..5d8d56b856 100644
--- a/src/providers/ipa/ipa_idmap.c
+++ b/src/providers/ipa/ipa_idmap.c
@@ -333,6 +333,16 @@ errno_t ipa_ranges_parse_results(TALLOC_CTX *mem_ctx,
             goto done;
         }
 
+        ret = sysdb_attrs_get_string(reply[c], IPA_ID_RANGE_MPG, &value);
+        if (ret == EOK) {
+            r->mpg_mode = str_to_domain_mpg_mode(value);
+        } else if (ret == ENOENT) {
+            r->mpg_mode = MPG_DEFAULT;
+        } else {
+            DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_get_string failed.\n");
+            goto done;
+        }
+
         ret = get_idmap_data_from_range(r, domain_name, &name1, &sid1, &rid1,
                                         &range1, &mapping1);
         if (ret == ERR_UNSUPPORTED_RANGE_TYPE) {
diff --git a/src/providers/ipa/ipa_subdomains.c b/src/providers/ipa/ipa_subdomains.c
index 252c25efc9..1b598a6c2b 100644
--- a/src/providers/ipa/ipa_subdomains.c
+++ b/src/providers/ipa/ipa_subdomains.c
@@ -408,6 +408,9 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent,
     bool enumerate;
     uint32_t direction;
     struct ldb_message_element *alternative_domain_suffixes = NULL;
+    struct range_info *range;
+    struct sss_domain_info *forest_dom;
+    const char *forest_id;
 
     tmp_ctx = talloc_new(parent);
     if (tmp_ctx == NULL) {
@@ -444,18 +447,6 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent,
         goto done;
     }
 
-    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(sdap_idmap_ctx,
-                                                               name, id);
-    if (use_id_mapping == true) {
-        mpg_mode = MPG_ENABLED;
-    } else {
-        /* Domains that use the POSIX attributes set by the admin must
-         * inherit the MPG setting from the parent domain so that the
-         * auto_private_groups options works for trusted domains as well
-         */
-        mpg_mode = get_domain_mpg_mode(parent);
-    }
-
     ret = ipa_subdom_get_forest(tmp_ctx, sysdb_ctx_get_ldb(parent->sysdb),
                                 attrs, &forest);
     if (ret != EOK) {
@@ -481,6 +472,34 @@ static errno_t ipa_subdom_store(struct sss_domain_info *parent,
               "Trust type of [%s]: %s\n", name, ipa_trust_dir2str(direction));
     }
 
+    /* If the root domain does not exist then this is the root */
+    forest_dom = find_domain_by_name(id_ctx->sdap_id_ctx->be->domain, forest,
+                                     false);
+    forest_id = forest_dom == NULL ? id : forest_dom->domain_id;
+    ret = sysdb_get_range(tmp_ctx, parent->sysdb, forest_id, &range);
+    mpg_mode = ret == EOK ? range->mpg_mode : MPG_DEFAULT;
+
+
+    DEBUG(SSSDBG_TRACE_FUNC, "Range mpg mode for %s: %s\n",
+          name, str_domain_mpg_mode(mpg_mode));
+
+    if (mpg_mode == MPG_DEFAULT) {
+        use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
+                                                    sdap_idmap_ctx, name, id);
+        if (use_id_mapping == true) {
+            mpg_mode = MPG_ENABLED;
+        } else {
+            /* Domains that use the POSIX attributes set by the admin must
+            * inherit the MPG setting from the parent domain so that the
+            * auto_private_groups options works for trusted domains as well
+            */
+            mpg_mode = get_domain_mpg_mode(parent);
+        }
+    }
+
+    DEBUG(SSSDBG_TRACE_FUNC, "Domain mpg mode for %s: %s\n",
+          name, str_domain_mpg_mode(mpg_mode));
+
     ret = sysdb_subdomain_store(parent->sysdb, name, realm, flat,
                                 id, mpg_mode, enumerate, forest,
                                 direction, alternative_domain_suffixes);
@@ -948,7 +967,7 @@ ipa_subdomains_ranges_send(TALLOC_CTX *mem_ctx,
     const char *attrs[] = { OBJECTCLASS, IPA_CN,
                             IPA_BASE_ID, IPA_BASE_RID, IPA_SECONDARY_BASE_RID,
                             IPA_ID_RANGE_SIZE, IPA_TRUSTED_DOMAIN_SID,
-                            IPA_RANGE_TYPE, NULL };
+                            IPA_RANGE_TYPE, IPA_ID_RANGE_MPG, NULL };
 
     req = tevent_req_create(mem_ctx, &state,
                             struct ipa_subdomains_ranges_state);
diff --git a/src/util/domain_info_utils.c b/src/util/domain_info_utils.c
index 57157861ea..26e3ed054e 100644
--- a/src/util/domain_info_utils.c
+++ b/src/util/domain_info_utils.c
@@ -980,6 +980,8 @@ const char *str_domain_mpg_mode(enum sss_domain_mpg_mode mpg_mode)
         return "false";
     case MPG_HYBRID:
         return "hybrid";
+    case MPG_DEFAULT:
+        return "default";
     }
 
     return NULL;
@@ -993,8 +995,11 @@ enum sss_domain_mpg_mode str_to_domain_mpg_mode(const char *str_mpg_mode)
         return MPG_ENABLED;
     } else if (strcasecmp(str_mpg_mode, "HYBRID") == 0) {
         return MPG_HYBRID;
+    } else if (strcasecmp(str_mpg_mode, "DEFAULT") == 0) {
+        return MPG_DEFAULT;
     }
 
+
     DEBUG(SSSDBG_MINOR_FAILURE,
           "Invalid value for %s\n, assuming disabled",
           SYSDB_SUBDOMAIN_MPG);
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org
Fedora Code of Conduct: 
https://docs.fedoraproject.org/en-US/project/code-of-conduct/
List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines
List Archives: 
https://lists.fedorahosted.org/archives/list/sssd-devel@lists.fedorahosted.org
Do not reply to spam on the list, report it: 
https://pagure.io/fedora-infrastructure

Reply via email to