diff options
-rw-r--r-- | server/responder/nss/nsssrv.c | 1 | ||||
-rw-r--r-- | server/responder/nss/nsssrv.h | 4 | ||||
-rw-r--r-- | server/responder/nss/nsssrv_cmd.c | 36 |
3 files changed, 39 insertions, 2 deletions
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c index 7c68ba19..248b8a1e 100644 --- a/server/responder/nss/nsssrv.c +++ b/server/responder/nss/nsssrv.c @@ -471,6 +471,7 @@ int nss_process_init(TALLOC_CTX *mem_ctx, return ret; } + nctx->expire_time = 120; /* FIXME: read from conf */ nctx->cache_timeout = 600; /* FIXME: read from conf */ DEBUG(1, ("NSS Initialization complete\n")); diff --git a/server/responder/nss/nsssrv.h b/server/responder/nss/nsssrv.h index 1431dded..e08d8d29 100644 --- a/server/responder/nss/nsssrv.h +++ b/server/responder/nss/nsssrv.h @@ -64,6 +64,10 @@ struct nss_ctx { int cache_timeout; + int expire_time; + time_t last_user_enum; + time_t last_group_enum; + struct sbus_method *sss_sbus_methods; struct sss_cmd_table *sss_cmds; const char *sss_pipe_name; diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c index f14724b9..130b8c66 100644 --- a/server/responder/nss/nsssrv_cmd.c +++ b/server/responder/nss/nsssrv_cmd.c @@ -749,6 +749,9 @@ static void nss_cmd_setpwent_callback(void *ptr, int status, /* do not reply until all domain searches are done */ if (cmdctx->nr) return; + /* set cache mark */ + cctx->nctx->last_user_enum = time(NULL); + if (cmdctx->immediate) { /* this was a getpwent call w/o setpwent, * return immediately one result */ @@ -805,6 +808,8 @@ static int nss_cmd_setpwent_ext(struct cli_ctx *cctx, bool immediate) struct nss_dom_ctx *dctx; struct getent_ctx *gctx; const char **domains; + time_t now = time(NULL); + bool cached = false; int timeout; int i, ret, num; @@ -841,6 +846,13 @@ static int nss_cmd_setpwent_ext(struct cli_ctx *cctx, bool immediate) return ret; } + /* do not query backends if we have a recent enumeration */ + if (cctx->nctx->expire_time) { + if (cctx->nctx->last_user_enum + cctx->nctx->expire_time > now) { + cached = true; + } + } + /* check if enumeration is enabled in any domain */ for (i = 0; i < num; i++) { info = btreemap_get_value(cctx->nctx->domain_map, domains[i]); @@ -858,7 +870,11 @@ static int nss_cmd_setpwent_ext(struct cli_ctx *cctx, bool immediate) dctx->cmdctx = cmdctx; dctx->domain = talloc_strdup(dctx, domains[i]); if (!dctx->domain) return ENOMEM; - dctx->check_provider = strcasecmp(domains[i], "LOCAL"); + if (cached) { + dctx->check_provider = false; + } else { + dctx->check_provider = strcasecmp(domains[i], "LOCAL"); + } dctx->legacy = info->legacy; if (dctx->check_provider) { @@ -1652,6 +1668,9 @@ static void nss_cmd_setgrent_callback(void *ptr, int status, /* do not reply until all domain searches are done */ if (cmdctx->nr) return; + /* set cache mark */ + cctx->nctx->last_group_enum = time(NULL); + if (cmdctx->immediate) { /* this was a getgrent call w/o setgrent, * return immediately one result */ @@ -1707,6 +1726,8 @@ static int nss_cmd_setgrent_ext(struct cli_ctx *cctx, bool immediate) struct nss_dom_ctx *dctx; struct getent_ctx *gctx; const char **domains; + time_t now = time(NULL); + bool cached = false; int timeout; int i, ret, num; @@ -1743,6 +1764,13 @@ static int nss_cmd_setgrent_ext(struct cli_ctx *cctx, bool immediate) return ret; } + /* do not query backends if we have a recent enumeration */ + if (cctx->nctx->expire_time) { + if (cctx->nctx->last_group_enum + cctx->nctx->expire_time > now) { + cached = true; + } + } + /* check if enumeration is enabled in any domain */ for (i = 0; i < num; i++) { info = btreemap_get_value(cctx->nctx->domain_map, domains[i]); @@ -1760,7 +1788,11 @@ static int nss_cmd_setgrent_ext(struct cli_ctx *cctx, bool immediate) dctx->cmdctx = cmdctx; dctx->domain = talloc_strdup(dctx, domains[i]); if (!dctx->domain) return ENOMEM; - dctx->check_provider = strcasecmp(domains[i], "LOCAL"); + if (cached) { + dctx->check_provider = false; + } else { + dctx->check_provider = strcasecmp(domains[i], "LOCAL"); + } dctx->legacy = info->legacy; if (dctx->check_provider) { |