From 6eb816852316f878e5c7aaac9b4ec7578621852a Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Mon, 29 Jul 2013 14:45:35 +0200 Subject: 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 17a59b19a..c6ff4f178 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" @@ -453,7 +454,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")); return EIO; diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c index 4b10b1819..d415d81c1 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; @@ -994,3 +1000,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 ed345c434..a909abed3 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_ */ -- cgit