summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/responder/nss/nsssrv.c1
-rw-r--r--server/responder/nss/nsssrv.h4
-rw-r--r--server/responder/nss/nsssrv_cmd.c36
3 files changed, 39 insertions, 2 deletions
diff --git a/server/responder/nss/nsssrv.c b/server/responder/nss/nsssrv.c
index 7c68ba190..248b8a1e7 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 1431ddedd..e08d8d296 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 f14724b9e..130b8c666 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) {