summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSimo Sorce <idra@samba.org>2009-01-11 12:17:18 -0500
committerSimo Sorce <idra@samba.org>2009-01-11 12:17:18 -0500
commit28fc5582c207d493a33406222da517a241a157ec (patch)
tree87b4944e91df4b3783da193c58c3e8f5734a5344
parent91dfe750f64cc0d8a970864959767379e0d128db (diff)
downloadsssd-28fc5582c207d493a33406222da517a241a157ec.tar.gz
sssd-28fc5582c207d493a33406222da517a241a157ec.tar.bz2
sssd-28fc5582c207d493a33406222da517a241a157ec.zip
Add caching behavior to nsssrv_cmd.c check cache first and
dispatch to backends only if we have a cache miss.
-rw-r--r--server/nss/nss_ldb.h10
-rw-r--r--server/nss/nsssrv.c2
-rw-r--r--server/nss/nsssrv.h2
-rw-r--r--server/nss/nsssrv_cmd.c88
4 files changed, 82 insertions, 20 deletions
diff --git a/server/nss/nss_ldb.h b/server/nss/nss_ldb.h
index b41c7a67..eee4344f 100644
--- a/server/nss/nss_ldb.h
+++ b/server/nss/nss_ldb.h
@@ -29,13 +29,15 @@
#define NSS_DEF_GR_GIDNUM "gidNumber"
#define NSS_DEF_GR_MEMBER "member"
+#define NSS_DEF_LAST_UPDATE "lastUpdate"
+
#define NSS_DEF_PW_ATTRS {NSS_DEF_PW_NAME, NSS_DEF_PW_UIDNUM, \
NSS_DEF_PW_GIDNUM, NSS_DEF_PW_FULLNAME, \
NSS_DEF_PW_HOMEDIR, NSS_DEF_PW_SHELL, \
- NULL}
-#define NSS_DEF_GRNAM_ATTRS {NSS_DEF_GR_NAME, NSS_DEF_GR_GIDNUM, NULL}
-#define NSS_DEF_GRPW_ATTRS {NSS_DEF_PW_NAME, NULL}
+ NSS_DEF_LAST_UPDATE, NULL}
+#define NSS_DEF_GRNAM_ATTRS {NSS_DEF_GR_NAME, NSS_DEF_GR_GIDNUM, NSS_DEF_LAST_UPDATE, NULL}
+#define NSS_DEF_GRPW_ATTRS {NSS_DEF_PW_NAME, NSS_DEF_LAST_UPDATE, NULL}
#define NSS_DEF_INITGR_ATTR "memberof"
-#define NSS_DEF_INITGR_ATTRS {NSS_DEF_GR_GIDNUM, NULL}
+#define NSS_DEF_INITGR_ATTRS {NSS_DEF_GR_GIDNUM, NSS_DEF_LAST_UPDATE, NULL}
diff --git a/server/nss/nsssrv.c b/server/nss/nsssrv.c
index 5fc707f8..c787637a 100644
--- a/server/nss/nsssrv.c
+++ b/server/nss/nsssrv.c
@@ -439,6 +439,8 @@ int nss_process_init(TALLOC_CTX *mem_ctx,
return ret;
}
+ nctx->cache_timeout = 600; /* FIXME: read from conf */
+
DEBUG(1, ("NSS Initialization complete\n"));
return EOK;
diff --git a/server/nss/nsssrv.h b/server/nss/nsssrv.h
index 51b0f535..faefa7df 100644
--- a/server/nss/nsssrv.h
+++ b/server/nss/nsssrv.h
@@ -48,6 +48,8 @@ struct nss_ctx {
struct service_sbus_ctx *ss_ctx;
struct service_sbus_ctx *dp_ctx;
struct btreemap *domain_map;
+
+ int cache_timeout;
};
struct cli_ctx {
diff --git a/server/nss/nsssrv_cmd.c b/server/nss/nsssrv_cmd.c
index 828bdb78..9347c329 100644
--- a/server/nss/nsssrv_cmd.c
+++ b/server/nss/nsssrv_cmd.c
@@ -24,11 +24,13 @@
#include "util/util.h"
#include "nss/nsssrv.h"
#include "nss/nsssrv_ldb.h"
+#include <time.h>
struct nss_cmd_ctx {
struct cli_ctx *cctx;
const char *name;
uint64_t id;
+ bool check_expiration;
};
struct getent_ctx {
@@ -185,26 +187,45 @@ done:
return EOK;
}
+static void nss_cmd_getpwnam_callback(uint16_t err_maj, uint32_t err_min,
+ const char *err_msg, void *ptr);
+
static void nss_cmd_getpw_callback(void *ptr, int status,
struct ldb_result *res)
{
struct nss_cmd_ctx *nctx = talloc_get_type(ptr, struct nss_cmd_ctx);
struct cli_ctx *cctx = nctx->cctx;
+ int timeout;
+ uint64_t lastUpdate;
uint8_t *body;
size_t blen;
int ret;
- /* create response packet */
- ret = nss_packet_new(cctx->creq, 0,
- nss_packet_get_cmd(cctx->creq->in),
- &cctx->creq->out);
- if (ret != EOK) {
- NSS_CMD_FATAL_ERROR(cctx);
+ if (status != LDB_SUCCESS) {
+ ret = nss_cmd_send_error(nctx, status);
+ if (ret != EOK) {
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+ return;
}
- if (status != LDB_SUCCESS) {
- nss_packet_set_error(cctx->creq->out, status);
- goto done;
+ if (res->count == 0 && nctx->check_expiration) {
+
+ /* dont loop forever :-) */
+ nctx->check_expiration = false;
+
+ ret = nss_dp_send_acct_req(cctx->nctx, nctx,
+ nss_cmd_getpwnam_callback, nctx,
+ SSS_NSS_SOCKET_TIMEOUT/2, "*",
+ NSS_DP_USER, nctx->name, 0);
+ if (ret != EOK) {
+ ret = nss_cmd_send_error(nctx, ret);
+ }
+ if (ret != EOK) {
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+
+ return;
}
if (res->count != 1) {
@@ -226,6 +247,38 @@ static void nss_cmd_getpw_callback(void *ptr, int status,
goto done;
}
+ if (nctx->check_expiration) {
+ timeout = nctx->cctx->nctx->cache_timeout;
+
+ lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0], "lastUpdate", 0);
+ if (lastUpdate + timeout < time(NULL)) {
+
+ /* dont loop forever :-) */
+ nctx->check_expiration = false;
+
+ ret = nss_dp_send_acct_req(cctx->nctx, nctx,
+ nss_cmd_getpwnam_callback, nctx,
+ SSS_NSS_SOCKET_TIMEOUT/2, "*",
+ NSS_DP_USER, nctx->name, 0);
+ if (ret != EOK) {
+ ret = nss_cmd_send_error(nctx, ret);
+ }
+ if (ret != EOK) {
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+
+ return;
+ }
+ }
+
+ /* create response packet */
+ ret = nss_packet_new(cctx->creq, 0,
+ nss_packet_get_cmd(cctx->creq->in),
+ &cctx->creq->out);
+ if (ret != EOK) {
+ NSS_CMD_FATAL_ERROR(cctx);
+ }
+
ret = fill_pwent(cctx->creq->out, cctx->nctx->lctx, res->msgs, res->count);
nss_packet_set_error(cctx->creq->out, ret);
@@ -271,6 +324,7 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
return ENOMEM;
}
nctx->cctx = cctx;
+ nctx->check_expiration = true;
/* get user name to query */
nss_packet_get_body(cctx->creq->in, &body, &blen);
@@ -286,16 +340,18 @@ static int nss_cmd_getpwnam(struct cli_ctx *cctx)
/* FIXME: Just ask all backends for now, until Steve provides for name
* parsing code */
- ret = nss_dp_send_acct_req(cctx->nctx, nctx,
- nss_cmd_getpwnam_callback, nctx,
- SSS_NSS_SOCKET_TIMEOUT/2, "*",
- NSS_DP_USER, nctx->name, 0);
+ ret = nss_ldb_getpwnam(nctx, cctx->ev, cctx->nctx->lctx,
+ nctx->name, nss_cmd_getpw_callback, nctx);
if (ret != EOK) {
- talloc_free(nctx);
- return ret;
+ DEBUG(1, ("Failed to make request to our cache!\n"));
+
+ ret = nss_cmd_send_error(nctx, ret);
+ if (ret != EOK) {
+ return ret;
+ }
}
- return ret;
+ return EOK;
}
static int nss_cmd_getpwuid(struct cli_ctx *cctx)