[SSSD] [PATCH] NSS: invalidate memcache user entry on initgr, too

Jakub Hrozek jhrozek at redhat.com
Tue Jan 15 08:02:59 UTC 2013


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.
-------------- next part --------------
>From 71cceb360a178497a112b394e20b797885229a0b Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at 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

-------------- next part --------------
>From fa8701be60cecdc4d6f71cb1880198d14aec0e45 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at 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



More information about the sssd-devel mailing list