From eb4f8ab8ddd78e3b2efc6130509f035001154ba3 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Wed, 4 Mar 2009 18:22:35 -0500 Subject: Add enumeration backout period. If an enumeration has been requested recently enough, force the nss responder to read from the cache and not go out to each backend and do slow network operations. This greatly improves performances if enumerations are used often. Currently the balcout period is harcoded to 2 min, we will need to make it a configurable option. --- server/responder/nss/nsssrv.c | 1 + server/responder/nss/nsssrv.h | 4 ++++ server/responder/nss/nsssrv_cmd.c | 36 ++++++++++++++++++++++++++++++++++-- 3 files changed, 39 insertions(+), 2 deletions(-) (limited to 'server/responder/nss') 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) { -- cgit