Blame SOURCES/0026-AD-filter-domain-local-groups-for-trusted-sub-domain.patch

2fc102
From 8d55e0fffd29184d44cb49eaab2ca3a4226e0123 Mon Sep 17 00:00:00 2001
2fc102
From: Sumit Bose <sbose@redhat.com>
2fc102
Date: Tue, 10 Dec 2013 10:14:28 +0100
2fc102
Subject: [PATCH 26/31] AD: filter domain local groups for trusted/sub domains
2fc102
2fc102
In Active Directory groups with a domain local scope should only be used
2fc102
inside of the specific domain. Since SSSD read the group memberships
2fc102
from LDAP server of the user's domain the domain local groups are
2fc102
included in the LDAP result. Those groups should be filtered out if the
2fc102
domain is a sub/trusted domain, i.e. is not the domain the client
2fc102
running SSSD is joined to.
2fc102
2fc102
The groups will still be in the cache but marked as non-POSIX groups and
2fc102
no GID will be assigned.
2fc102
2fc102
Fixes https://fedorahosted.org/sssd/ticket/2178
2fc102
---
2fc102
 src/providers/ldap/sdap.h                     |   8 ++
2fc102
 src/providers/ldap/sdap_async_groups.c        | 160 ++++++++++++++++----------
2fc102
 src/providers/ldap/sdap_async_initgroups_ad.c |   6 +-
2fc102
 src/providers/ldap/sdap_async_nested_groups.c |  28 ++++-
2fc102
 4 files changed, 138 insertions(+), 64 deletions(-)
2fc102
2fc102
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
2fc102
index fa641730bb78b6a96c0b9640af7612b876f56533..a7ea94eb810a96b61862bd8cc6fcd800c3e8e0cb 100644
2fc102
--- a/src/providers/ldap/sdap.h
2fc102
+++ b/src/providers/ldap/sdap.h
2fc102
@@ -137,6 +137,14 @@ struct sdap_ppolicy_data {
2fc102
 #define SDAP_AD_USN "uSNChanged"
2fc102
 #define SDAP_AD_LAST_USN "highestCommittedUSN"
2fc102
 
2fc102
+#define SDAP_AD_GROUP_TYPE_BUILTIN      0x00000001
2fc102
+#define SDAP_AD_GROUP_TYPE_GLOBAL       0x00000002
2fc102
+#define SDAP_AD_GROUP_TYPE_DOMAIN_LOCAL 0x00000004
2fc102
+#define SDAP_AD_GROUP_TYPE_UNIVERSAL    0x00000008
2fc102
+#define SDAP_AD_GROUP_TYPE_APP_BASIC    0x00000010
2fc102
+#define SDAP_AD_GROUP_TYPE_APP_QUERY    0x00000020
2fc102
+#define SDAP_AD_GROUP_TYPE_SECURITY     0x80000000
2fc102
+
2fc102
 enum sdap_basic_opt {
2fc102
     SDAP_URI = 0,
2fc102
     SDAP_BACKUP_URI,
2fc102
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
2fc102
index 9f7e3e55d0234e9aa7b9e59456044587bcad88ef..33648c5da367c908d085a71a9a9017cb294bb300 100644
2fc102
--- a/src/providers/ldap/sdap_async_groups.c
2fc102
+++ b/src/providers/ldap/sdap_async_groups.c
2fc102
@@ -451,6 +451,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
2fc102
     bool posix_group;
2fc102
     bool use_id_mapping;
2fc102
     char *sid_str;
2fc102
+    int32_t ad_group_type;
2fc102
 
2fc102
     tmpctx = talloc_new(NULL);
2fc102
     if (!tmpctx) {
2fc102
@@ -503,74 +504,113 @@ static int sdap_save_group(TALLOC_CTX *memctx,
2fc102
     }
2fc102
     DEBUG(SSSDBG_TRACE_FUNC, ("Processing group %s\n", group_name));
2fc102
 
2fc102
-    use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
2fc102
-                                                               dom->name,
2fc102
-                                                               sid_str);
2fc102
-    if (use_id_mapping) {
2fc102
-        posix_group = true;
2fc102
-
2fc102
-        if (sid_str == NULL) {
2fc102
-            DEBUG(SSSDBG_MINOR_FAILURE, ("SID not available, cannot map a " \
2fc102
-                                         "unix ID to group [%s].\n", group_name));
2fc102
-            ret = ENOENT;
2fc102
+    posix_group = true;
2fc102
+    if (opts->schema_type == SDAP_SCHEMA_AD) {
2fc102
+        ret = sysdb_attrs_get_int32_t(attrs, SYSDB_GROUP_TYPE, &ad_group_type);
2fc102
+        if (ret != EOK) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_int32_t failed.\n"));
2fc102
             goto done;
2fc102
         }
2fc102
 
2fc102
-        DEBUG(SSSDBG_TRACE_LIBS,
2fc102
-              ("Mapping group [%s] objectSID [%s] to unix ID\n",
2fc102
-               group_name, sid_str));
2fc102
-
2fc102
-        /* Convert the SID into a UNIX group ID */
2fc102
-        ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &gid;;
2fc102
-        if (ret == ENOTSUP) {
2fc102
-            /* ENOTSUP is returned if built-in SID was provided
2fc102
-             * => do not store the group, but return EOK */
2fc102
-            DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n"));
2fc102
-            ret = EOK;
2fc102
-            goto done;
2fc102
-        } else if (ret != EOK) {
2fc102
-            DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
-                  ("Could not convert SID string: [%s]\n",
2fc102
-                   strerror(ret)));
2fc102
-            goto done;
2fc102
+        DEBUG(SSSDBG_TRACE_ALL, ("AD group [%s] has type flags %#x.",
2fc102
+                                 group_name, ad_group_type));
2fc102
+        /* Only security groups from AD are considered for POSIX groups.
2fc102
+         * Additionally only global and universal group are taken to account
2fc102
+         * for trusted domains. */
2fc102
+        if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY)
2fc102
+                || (IS_SUBDOMAIN(dom)
2fc102
+                    && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL)
2fc102
+                        || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) {
2fc102
+            posix_group = false;
2fc102
+            gid = 0;
2fc102
+            DEBUG(SSSDBG_TRACE_FUNC, ("Filtering AD group [%s].\n",
2fc102
+                                      group_name));
2fc102
+            ret = sysdb_attrs_add_uint32(group_attrs,
2fc102
+                                         opts->group_map[SDAP_AT_GROUP_GID].sys_name, 0);
2fc102
+            if (ret != EOK) {
2fc102
+                DEBUG(SSSDBG_CRIT_FAILURE,
2fc102
+                      ("Failed to add a GID to non-posix group!\n"));
2fc102
+                return ret;
2fc102
+            }
2fc102
+            ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, false);
2fc102
+            if (ret != EOK) {
2fc102
+                DEBUG(SSSDBG_OP_FAILURE,
2fc102
+                      ("Error: Failed to mark group as non-posix!\n"));
2fc102
+                return ret;
2fc102
+            }
2fc102
         }
2fc102
+    }
2fc102
 
2fc102
-        /* Store the GID in the ldap_attrs so it doesn't get
2fc102
-         * treated as a missing attribute from LDAP and removed.
2fc102
-         */
2fc102
-        ret = sdap_replace_id(attrs, SYSDB_GIDNUM, gid);
2fc102
-        if (ret) {
2fc102
-            DEBUG(SSSDBG_OP_FAILURE, ("Cannot set the id-mapped GID\n"));
2fc102
-            goto done;
2fc102
-        }
2fc102
-    } else {
2fc102
-        ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix_group);
2fc102
-        if (ret == ENOENT) {
2fc102
+    if (posix_group) {
2fc102
+        use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
2fc102
+                                                                   dom->name,
2fc102
+                                                                   sid_str);
2fc102
+        if (use_id_mapping) {
2fc102
             posix_group = true;
2fc102
-        } else if (ret != EOK) {
2fc102
-            DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
-                  ("Error reading posix attribute: [%s]\n",
2fc102
-                   strerror(ret)));
2fc102
-            goto done;
2fc102
-        }
2fc102
 
2fc102
-        DEBUG(8, ("This is%s a posix group\n", (posix_group)?"":" not"));
2fc102
-        ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, posix_group);
2fc102
-        if (ret != EOK) {
2fc102
-            DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
-                  ("Error setting posix attribute: [%s]\n",
2fc102
-                   strerror(ret)));
2fc102
-            goto done;
2fc102
-        }
2fc102
+            if (sid_str == NULL) {
2fc102
+                DEBUG(SSSDBG_MINOR_FAILURE, ("SID not available, cannot map a " \
2fc102
+                                             "unix ID to group [%s].\n", group_name));
2fc102
+                ret = ENOENT;
2fc102
+                goto done;
2fc102
+            }
2fc102
 
2fc102
-        ret = sysdb_attrs_get_uint32_t(attrs,
2fc102
-                                       opts->group_map[SDAP_AT_GROUP_GID].sys_name,
2fc102
-                                       &gid;;
2fc102
-        if (ret != EOK) {
2fc102
-            DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
2fc102
-                      group_name, dom->name));
2fc102
-            ret = EINVAL;
2fc102
-            goto done;
2fc102
+            DEBUG(SSSDBG_TRACE_LIBS,
2fc102
+                  ("Mapping group [%s] objectSID [%s] to unix ID\n",
2fc102
+                   group_name, sid_str));
2fc102
+
2fc102
+            /* Convert the SID into a UNIX group ID */
2fc102
+            ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &gid;;
2fc102
+            if (ret == ENOTSUP) {
2fc102
+                /* ENOTSUP is returned if built-in SID was provided
2fc102
+                 * => do not store the group, but return EOK */
2fc102
+                DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n"));
2fc102
+                ret = EOK;
2fc102
+                goto done;
2fc102
+            } else if (ret != EOK) {
2fc102
+                DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
+                      ("Could not convert SID string: [%s]\n",
2fc102
+                       strerror(ret)));
2fc102
+                goto done;
2fc102
+            }
2fc102
+
2fc102
+            /* Store the GID in the ldap_attrs so it doesn't get
2fc102
+             * treated as a missing attribute from LDAP and removed.
2fc102
+             */
2fc102
+            ret = sdap_replace_id(attrs, SYSDB_GIDNUM, gid);
2fc102
+            if (ret) {
2fc102
+                DEBUG(SSSDBG_OP_FAILURE, ("Cannot set the id-mapped GID\n"));
2fc102
+                goto done;
2fc102
+            }
2fc102
+        } else {
2fc102
+            ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix_group);
2fc102
+            if (ret == ENOENT) {
2fc102
+                posix_group = true;
2fc102
+            } else if (ret != EOK) {
2fc102
+                DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
+                      ("Error reading posix attribute: [%s]\n",
2fc102
+                       strerror(ret)));
2fc102
+                goto done;
2fc102
+            }
2fc102
+
2fc102
+            DEBUG(8, ("This is%s a posix group\n", (posix_group)?"":" not"));
2fc102
+            ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, posix_group);
2fc102
+            if (ret != EOK) {
2fc102
+                DEBUG(SSSDBG_MINOR_FAILURE,
2fc102
+                      ("Error setting posix attribute: [%s]\n",
2fc102
+                       strerror(ret)));
2fc102
+                goto done;
2fc102
+            }
2fc102
+
2fc102
+            ret = sysdb_attrs_get_uint32_t(attrs,
2fc102
+                                           opts->group_map[SDAP_AT_GROUP_GID].sys_name,
2fc102
+                                           &gid;;
2fc102
+            if (ret != EOK) {
2fc102
+                DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
2fc102
+                          group_name, dom->name));
2fc102
+                ret = EINVAL;
2fc102
+                goto done;
2fc102
+            }
2fc102
         }
2fc102
     }
2fc102
 
2fc102
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
index 8e0506831cb189415b62efaa378d3dc7ec350cde..f1bf77e8614c30b214118140e380c23c40c1195b 100644
2fc102
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
2fc102
@@ -1145,6 +1145,7 @@ static errno_t sdap_ad_tokengroups_initgr_posix_recv(struct tevent_req *req)
2fc102
 
2fc102
 struct sdap_ad_tokengroups_initgroups_state {
2fc102
     bool use_id_mapping;
2fc102
+    struct sss_domain_info *domain;
2fc102
 };
2fc102
 
2fc102
 static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq);
2fc102
@@ -1175,8 +1176,9 @@ sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
2fc102
     }
2fc102
 
2fc102
     state->use_id_mapping = use_id_mapping;
2fc102
+    state->domain = domain;
2fc102
 
2fc102
-    if (state->use_id_mapping) {
2fc102
+    if (state->use_id_mapping && !IS_SUBDOMAIN(state->domain)) {
2fc102
         subreq = sdap_ad_tokengroups_initgr_mapping_send(state, ev, opts,
2fc102
                                                          sysdb, domain, sh,
2fc102
                                                          name, orig_dn,
2fc102
@@ -1216,7 +1218,7 @@ static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq)
2fc102
     req = tevent_req_callback_data(subreq, struct tevent_req);
2fc102
     state = tevent_req_data(req, struct sdap_ad_tokengroups_initgroups_state);
2fc102
 
2fc102
-    if (state->use_id_mapping) {
2fc102
+    if (state->use_id_mapping && !IS_SUBDOMAIN(state->domain)) {
2fc102
         ret = sdap_ad_tokengroups_initgr_mapping_recv(subreq);
2fc102
     } else {
2fc102
         ret = sdap_ad_tokengroups_initgr_posix_recv(subreq);
2fc102
diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
2fc102
index c107b700b84b8c178051fd4505f3947be8373de2..f58564aec0628c827672950f767401ee32051b59 100644
2fc102
--- a/src/providers/ldap/sdap_async_nested_groups.c
2fc102
+++ b/src/providers/ldap/sdap_async_nested_groups.c
2fc102
@@ -239,15 +239,39 @@ sdap_nested_group_hash_group(struct sdap_nested_group_ctx *group_ctx,
2fc102
     struct sdap_attr_map *map = group_ctx->opts->group_map;
2fc102
     gid_t gid;
2fc102
     errno_t ret;
2fc102
+    int32_t ad_group_type;
2fc102
+    bool posix_group = true;
2fc102
+
2fc102
+    if (group_ctx->opts->schema_type == SDAP_SCHEMA_AD) {
2fc102
+        ret = sysdb_attrs_get_int32_t(group, SYSDB_GROUP_TYPE, &ad_group_type);
2fc102
+        if (ret != EOK) {
2fc102
+            DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_int32_t failed.\n"));
2fc102
+            return ret;
2fc102
+        }
2fc102
+
2fc102
+        DEBUG(SSSDBG_TRACE_ALL, ("AD group has type flags %#x.\n",
2fc102
+                                 ad_group_type));
2fc102
+        /* Only security groups from AD are considered for POSIX groups.
2fc102
+         * Additionally only global and universal group are taken to account
2fc102
+         * for trusted domains. */
2fc102
+        if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY)
2fc102
+                || (IS_SUBDOMAIN(group_ctx->domain)
2fc102
+                    && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL)
2fc102
+                        || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) {
2fc102
+            posix_group = false;
2fc102
+            gid = 0;
2fc102
+            DEBUG(SSSDBG_TRACE_FUNC, ("Filtering AD group.\n"));
2fc102
+        }
2fc102
+    }
2fc102
 
2fc102
     ret = sysdb_attrs_get_uint32_t(group, map[SDAP_AT_GROUP_GID].sys_name,
2fc102
                                    &gid;;
2fc102
-    if (ret == ENOENT || (ret == EOK && gid == 0)) {
2fc102
+    if (ret == ENOENT || (ret == EOK && gid == 0) || !posix_group) {
2fc102
         DEBUG(SSSDBG_TRACE_ALL,
2fc102
              ("The group's gid was %s\n", ret == ENOENT ? "missing" : "zero"));
2fc102
         DEBUG(SSSDBG_TRACE_INTERNAL,
2fc102
              ("Marking group as non-posix and setting GID=0!\n"));
2fc102
-        if (ret == ENOENT) {
2fc102
+        if (ret == ENOENT || !posix_group) {
2fc102
             ret = sysdb_attrs_add_uint32(group,
2fc102
                                          map[SDAP_AT_GROUP_GID].sys_name, 0);
2fc102
             if (ret != EOK) {
2fc102
-- 
2fc102
1.8.4.2
2fc102