URL: https://github.com/SSSD/sssd/pull/5784 Author: ikerexxe Title: #5784: proxy: allow removing group members Action: synchronized
To pull the PR as Git branch: git remote add ghsssd https://github.com/SSSD/sssd git fetch ghsssd pull/5784/head:pr5784 git checkout pr5784
From be0584db2c5ff898b9833116cfcda0a57a79415b Mon Sep 17 00:00:00 2001 From: Iker Pedrosa <ipedr...@redhat.com> Date: Tue, 14 Sep 2021 12:35:09 +0200 Subject: [PATCH] proxy: allow removing group members The proxy provider doesn't allow to remove group members once they have been added. This patch allows to do it by looping the member list from the cache and comparing it with the actual membership list. If a member is missing then it's removed from the cache. Resolves: https://github.com/SSSD/sssd/issues/5783 Signed-off-by: Iker Pedrosa <ipedr...@redhat.com> --- src/providers/proxy/proxy_id.c | 154 ++++++++++++++++++++++++++++++++- 1 file changed, 152 insertions(+), 2 deletions(-) diff --git a/src/providers/proxy/proxy_id.c b/src/providers/proxy/proxy_id.c index 25daea585d..6196c75020 100644 --- a/src/providers/proxy/proxy_id.c +++ b/src/providers/proxy/proxy_id.c @@ -908,6 +908,10 @@ handle_getgr_result(enum nss_status status, struct group *grp, struct sss_domain_info *dom, bool *delete_group) { + if (delete_group) { + *delete_group = false; + } + switch (status) { case NSS_STATUS_TRYAGAIN: DEBUG(SSSDBG_MINOR_FAILURE, "Buffer too small\n"); @@ -915,7 +919,9 @@ handle_getgr_result(enum nss_status status, struct group *grp, case NSS_STATUS_NOTFOUND: DEBUG(SSSDBG_MINOR_FAILURE, "Group not found.\n"); - *delete_group = true; + if (delete_group) { + *delete_group = true; + } break; case NSS_STATUS_SUCCESS: @@ -927,7 +933,9 @@ handle_getgr_result(enum nss_status status, struct group *grp, if (OUT_OF_ID_RANGE(grp->gr_gid, dom->id_min, dom->id_max)) { DEBUG(SSSDBG_MINOR_FAILURE, "Group filtered out! (id out of range)\n"); - *delete_group = true; + if (delete_group) { + *delete_group = true; + } break; } break; @@ -1488,6 +1496,136 @@ static int get_initgr(TALLOC_CTX *mem_ctx, return ret; } +static int remove_group_members(struct proxy_id_ctx *ctx, + struct sss_domain_info *dom, + const struct passwd *pwd, + long int num_gids, + const gid_t *gids, + long int num_cached_gids, + const gid_t *cached_gids) +{ + TALLOC_CTX *tmp_ctx = NULL; + int i = 0, j = 0; + int ret = EOK; + const char *groupname = NULL; + const char *username = NULL; + bool group_found = false; + struct ldb_result *res = NULL; + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + ret = ENOMEM; + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); + goto done; + } + + username = sss_create_internal_fqname(tmp_ctx, pwd->pw_name, dom->name); + if (username == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "Failed to create fqdn '%s'\n", pwd->pw_name); + ret = ENOMEM; + goto done; + } + + for (i = 0; i < num_cached_gids; i++) { + group_found = false; + /* group 0 is the primary group so it can be skipped */ + for (j = 1; j < num_gids; j++) { + if (cached_gids[i] == gids[j]) { + group_found = true; + break; + } + } + + if (!group_found) { + ret = sysdb_getgrgid(tmp_ctx, dom, cached_gids[i], &res); + if (ret != EOK || res->count != 1) { + DEBUG(SSSDBG_OP_FAILURE, "sysdb_getgrgid failed.\n"); + continue; + } + + groupname = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_NAME, NULL); + if (groupname == NULL) { + DEBUG(SSSDBG_OP_FAILURE, + "Attribute is missing but this should never happen!\n"); + ret = EFAULT; + continue; + } + + ret = sysdb_remove_group_member(dom, groupname, + username, + SYSDB_MEMBER_USER, false); + + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Could not remove member [%s] from group [%s]\n", + username, groupname); + continue; + } + } + } + +done: + return ret; +} + +static int get_cached_user_groups(struct sysdb_ctx *sysdb, + struct sss_domain_info *dom, + const struct passwd *pwd, + unsigned int *_num_cached_gids, + gid_t **_cached_gids) +{ + TALLOC_CTX *tmp_ctx = NULL; + int ret = EOK; + int i = 0, j = 0; + gid_t gid = 0; + gid_t *cached_gids = NULL; + const char *username = NULL; + struct ldb_result *res = NULL; + unsigned int num_cached_gids = 0; + + if (_num_cached_gids == NULL || _cached_gids == NULL) { + return EINVAL; + } + + tmp_ctx = talloc_new(NULL); + if (!tmp_ctx) { + ret = ENOMEM; + DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n"); + goto done; + } + + username = sss_create_internal_fqname(tmp_ctx, pwd->pw_name, dom->name); + if (username == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "Failed to create fqdn '%s'\n", pwd->pw_name); + ret = ENOMEM; + goto done; + } + + ret = sysdb_initgroups(tmp_ctx, dom, username, &res); + /* the first element is the user itself so it can be skipped */ + if (res->count > 1) { + num_cached_gids = res->count - 1; + + cached_gids = talloc_array(tmp_ctx, gid_t, num_cached_gids); + + for (i = 1; i < res->count; i++) { + gid = ldb_msg_find_attr_as_uint(res->msgs[i], SYSDB_GIDNUM, 0); + if (gid != 0) { + cached_gids[j] = gid; + j++; + } + } + } + + *_num_cached_gids = num_cached_gids; + *_cached_gids = talloc_steal(sysdb, cached_gids); + +done: + talloc_zfree(tmp_ctx); + + return ret; +} + static int get_initgr_groups_process(TALLOC_CTX *memctx, struct proxy_id_ctx *ctx, struct sysdb_ctx *sysdb, @@ -1503,6 +1641,8 @@ static int get_initgr_groups_process(TALLOC_CTX *memctx, int ret; int i; time_t now; + gid_t *cached_gids = NULL; + unsigned int num_cached_gids = 0; num_gids = 0; limit = 4096; @@ -1553,6 +1693,16 @@ static int get_initgr_groups_process(TALLOC_CTX *memctx, DEBUG(SSSDBG_CONF_SETTINGS, "User [%s] appears to be member of %lu " "groups\n", pwd->pw_name, num_gids); + ret = get_cached_user_groups(sysdb, dom, pwd, &num_cached_gids, &cached_gids); + if (ret) { + return ret; + } + ret = remove_group_members(ctx, dom, pwd, num_gids, gids, num_cached_gids, cached_gids); + if (ret) { + talloc_free(cached_gids); + return ret; + } + now = time(NULL); for (i = 0; i < num_gids; i++) { ret = get_gr_gid(memctx, ctx, sysdb, dom, gids[i], now);
_______________________________________________ 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