https://fedorahosted.org/sssd/ticket/1757
When the user entry was missing completely after initgroups, we would never invalidate the user entry from cache. This led to dangling cache entried in memory cache if the user was removed from the server while still being in memory cache.
>From 71cceb360a178497a112b394e20b797885229a0b Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Tue, 15 Jan 2013 07:05:56 +0100 Subject: [PATCH 1/2] NSS: invalidate memcache user entry on initgr, too https://fedorahosted.org/sssd/ticket/1757 When the user entry was missing completely after initgroups, we would never invalidate the user entry from cache. This led to dangling cache entried in memory cache if the user was removed from the server while still being in memory cache. --- src/responder/nss/nsssrv_cmd.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 55543f072bc63093fa2244ce86e6ab60638af9e0..c1d9fc1fb1f5b059a05aa87b560f74d3e32f61be 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -3414,6 +3414,7 @@ void nss_update_initgr_memcache(struct nss_ctx *nctx, TALLOC_CTX *tmp_ctx = NULL; struct sss_domain_info *dom; struct ldb_result *res; + struct sized_string delete_name; bool changed = false; uint32_t id; uint32_t gids[gnum]; @@ -3488,6 +3489,14 @@ void nss_update_initgr_memcache(struct nss_ctx *nctx, } if (changed) { + to_sized_string(&delete_name, name); + ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, &delete_name); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Internal failure in memory cache code: %d [%s]\n", + ret, strerror(ret))); + } + for (i = 0; i < gnum; i++) { id = groups[i]; -- 1.8.0.2
>From fa8701be60cecdc4d6f71cb1880198d14aec0e45 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek <jhro...@redhat.com> Date: Tue, 15 Jan 2013 07:54:03 +0100 Subject: [PATCH 2/2] Invalidate user entry even if there are no groups Related to https://fedorahosted.org/sssd/ticket/1757 Previously we would optimize the mc invalidate code for cases where the user was a member of some groups. But if the user was removed from the server while being in memory cache, we would only invalidate the mc record if he was a member of at least one supplementary group. --- src/providers/data_provider_be.c | 10 +++++----- src/responder/nss/nsssrv_cmd.c | 9 ++------- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c index 5208b48cbc4a15a3f8207a70986af3fd360ec581..fcd766eacdc37ad8914ef40471fe0eea08d2717a 100644 --- a/src/providers/data_provider_be.c +++ b/src/providers/data_provider_be.c @@ -669,9 +669,9 @@ static errno_t be_initgroups_prereq(struct be_req *be_req) if (ret && ret != ENOENT) { return ret; } - /* if the user is completely missing or has no group memberships - * at all there is no need to contact NSS, it would be a noop */ - if (ret == ENOENT || res->count == 0 || res->count == 1) { + /* if the user is completely missing there is no need to contact NSS, + * it would be a noop */ + if (ret == ENOENT || res->count == 0) { /* yet unknown, ignore */ return EOK; } @@ -680,7 +680,7 @@ static errno_t be_initgroups_prereq(struct be_req *be_req) if (!pr) { return ENOMEM; } - pr->groups = talloc_array(pr, gid_t, res->count - 1); + pr->groups = talloc_array(pr, gid_t, res->count); if (!pr->groups) { return ENOMEM; } @@ -696,7 +696,7 @@ static errno_t be_initgroups_prereq(struct be_req *be_req) if (!pr->domain) { return ENOMEM; } - for (pr->gnum = 0, i = 1; i < res->count; i++) { + for (pr->gnum = 0, i = 0; i < res->count; i++) { pr->groups[pr->gnum] = ldb_msg_find_attr_as_uint(res->msgs[i], SYSDB_GIDNUM, 0); /* if 0 it may be a non-posix group, so we skip it */ diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index c1d9fc1fb1f5b059a05aa87b560f74d3e32f61be..04311d5f9c0c65cb7d70e299190b4b7077046206 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -3421,11 +3421,6 @@ void nss_update_initgr_memcache(struct nss_ctx *nctx, int ret; int i, j; - if (gnum == 0) { - /* there are no groups to invalidate in any case, just return */ - return; - } - for (dom = nctx->rctx->domains; dom != NULL; dom = dom->next) { if (strcasecmp(dom->name, domain) == 0) { break; @@ -3462,7 +3457,7 @@ void nss_update_initgr_memcache(struct nss_ctx *nctx, /* probably non-posix group, skip */ continue; } - for (j = 0; j < gnum; j++) { + for (j = 1; j < gnum; j++) { if (gids[j] == id) { gids[j] = 0; break; @@ -3477,7 +3472,7 @@ void nss_update_initgr_memcache(struct nss_ctx *nctx, } if (!changed) { - for (j = 0; j < gnum; j++) { + for (j = 1; j < gnum; j++) { if (gids[j] != 0) { /* we found an un-cleared groups, this means the groups * have changed after the refresh (some got deleted) */ -- 1.8.0.2
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/sssd-devel