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:36:09 +0100
commitb61518461e08ba0e33ffd6c0c47da709a5757658 (patch)
treeb095f186cffac1873c0f305f63311cdcbf384fd9
parent4c106dc57de95ae1e9b41ec56f6c866d7098bbdf (diff)
downloadsssd-b61518461e08ba0e33ffd6c0c47da709a5757658.tar.gz
sssd-b61518461e08ba0e33ffd6c0c47da709a5757658.tar.xz
sssd-b61518461e08ba0e33ffd6c0c47da709a5757658.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 b42bb541a..d408be0a6 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 9f7e3e55d..33648c5da 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -451,6 +451,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) {
@@ -503,74 +504,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 8e0506831..f1bf77e86 100644
--- a/src/providers/ldap/sdap_async_initgroups_ad.c
+++ b/src/providers/ldap/sdap_async_initgroups_ad.c
@@ -1145,6 +1145,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);
@@ -1175,8 +1176,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,
@@ -1216,7 +1218,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 c107b700b..f58564aec 100644
--- a/src/providers/ldap/sdap_async_nested_groups.c
+++ b/src/providers/ldap/sdap_async_nested_groups.c
@@ -239,15 +239,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) {