diff options
Diffstat (limited to 'server/responder')
-rw-r--r-- | server/responder/nss/nsssrv.c | 16 | ||||
-rw-r--r-- | server/responder/nss/nsssrv.h | 4 | ||||
-rw-r--r-- | server/responder/nss/nsssrv_cmd.c | 35 |
3 files changed, 53 insertions, 2 deletions
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c index ad804389..3920189a 100644 --- a/server/responder/nss/nsssrv.c +++ b/server/responder/nss/nsssrv.c @@ -107,6 +107,22 @@ static int nss_get_config(struct nss_ctx *nctx, &nctx->filter_users_in_groups); if (ret != EOK) goto done; + + ret = confdb_get_int(cdb, nctx, NSS_SRV_CONFIG, + "EntryCacheNoWaitRefreshTimeout", 0, + &nctx->cache_refresh_timeout); + if (ret != EOK) goto done; + if (nctx->cache_refresh_timeout >= nctx->cache_timeout) { + DEBUG(0,("Configuration error: EntryCacheNoWaitRefreshTimeout exceeds" + "EntryCacheTimeout. Disabling feature.\n")); + nctx->cache_refresh_timeout = 0; + } + if (nctx->cache_refresh_timeout < 0) { + DEBUG(0,("Configuration error: EntryCacheNoWaitRefreshTimeout is" + "invalid. Disabling feature.\n")); + nctx->cache_refresh_timeout = 0; + } + ret = confdb_get_string_as_list(cdb, tmpctx, NSS_SRV_CONFIG, "filterUsers", &filter_list); if (ret == ENOENT) filter_list = NULL; diff --git a/server/responder/nss/nsssrv.h b/server/responder/nss/nsssrv.h index c5a7bb30..a5adbaf8 100644 --- a/server/responder/nss/nsssrv.h +++ b/server/responder/nss/nsssrv.h @@ -46,10 +46,12 @@ struct getent_ctx; struct nss_ctx { struct resp_ctx *rctx; - int cache_timeout; int neg_timeout; struct nss_nc_ctx *ncache; + int cache_timeout; + int cache_refresh_timeout; + int enum_cache_timeout; time_t last_user_enum; time_t last_group_enum; diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c index 3b0f867e..92600933 100644 --- a/server/responder/nss/nsssrv_cmd.c +++ b/server/responder/nss/nsssrv_cmd.c @@ -278,26 +278,50 @@ static errno_t check_cache(struct nss_dom_ctx *dctx, { errno_t ret; int timeout; + int refresh_timeout; time_t now; uint64_t lastUpdate; struct nss_cmd_ctx *cmdctx = dctx->cmdctx; struct cli_ctx *cctx = cmdctx->cctx; bool call_provider = false; + sss_dp_callback_t cb = NULL; if (dctx->check_provider) { switch (res->count) { case 0: + /* This is a cache miss. We need to get the updated user + * information before returning it. + */ call_provider = true; + cb = callback; break; case 1: timeout = nctx->cache_timeout; + refresh_timeout = nctx->cache_refresh_timeout; now = time(NULL); lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_LAST_UPDATE, 0); if (lastUpdate + timeout < now) { + /* This is a cache miss. We need to get the updated user + * information before returning it. + */ call_provider = true; + cb = callback; + } + else if (refresh_timeout && (lastUpdate + refresh_timeout < now)) { + /* We're past the the cache refresh timeout + * We'll return the value from the cache, but we'll also + * queue the cache entry for update out-of-band. + */ + call_provider = true; + cb = NULL; + } + else { + /* Cache is still valid. Just return it. */ + call_provider = false; + cb = NULL; } break; @@ -340,7 +364,16 @@ static errno_t check_cache(struct nss_dom_ctx *dctx, /* Tell the calling function to return so the dp callback * can resolve */ - return EAGAIN; + if (cb) { + return EAGAIN; + } + + /* No callback required + * This was an out-of-band update. We'll return EOK + * so the calling function can return the cached entry + * immediately. + */ + DEBUG(3, ("Updating cache out-of-band\n")); } return EOK; |