From c28d61203655dd41cd8eb69752e435d3241e63b2 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 3 Oct 2017 12:34:49 +0200 Subject: [PATCH 06/21] SDAP: Allow the mpg flag for the main domain MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This commit allows saving the users in the MPG domain in the SDAP layer. The commit contains the following changes: - abstracts the change where if the primary GID exists in the original object, it is saved instead as the SYSDB_PRIMARY_GROUP_GIDNUM attribute, which will allow the original primary GID to be exposed as a secondary group - if the primary GID does not exist, no SYSDB_PRIMARY_GROUP_GIDNUM is added. This will allow to handle LDAP objects that only contain the UID but no GID. Since this is a new use-case, a test is added later - a branch that handles the above is added to sdap_save_user() also for joined domains that set the MPG flag. Previously, only subdomains were handled. - to allow passing GID=0 to the sysdb layer, the range check is relaxed. Related: https://pagure.io/SSSD/sssd/issue/1872 Reviewed-by: Fabiano Fidêncio Reviewed-by: Pavel Březina (cherry picked from commit cdb74b2cc6cc3fe52969712907c9eb4026c7a44f) --- src/providers/ldap/sdap_async_users.c | 83 +++++++++++++++++++++++++++++++---- 1 file changed, 75 insertions(+), 8 deletions(-) diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c index 09d096e84cac6c9d52bcde0e1587c47dbd88b504..7338b4a15694b1d0a16723990130a23a7280af5f 100644 --- a/src/providers/ldap/sdap_async_users.c +++ b/src/providers/ldap/sdap_async_users.c @@ -136,6 +136,38 @@ static errno_t sdap_set_non_posix_flag(struct sysdb_attrs *attrs, return EOK; } +static int sdap_user_set_mpg(struct sysdb_attrs *user_attrs, + gid_t *_gid) +{ + errno_t ret; + + if (_gid == NULL) { + return EINVAL; + } + + if (*_gid == 0) { + /* The original entry had no GID number. This is OK, we just won't add + * the SYSDB_PRIMARY_GROUP_GIDNUM attribute + */ + return EOK; + } + + ret = sysdb_attrs_add_uint32(user_attrs, + SYSDB_PRIMARY_GROUP_GIDNUM, + (uint32_t) *_gid); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n"); + return ret; + } + + /* We won't really store gidNumber=0, but the zero value tells + * the sysdb layer that no GID is set, which sysdb requires for + * MPG-enabled domains + */ + *_gid = 0; + return EOK; +} + /* FIXME: support storing additional attributes */ int sdap_save_user(TALLOC_CTX *memctx, struct sdap_options *opts, @@ -357,7 +389,7 @@ int sdap_save_user(TALLOC_CTX *memctx, goto done; } - if (IS_SUBDOMAIN(dom)) { + if (IS_SUBDOMAIN(dom) || dom->mpg == true) { /* For subdomain users, only create the private group as * the subdomain is an MPG domain. * But we have to save the GID of the original primary group @@ -365,14 +397,13 @@ int sdap_save_user(TALLOC_CTX *memctx, * typically (Unix and AD) the user is not listed in his primary * group as a member. */ - ret = sysdb_attrs_add_uint32(user_attrs, SYSDB_PRIMARY_GROUP_GIDNUM, - (uint32_t) gid); + ret = sdap_user_set_mpg(user_attrs, &gid); if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "sysdb_attrs_add_uint32 failed.\n"); + DEBUG(SSSDBG_OP_FAILURE, + "sdap_user_set_mpg failed [%d]: %s\n", ret, + sss_strerror(ret)); goto done; } - - gid = 0; } /* Store the GID in the ldap_attrs so it doesn't get @@ -380,6 +411,41 @@ int sdap_save_user(TALLOC_CTX *memctx, */ ret = sysdb_attrs_add_uint32(attrs, SYSDB_GIDNUM, gid); if (ret != EOK) goto done; + } else if (dom->mpg) { + /* Likewise, if a domain is set to contain 'magic private groups', do + * not process the real GID, but save it in the cache as originalGID + * (if available) + */ + ret = sysdb_attrs_get_uint32_t(attrs, + opts->user_map[SDAP_AT_USER_GID].sys_name, + &gid); + if (ret == ENOENT) { + DEBUG(SSSDBG_TRACE_LIBS, + "Missing GID, won't save the %s attribute\n", + SYSDB_PRIMARY_GROUP_GIDNUM); + + /* Store the UID as GID (since we're in a MPG domain so that it doesn't + * get treated as a missing attribute and removed + */ + ret = sdap_replace_id(attrs, SYSDB_GIDNUM, uid); + if (ret) { + DEBUG(SSSDBG_OP_FAILURE, "Cannot set the id-mapped UID\n"); + goto done; + } + gid = 0; + } else if (ret != EOK) { + DEBUG(SSSDBG_MINOR_FAILURE, + "Cannot retrieve GID, won't save the %s attribute\n", + SYSDB_PRIMARY_GROUP_GIDNUM); + gid = 0; + } + + ret = sdap_user_set_mpg(user_attrs, &gid); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "sdap_user_set_mpg failed [%d]: %s\n", ret, sss_strerror(ret)); + goto done; + } } else { ret = sysdb_attrs_get_uint32_t(attrs, opts->user_map[SDAP_AT_USER_GID].sys_name, @@ -403,8 +469,9 @@ int sdap_save_user(TALLOC_CTX *memctx, } /* check that the gid is valid for this domain */ - if (is_posix == true && IS_SUBDOMAIN(dom) == false && - OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) { + if (is_posix == true && IS_SUBDOMAIN(dom) == false + && dom->mpg == false + && OUT_OF_ID_RANGE(gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_CRIT_FAILURE, "User [%s] filtered out! (primary gid out of range)\n", user_name); -- 2.13.5