[SSSD] [PATCHES] NSS: Clear cached netgroups if a request comes in from the sss_cache

Lukas Slebodnik lslebodn at redhat.com
Tue Jul 30 06:19:53 UTC 2013


ehlo,

Attached patches fix ticket #1759
sss_cache -N/-n should invalidate the hash table in sssd_nss

LS
-------------- next part --------------
>From 1cb2bc71b1fb16d8fb549ae613688b0c86ff9a17 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Mon, 29 Jul 2013 14:45:35 +0200
Subject: [PATCH 1/2] NSS: allow removing entries from netgroup hash table

There is a timed desctructor in the nss responder that, when the
entry timeout passes, removes the netgroup from the hash table while
the netgroup is freed. This patch adds a hash delete callback so that if the
netgroup is removed from the hash table with hash_delete, its hash table
pointer will be invalidated. Later, when the entry is being freed, the
destructor won't attempt to remove it from the hash table.
---
 src/responder/nss/nsssrv.c          |  4 +++-
 src/responder/nss/nsssrv_netgroup.c | 27 +++++++++++++++++++++++++++
 src/responder/nss/nsssrv_netgroup.h |  2 ++
 3 files changed, 32 insertions(+), 1 deletion(-)

diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index ebad15015ac9c164f6c6e8b6e5521de95104d5ed..7bc49e3ef8111ce0fcf6c9f0613e5d93058767d5 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -35,6 +35,7 @@
 #include "responder/nss/nsssrv.h"
 #include "responder/nss/nsssrv_private.h"
 #include "responder/nss/nsssrv_mmap_cache.h"
+#include "responder/nss/nsssrv_netgroup.h"
 #include "responder/common/negcache.h"
 #include "db/sysdb.h"
 #include "confdb/confdb.h"
@@ -477,7 +478,8 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
     }
 
     /* Create the lookup table for netgroup results */
-    hret = sss_hash_create(nctx, 10, &nctx->netgroups);
+    hret = sss_hash_create_ex(nctx, 10, &nctx->netgroups, 0, 0, 0, 0,
+                              netgroup_hash_delete_cb, NULL);
     if (hret != HASH_SUCCESS) {
         DEBUG(0,("Unable to initialize netgroup hash table\n"));
         ret = EIO;
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 12be52bf832cc5315f29b8faac22d4b6c44b3b22..3da7fb535087b0406aa5d18e0e170d6af100f756 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -142,6 +142,12 @@ static int netgr_hash_remove (TALLOC_CTX *ctx)
     struct getent_ctx *netgr =
             talloc_get_type(ctx, struct getent_ctx);
 
+    if (netgr->lookup_table == NULL) {
+        DEBUG(SSSDBG_TRACE_LIBS, ("netgroup [%s] was already removed\n",
+                                  netgr->name));
+        return EOK;
+    }
+
     key.type = HASH_KEY_STRING;
     key.str = netgr->name;
 
@@ -1006,3 +1012,24 @@ int nss_cmd_endnetgrent(struct cli_ctx *client)
     sss_cmd_done(client, NULL);
     return EOK;
 }
+
+void
+netgroup_hash_delete_cb(hash_entry_t *item,
+                        hash_destroy_enum deltype, void *pvt)
+{
+    struct getent_ctx *netgr;
+
+    if (deltype != HASH_ENTRY_DESTROY) {
+        return;
+    }
+
+    netgr = talloc_get_type(item->value.ptr, struct getent_ctx);
+    if (!netgr) {
+        DEBUG(SSSDBG_OP_FAILURE, ("Invalid netgroup\n"));
+        return;
+    }
+
+    /* So that the destructor wouldn't attempt to remove the netgroup from hash
+     * table */
+    netgr->lookup_table = NULL;
+}
diff --git a/src/responder/nss/nsssrv_netgroup.h b/src/responder/nss/nsssrv_netgroup.h
index ed345c43487d852709eef0f1ed55027f09b605fd..a909abed3cdb27f84ead38f32e799375f7f41f62 100644
--- a/src/responder/nss/nsssrv_netgroup.h
+++ b/src/responder/nss/nsssrv_netgroup.h
@@ -31,4 +31,6 @@ int nss_cmd_setnetgrent(struct cli_ctx *cctx);
 int nss_cmd_getnetgrent(struct cli_ctx *cctx);
 int nss_cmd_endnetgrent(struct cli_ctx *cctx);
 
+void netgroup_hash_delete_cb(hash_entry_t *item,
+                             hash_destroy_enum deltype, void *pvt);
 #endif /* NSSRV_NETGROUP_H_ */
-- 
1.8.3.1

-------------- next part --------------
>From 4bd681d0e60ff9868a773f1285f412ac8866b8d7 Mon Sep 17 00:00:00 2001
From: Lukas Slebodnik <lslebodn at redhat.com>
Date: Mon, 29 Jul 2013 15:24:34 +0200
Subject: [PATCH 2/2] NSS: Clear cached netgroups if a request comes in from
 the sss_cache

In order for sss_cache to work correctly, we must also signal the nss
responder to invalidate the hash table requests.

https://fedorahosted.org/sssd/ticket/1759
---
 src/monitor/monitor.c               |  1 +
 src/responder/nss/nsssrv.c          | 21 +++++++++++++++++++++
 src/responder/nss/nsssrv_netgroup.c | 26 ++++++++++++++++++++++++++
 src/responder/nss/nsssrv_netgroup.h |  3 +++
 4 files changed, 51 insertions(+)

diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 8882e4dbda5f579ef14e7c10f93d0285f85fb381..67811ac16f91fa4e6f97ab2cf2ff977855d95751 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -1347,6 +1347,7 @@ static void monitor_hup(struct tevent_context *ev,
         service_signal_rotate(cur_svc);
         if (!strcmp(NSS_SBUS_SERVICE_NAME, cur_svc->name)) {
             service_signal_clear_memcache(cur_svc);
+            service_signal_clear_enum_cache(cur_svc);
         }
 
         if (!strcmp(SSS_AUTOFS_SBUS_SERVICE_NAME, cur_svc->name)) {
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 7bc49e3ef8111ce0fcf6c9f0613e5d93058767d5..253756d1bebb2ecc06740c5e6afff2799de92e1e 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -56,12 +56,15 @@
 
 static int nss_clear_memcache(DBusMessage *message,
                               struct sbus_connection *conn);
+static int nss_clear_netgroup_hash_table(DBusMessage *message,
+                                         struct sbus_connection *conn);
 
 struct sbus_method monitor_nss_methods[] = {
     { MON_CLI_METHOD_PING, monitor_common_pong },
     { MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
     { MON_CLI_METHOD_ROTATE, responder_logrotate },
     { MON_CLI_METHOD_CLEAR_MEMCACHE, nss_clear_memcache},
+    { MON_CLI_METHOD_CLEAR_ENUM_CACHE, nss_clear_netgroup_hash_table},
     { NULL, NULL }
 };
 
@@ -132,6 +135,24 @@ done:
     return monitor_common_pong(message, conn);
 }
 
+static int nss_clear_netgroup_hash_table(DBusMessage *message,
+                                         struct sbus_connection *conn)
+{
+    errno_t ret;
+    struct resp_ctx *rctx = talloc_get_type(sbus_conn_get_private_data(conn),
+                                            struct resp_ctx);
+    struct nss_ctx *nctx = (struct nss_ctx*) rctx->pvt_ctx;
+
+    ret = nss_orphan_netgroups(nctx);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_CRIT_FAILURE,
+              ("Could not invalidate netgroups\n"));
+        return ret;
+    }
+
+    return monitor_common_pong(message, conn);
+}
+
 static errno_t nss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells)
 {
     int i = 0;
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 3da7fb535087b0406aa5d18e0e170d6af100f756..51dd165f1a2a6e2935cc19c9461e6ef27f6bd7f2 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -1033,3 +1033,29 @@ netgroup_hash_delete_cb(hash_entry_t *item,
      * table */
     netgr->lookup_table = NULL;
 }
+
+errno_t nss_orphan_netgroups(struct nss_ctx *nctx) {
+    int hret;
+    unsigned long mcount;
+    unsigned long i;
+    hash_key_t *netgroups;
+
+    if (!nctx || !nctx->netgroups) {
+        return EINVAL;
+    }
+
+    hret = hash_keys(nctx->netgroups, &mcount, &netgroups);
+    if (hret != HASH_SUCCESS) {
+        return EIO;
+    }
+
+    for (i = 0; i < mcount; i++) {
+        hret = hash_delete(nctx->netgroups, &netgroups[i]);
+        if (hret != HASH_SUCCESS) {
+            DEBUG(SSSDBG_MINOR_FAILURE, ("Could not delete key from hash\n"));
+            continue;
+        }
+    }
+
+    return EOK;
+}
diff --git a/src/responder/nss/nsssrv_netgroup.h b/src/responder/nss/nsssrv_netgroup.h
index a909abed3cdb27f84ead38f32e799375f7f41f62..ddeb35df688862a07757a1aeedd3dae2e106c73e 100644
--- a/src/responder/nss/nsssrv_netgroup.h
+++ b/src/responder/nss/nsssrv_netgroup.h
@@ -33,4 +33,7 @@ int nss_cmd_endnetgrent(struct cli_ctx *cctx);
 
 void netgroup_hash_delete_cb(hash_entry_t *item,
                              hash_destroy_enum deltype, void *pvt);
+
+errno_t nss_orphan_netgroups(struct nss_ctx *nctx);
+
 #endif /* NSSRV_NETGROUP_H_ */
-- 
1.8.3.1



More information about the sssd-devel mailing list