summaryrefslogtreecommitdiffstats
path: root/server/responder
diff options
context:
space:
mode:
Diffstat (limited to 'server/responder')
-rw-r--r--server/responder/nss/nsssrv.c16
-rw-r--r--server/responder/nss/nsssrv.h4
-rw-r--r--server/responder/nss/nsssrv_cmd.c35
3 files changed, 53 insertions, 2 deletions
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index ad8043890..3920189af 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 c5a7bb301..a5adbaf83 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 3b0f867e2..926009335 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;