From f280594df77277dbfa56909fbd43c5a9d429aa89 Mon Sep 17 00:00:00 2001
From: Jan Zeleny <jzeleny@redhat.com>
Date: Thu, 31 Mar 2011 08:22:22 -0400
Subject: [PATCH] Don't use negative cache in netgroup lookup

In responder a negative cache is used to indicate that the record has
not been found by previous lookup. This approach is however not
applicable for netgroup lookup because the design of their lookup is a
little different.

This patch removes some pieces of code working with negative cache,
because they didn't fuction well. Instead a new flag has been added to
the positive cache. This flag indicates if the record in the cache
is a record of existing netgroup or it's just a placeholder.

https://fedorahosted.org/sssd/ticket/820
---
 src/responder/nss/nsssrv_netgroup.c |   39 +++++++++++++++++------------------
 src/responder/nss/nsssrv_private.h  |    1 +
 2 files changed, 20 insertions(+), 20 deletions(-)

diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index dbee7f2de811573d5137c6bcdc7967c94a7afd4f..df3823ed2798e6022c07e1c8af630c2cb8a14028 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -231,10 +231,16 @@ static struct tevent_req *setnetgrent_send(TALLOC_CTX *mem_ctx,
          * Check whether it's ready for processing.
          */
         if (state->netgr->ready) {
-            /* Ready to process results */
-            tevent_req_done(req);
-            tevent_req_post(req, nctx->rctx->ev);
-            return req;
+            if (state->netgr->found) {
+                /* Ready to process results */
+                tevent_req_done(req);
+                tevent_req_post(req, nctx->rctx->ev);
+                return req;
+            } else {
+                tevent_req_error(req, ENOENT);
+                tevent_req_post(req, nctx->rctx->ev);
+                return req;
+            }
         }
 
         /* Result object is still being constructed
@@ -387,22 +393,6 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
         /* make sure to update the dctx if we changed domain */
         step_ctx->dctx->domain = dom;
 
-        /* verify this netgroup has not yet been negatively cached */
-        ret = sss_ncache_check_netgr(step_ctx->nctx->ncache,
-                                     step_ctx->nctx->neg_timeout,
-                                     dom->name, step_ctx->name);
-
-        /* if neg cached, return we didn't find it */
-        if (ret == EEXIST) {
-            DEBUG(2, ("Netgroup [%s] does not exist! (negative cache)\n",
-                      step_ctx->name));
-            /* if a multidomain search, try with next */
-            if (step_ctx->check_next) {
-                dom = dom->next;
-                continue;
-            }
-        }
-
         DEBUG(4, ("Requesting info for [%s@%s]\n",
                   step_ctx->name, dom->name));
         ret = sysdb_get_ctx_from_list(step_ctx->rctx->db_list, dom, &sysdb);
@@ -445,6 +435,9 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
                                      &netgr->entries);
         if (ret == ENOENT) {
             /* This netgroup was not found in this domain */
+            DEBUG(2, ("No results for netgroup %s (domain %s)\n",
+                      step_ctx->name, dom->name));
+
             if (!step_ctx->dctx->check_provider) {
                 if (step_ctx->check_next) {
                     dom = dom->next;
@@ -458,6 +451,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
         if (ret != EOK) {
             DEBUG(1, ("Failed to convert results into entries\n"));
             netgr->ready = true;
+            netgr->found = false;
             set_netgr_lifetime(step_ctx->nctx->neg_timeout, step_ctx, netgr);
             return EIO;
         }
@@ -484,6 +478,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
         DEBUG(6, ("Returning info for netgroup [%s@%s]\n",
                   step_ctx->name, dom->name));
         netgr->ready = true;
+        netgr->found = true;
         set_netgr_lifetime(dom->entry_cache_timeout, step_ctx, netgr);
         return EOK;
     }
@@ -497,6 +492,7 @@ static errno_t lookup_netgr_step(struct setent_step_ctx *step_ctx)
         DEBUG(1, ("talloc_zero failed, ignored.\n"));
     } else {
         netgr->ready = true;
+        netgr->found = false;
         netgr->entries = NULL;
         netgr->lookup_table = step_ctx->nctx->netgroups;
         netgr->name = talloc_strdup(netgr, step_ctx->name);
@@ -691,6 +687,9 @@ int nss_cmd_getnetgrent(struct cli_ctx *client)
         tevent_req_set_callback(req, setnetgrent_implicit_done, cmdctx);
 
         return EOK;
+    } else if (!netgr->found) {
+        DEBUG(6, ("Results for [%s] not found.\n", client->netgr_name));
+        return ENOENT;
     }
 
     DEBUG(6, ("Returning results for [%s]\n", client->netgr_name));
diff --git a/src/responder/nss/nsssrv_private.h b/src/responder/nss/nsssrv_private.h
index 52c4ace3a1de5986ef2d3cf48a3ad1c1bf9a977b..27b0e567e488008cccfd283101c32fe3fe483b03 100644
--- a/src/responder/nss/nsssrv_private.h
+++ b/src/responder/nss/nsssrv_private.h
@@ -64,6 +64,7 @@ struct getent_ctx {
     struct sysdb_netgroup_ctx **entries;
     char *name;
     char *domain;
+    bool found;
 };
 
 struct nss_dom_ctx {
-- 
1.7.4.1

