summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2013-12-10 10:14:28 +0100
committerJakub Hrozek <jhrozek@redhat.com>2013-12-19 17:34:01 +0100
commit8280c5213094a72fcaa499dda2f8647246185d45 (patch)
tree632fd902d268e1d537fd10f8ffbe835c6c894013
parentfb4435785f92712840efb107700452598371ce77 (diff)
downloadsssd-8280c5213094a72fcaa499dda2f8647246185d45.tar.gz
sssd-8280c5213094a72fcaa499dda2f8647246185d45.tar.xz
sssd-8280c5213094a72fcaa499dda2f8647246185d45.zip
AD: filter domain local groups for trusted/sub domains
In Active Directory groups with a domain local scope should only be used inside of the specific domain. Since SSSD read the group memberships from LDAP server of the user's domain the domain local groups are included in the LDAP result. Those groups should be filtered out if the domain is a sub/trusted domain, i.e. is not the domain the client running SSSD is joined to. The groups will still be in the cache but marked as non-POSIX groups and no GID will be assigned. Fixes https://fedorahosted.org/sssd/ticket/2178
-rw-r--r--src/providers/ldap/sdap.h8
-rw-r--r--src/providers/ldap/sdap_async_groups.c160
-rw-r--r--src/providers/ldap/sdap_async_initgroups_ad.c6
-rw-r--r--src/providers/ldap/sdap_async_nested_groups.c28
4 files changed, 138 insertions, 64 deletions
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 59b181c72..73c7055f1 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -137,6 +137,14 @@ struct sdap_ppolicy_data {
#define SDAP_AD_USN "uSNChanged"
#define SDAP_AD_LAST_USN "highestCommittedUSN"
+#define SDAP_AD_GROUP_TYPE_BUILTIN 0x00000001
+#define SDAP_AD_GROUP_TYPE_GLOBAL 0x00000002
+#define SDAP_AD_GROUP_TYPE_DOMAIN_LOCAL 0x00000004
+#define SDAP_AD_GROUP_TYPE_UNIVERSAL 0x00000008
+#define SDAP_AD_GROUP_TYPE_APP_BASIC 0x00000010
+#define SDAP_AD_GROUP_TYPE_APP_QUERY 0x00000020
+#define SDAP_AD_GROUP_TYPE_SECURITY 0x80000000
+
enum sdap_basic_opt {
SDAP_URI = 0,
SDAP_BACKUP_URI,
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 1a911fef6..9b8e6e5c0 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -449,6 +449,7 @@ static int sdap_save_group(TALLOC_CTX *memctx,
bool posix_group;
bool use_id_mapping;
char *sid_str;
+ int32_t ad_group_type;
tmpctx = talloc_new(NULL);
if (!tmpctx) {
@@ -501,74 +502,113 @@ static int sdap_save_group(TALLOC_CTX *memctx,
}
DEBUG(SSSDBG_TRACE_FUNC, ("Processing group %s\n", group_name));
- use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
- dom->name,
- sid_str);
- if (use_id_mapping) {
- posix_group = true;
-
- if (sid_str == NULL) {
- DEBUG(SSSDBG_MINOR_FAILURE, ("SID not available, cannot map a " \
- "unix ID to group [%s].\n", group_name));
- ret = ENOENT;
+ posix_group = true;
+ if (opts->schema_type == SDAP_SCHEMA_AD) {
+ ret = sysdb_attrs_get_int32_t(attrs, SYSDB_GROUP_TYPE, &ad_group_type);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_int32_t failed.\n"));
goto done;
}
- DEBUG(SSSDBG_TRACE_LIBS,
- ("Mapping group [%s] objectSID [%s] to unix ID\n",
- group_name, sid_str));
-
- /* Convert the SID into a UNIX group ID */
- ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &gid);
- if (ret == ENOTSUP) {
- /* ENOTSUP is returned if built-in SID was provided
- * => do not store the group, but return EOK */
- DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n"));
- ret = EOK;
- goto done;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("Could not convert SID string: [%s]\n",
- strerror(ret)));
- goto done;
+ DEBUG(SSSDBG_TRACE_ALL, ("AD group [%s] has type flags %#x.",
+ group_name, ad_group_type));
+ /* Only security groups from AD are considered for POSIX groups.
+ * Additionally only global and universal group are taken to account
+ * for trusted domains. */
+ if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY)
+ || (IS_SUBDOMAIN(dom)
+ && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL)
+ || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) {
+ posix_group = false;
+ gid = 0;
+ DEBUG(SSSDBG_TRACE_FUNC, ("Filtering AD group [%s].\n",
+ group_name));
+ ret = sysdb_attrs_add_uint32(group_attrs,
+ opts->group_map[SDAP_AT_GROUP_GID].sys_name, 0);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Failed to add a GID to non-posix group!\n"));
+ return ret;
+ }
+ ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, false);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ ("Error: Failed to mark group as non-posix!\n"));
+ return ret;
+ }
}
+ }
- /* Store the GID in the ldap_attrs so it doesn't get
- * treated as a missing attribute from LDAP and removed.
- */
- ret = sdap_replace_id(attrs, SYSDB_GIDNUM, gid);
- if (ret) {
- DEBUG(SSSDBG_OP_FAILURE, ("Cannot set the id-mapped GID\n"));
- goto done;
- }
- } else {
- ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix_group);
- if (ret == ENOENT) {
+ if (posix_group) {
+ use_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(opts->idmap_ctx,
+ dom->name,
+ sid_str);
+ if (use_id_mapping) {
posix_group = true;
- } else if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("Error reading posix attribute: [%s]\n",
- strerror(ret)));
- goto done;
- }
- DEBUG(8, ("This is%s a posix group\n", (posix_group)?"":" not"));
- ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, posix_group);
- if (ret != EOK) {
- DEBUG(SSSDBG_MINOR_FAILURE,
- ("Error setting posix attribute: [%s]\n",
- strerror(ret)));
- goto done;
- }
+ if (sid_str == NULL) {
+ DEBUG(SSSDBG_MINOR_FAILURE, ("SID not available, cannot map a " \
+ "unix ID to group [%s].\n", group_name));
+ ret = ENOENT;
+ goto done;
+ }
- ret = sysdb_attrs_get_uint32_t(attrs,
- opts->group_map[SDAP_AT_GROUP_GID].sys_name,
- &gid);
- if (ret != EOK) {
- DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
- group_name, dom->name));
- ret = EINVAL;
- goto done;
+ DEBUG(SSSDBG_TRACE_LIBS,
+ ("Mapping group [%s] objectSID [%s] to unix ID\n",
+ group_name, sid_str));
+
+ /* Convert the SID into a UNIX group ID */
+ ret = sdap_idmap_sid_to_unix(opts->idmap_ctx, sid_str, &gid);
+ if (ret == ENOTSUP) {
+ /* ENOTSUP is returned if built-in SID was provided
+ * => do not store the group, but return EOK */
+ DEBUG(SSSDBG_TRACE_FUNC, ("Skipping built-in object.\n"));
+ ret = EOK;
+ goto done;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Could not convert SID string: [%s]\n",
+ strerror(ret)));
+ goto done;
+ }
+
+ /* Store the GID in the ldap_attrs so it doesn't get
+ * treated as a missing attribute from LDAP and removed.
+ */
+ ret = sdap_replace_id(attrs, SYSDB_GIDNUM, gid);
+ if (ret) {
+ DEBUG(SSSDBG_OP_FAILURE, ("Cannot set the id-mapped GID\n"));
+ goto done;
+ }
+ } else {
+ ret = sysdb_attrs_get_bool(attrs, SYSDB_POSIX, &posix_group);
+ if (ret == ENOENT) {
+ posix_group = true;
+ } else if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Error reading posix attribute: [%s]\n",
+ strerror(ret)));
+ goto done;
+ }
+
+ DEBUG(8, ("This is%s a posix group\n", (posix_group)?"":" not"));
+ ret = sysdb_attrs_add_bool(group_attrs, SYSDB_POSIX, posix_group);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Error setting posix attribute: [%s]\n",
+ strerror(ret)));
+ goto done;
+ }
+
+ ret = sysdb_attrs_get_uint32_t(attrs,
+ opts->group_map[SDAP_AT_GROUP_GID].sys_name,
+ &gid);
+ if (ret != EOK) {
+ DEBUG(1, ("no gid provided for [%s] in domain [%s].\n",
+ group_name, dom->name));
+ ret = EINVAL;
+ goto done;
+ }
}
}
diff --git a/src/providers/ldap/sdap_async_initgroups_ad.c b/src/providers/ldap/sdap_async_initgroups_ad.c
index ccaded945..1a381d81f 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -1142,6 +1142,7 @@ static errno_t sdap_ad_tokengroups_initgr_posix_recv(struct tevent_req *req)
struct sdap_ad_tokengroups_initgroups_state {
bool use_id_mapping;
+ struct sss_domain_info *domain;
};
static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq);
@@ -1172,8 +1173,9 @@ sdap_ad_tokengroups_initgroups_send(TALLOC_CTX *mem_ctx,
}
state->use_id_mapping = use_id_mapping;
+ state->domain = domain;
- if (state->use_id_mapping) {
+ if (state->use_id_mapping && !IS_SUBDOMAIN(state->domain)) {
subreq = sdap_ad_tokengroups_initgr_mapping_send(state, ev, opts,
sysdb, domain, sh,
name, orig_dn,
@@ -1213,7 +1215,7 @@ static void sdap_ad_tokengroups_initgroups_done(struct tevent_req *subreq)
req = tevent_req_callback_data(subreq, struct tevent_req);
state = tevent_req_data(req, struct sdap_ad_tokengroups_initgroups_state);
- if (state->use_id_mapping) {
+ if (state->use_id_mapping && !IS_SUBDOMAIN(state->domain)) {
ret = sdap_ad_tokengroups_initgr_mapping_recv(subreq);
} else {
ret = sdap_ad_tokengroups_initgr_posix_recv(subreq);
diff --git a/src/providers/ldap/sdap_async_nested_groups.c b/src/providers/ldap/sdap_async_nested_groups.c
index 2ff1ecb7b..306f55397 100644
--- a/src/providers/ldap/sdap_async_nested_groups.c
+++ b/src/providers/ldap/sdap_async_nested_groups.c
@@ -240,15 +240,39 @@ sdap_nested_group_hash_group(struct sdap_nested_group_ctx *group_ctx,
struct sdap_attr_map *map = group_ctx->opts->group_map;
gid_t gid;
errno_t ret;
+ int32_t ad_group_type;
+ bool posix_group = true;
+
+ if (group_ctx->opts->schema_type == SDAP_SCHEMA_AD) {
+ ret = sysdb_attrs_get_int32_t(group, SYSDB_GROUP_TYPE, &ad_group_type);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, ("sysdb_attrs_get_int32_t failed.\n"));
+ return ret;
+ }
+
+ DEBUG(SSSDBG_TRACE_ALL, ("AD group has type flags %#x.\n",
+ ad_group_type));
+ /* Only security groups from AD are considered for POSIX groups.
+ * Additionally only global and universal group are taken to account
+ * for trusted domains. */
+ if (!(ad_group_type & SDAP_AD_GROUP_TYPE_SECURITY)
+ || (IS_SUBDOMAIN(group_ctx->domain)
+ && (!((ad_group_type & SDAP_AD_GROUP_TYPE_GLOBAL)
+ || (ad_group_type & SDAP_AD_GROUP_TYPE_UNIVERSAL))))) {
+ posix_group = false;
+ gid = 0;
+ DEBUG(SSSDBG_TRACE_FUNC, ("Filtering AD group.\n"));
+ }
+ }
ret = sysdb_attrs_get_uint32_t(group, map[SDAP_AT_GROUP_GID].sys_name,
&gid);
- if (ret == ENOENT || (ret == EOK && gid == 0)) {
+ if (ret == ENOENT || (ret == EOK && gid == 0) || !posix_group) {
DEBUG(SSSDBG_TRACE_ALL,
("The group's gid was %s\n", ret == ENOENT ? "missing" : "zero"));
DEBUG(SSSDBG_TRACE_INTERNAL,
("Marking group as non-posix and setting GID=0!\n"));
- if (ret == ENOENT) {
+ if (ret == ENOENT || !posix_group) {
ret = sysdb_attrs_add_uint32(group,
map[SDAP_AT_GROUP_GID].sys_name, 0);
if (ret != EOK) {