From ebba1aa6b9783daa0d530e9f5e307f7be17d3cd3 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 5 Dec 2012 17:40:43 +0000 Subject: Hook to perform a mmap cache update from sssd_nss This set of functions enumerate each user/group from all domains and invalidate any mmap cache record that matches. --- src/responder/nss/nsssrv_cmd.c | 100 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) (limited to 'src/responder/nss/nsssrv_cmd.c') diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index db1efdd2..2397fb38 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -107,6 +107,56 @@ struct setent_ctx { * PASSWD db related functions ***************************************************************************/ +void nss_update_pw_memcache(struct nss_ctx *nctx) +{ + struct sss_domain_info *dom; + struct ldb_result *res; + uint64_t exp; + struct sized_string key; + const char *id; + time_t now; + int ret; + int i; + + now = time(NULL); + + for (dom = nctx->rctx->domains; dom != NULL; dom = dom->next) { + ret = sysdb_enumpwent(nctx, dom->sysdb, &res); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to enumerate users for domain [%s]\n", dom->name)); + continue; + } + + for (i = 0; i < res->count; i++) { + exp = ldb_msg_find_attr_as_uint64(res->msgs[i], + SYSDB_CACHE_EXPIRE, 0); + if (exp >= now) { + continue; + } + + /* names require more manipulation (build up fqname conditionally), + * but uidNumber is unique and always resolvable too, so we use + * that to update the cache, as it points to the same entry */ + id = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_UIDNUM, NULL); + if (!id) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to find uidNumber in %s.\n", + ldb_dn_get_linearized(res->msgs[i]->dn))); + continue; + } + to_sized_string(&key, id); + + ret = sss_mmap_cache_pw_invalidate(nctx->pwd_mc_ctx, &key); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Internal failure in memory cache code: %d [%s]\n", + ret, strerror(ret))); + } + } + } +} + static gid_t get_gid_override(struct ldb_message *msg, struct sss_domain_info *dom) { @@ -1746,6 +1796,56 @@ done: * GROUP db related functions ***************************************************************************/ +void nss_update_gr_memcache(struct nss_ctx *nctx) +{ + struct sss_domain_info *dom; + struct ldb_result *res; + uint64_t exp; + struct sized_string key; + const char *id; + time_t now; + int ret; + int i; + + now = time(NULL); + + for (dom = nctx->rctx->domains; dom != NULL; dom = dom->next) { + ret = sysdb_enumgrent(nctx, dom->sysdb, &res); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to enumerate users for domain [%s]\n", dom->name)); + continue; + } + + for (i = 0; i < res->count; i++) { + exp = ldb_msg_find_attr_as_uint64(res->msgs[i], + SYSDB_CACHE_EXPIRE, 0); + if (exp >= now) { + continue; + } + + /* names require more manipulation (build up fqname conditionally), + * but uidNumber is unique and always resolvable too, so we use + * that to update the cache, as it points to the same entry */ + id = ldb_msg_find_attr_as_string(res->msgs[i], SYSDB_GIDNUM, NULL); + if (!id) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Failed to find gidNumber in %s.\n", + ldb_dn_get_linearized(res->msgs[i]->dn))); + continue; + } + to_sized_string(&key, id); + + ret = sss_mmap_cache_gr_invalidate(nctx->grp_mc_ctx, &key); + if (ret != EOK && ret != ENOENT) { + DEBUG(SSSDBG_CRIT_FAILURE, + ("Internal failure in memory cache code: %d [%s]\n", + ret, strerror(ret))); + } + } + } +} + #define GID_ROFFSET 0 #define MNUM_ROFFSET sizeof(uint32_t) #define STRS_ROFFSET 2*sizeof(uint32_t) -- cgit