summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/responder/nss/nsssrv_cmd.c201
1 files changed, 104 insertions, 97 deletions
diff --git a/server/responder/nss/nsssrv_cmd.c b/server/responder/nss/nsssrv_cmd.c
index 8f4f5db8..b2a2035c 100644
--- a/server/responder/nss/nsssrv_cmd.c
+++ b/server/responder/nss/nsssrv_cmd.c
@@ -284,77 +284,88 @@ static errno_t check_cache(struct nss_dom_ctx *dctx,
uint64_t midpoint_refresh;
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) {
- if (res->count == 0) {
- /* This is a cache miss. We need to get the updated user
- * information before returning it.
- */
- call_provider = true;
- cb = callback;
+ bool off_band_update = false;
- } else if ((req_type == SSS_DP_GROUP) ||
- ((req_type == SSS_DP_USER) && (res->count == 1))) {
+ /* when searching for a user, more than one reply is a db error */
+ if ((req_type == SSS_DP_USER) && (res->count > 1)) {
+ DEBUG(1, ("getpwXXX call returned more than one result!"
+ " DB Corrupted?\n"));
+ ret = nss_cmd_send_error(cmdctx, ENOENT);
+ if (ret != EOK) {
+ NSS_CMD_FATAL_ERROR_CODE(cctx, ENOENT);
+ }
+ sss_cmd_done(cctx, cmdctx);
+ return ENOENT;
+ }
- now = time(NULL);
+ /* if we have any reply let's check cache validity */
+ if (res->count > 0) {
- lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0],
- SYSDB_LAST_UPDATE, 0);
- cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
- SYSDB_CACHE_EXPIRE, 0);
+ now = time(NULL);
- midpoint_refresh = 0;
- if(nctx->cache_refresh_percent) {
- midpoint_refresh = lastUpdate +
- (cacheExpire - lastUpdate)*nctx->cache_refresh_percent/100;
- if (midpoint_refresh - lastUpdate < 10) {
- /* If the percentage results in an expiration
- * less than ten seconds after the lastUpdate time,
- * that's too often we will simply set it to 10s
- */
- midpoint_refresh = lastUpdate+10;
- }
- }
+ lastUpdate = ldb_msg_find_attr_as_uint64(res->msgs[0],
+ SYSDB_LAST_UPDATE, 0);
+ cacheExpire = ldb_msg_find_attr_as_uint64(res->msgs[0],
+ SYSDB_CACHE_EXPIRE, 0);
- if (cacheExpire < now) {
- /* This is a cache miss. We need to get the updated user
- * information before returning it.
+ midpoint_refresh = 0;
+ if(nctx->cache_refresh_percent) {
+ midpoint_refresh = lastUpdate +
+ (cacheExpire - lastUpdate)*nctx->cache_refresh_percent/100;
+ if (midpoint_refresh - lastUpdate < 10) {
+ /* If the percentage results in an expiration
+ * less than ten seconds after the lastUpdate time,
+ * that's too often we will simply set it to 10s
*/
- call_provider = true;
- cb = callback;
+ midpoint_refresh = lastUpdate+10;
}
- else if (midpoint_refresh && midpoint_refresh < now) {
+ }
+
+ if (cacheExpire > now) {
+ /* cache still valid */
+
+ if (midpoint_refresh && midpoint_refresh < 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.
*/
- DEBUG(6, ("Performing midpoint cache update on [%s]\n", opt_name));
- call_provider = true;
- cb = NULL;
+ DEBUG(6, ("Performing midpoint cache update on [%s]\n",
+ opt_name));
+ off_band_update = true;
}
else {
+
/* Cache is still valid. Just return it. */
- call_provider = false;
- cb = NULL;
+ return EOK;
}
+ }
+ }
+
+ if (off_band_update) {
+
+ timeout = SSS_CLI_SOCKET_TIMEOUT/2;
+ /* No callback required
+ * This was an out-of-band update. We'll return EOK
+ * so the calling function can return the cached entry
+ * immediately.
+ */
+ ret = sss_dp_send_acct_req(cctx->rctx, NULL, NULL, NULL,
+ timeout, dctx->domain->name,
+ req_type, opt_name, opt_id);
+ if (ret != EOK) {
+ DEBUG(3, ("Failed to dispatch request: %d(%s)\n",
+ ret, strerror(ret)));
} else {
- if (req_type == SSS_DP_USER) {
- DEBUG(1, ("getpwXXX call returned more than one result!"
- " DB Corrupted?\n"));
- }
- ret = nss_cmd_send_error(cmdctx, ENOENT);
- if (ret != EOK) {
- NSS_CMD_FATAL_ERROR_CODE(cctx, ENOENT);
- }
- sss_cmd_done(cctx, cmdctx);
- return ENOENT;
+
+ DEBUG(3, ("Updating cache out-of-band\n"));
}
- }
- if (call_provider) {
+ } else {
+ /* This is a cache miss. Or the cache is expired.
+ * We need to get the updated user information before returning it.
+ */
+
/* dont loop forever :-) */
dctx->check_provider = false;
timeout = SSS_CLI_SOCKET_TIMEOUT/2;
@@ -379,19 +390,7 @@ static errno_t check_cache(struct nss_dom_ctx *dctx,
return EIO;
}
- /* Tell the calling function to return so the dp callback
- * can resolve
- */
- 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 EAGAIN;
}
return EOK;
@@ -426,14 +425,16 @@ static void nss_cmd_getpwnam_callback(void *ptr, int status,
return;
}
- ret = check_cache(dctx, nctx, res,
- SSS_DP_USER, cmdctx->name, 0,
- nss_cmd_getpwnam_dp_callback);
- if (ret != EOK) {
- /* Anything but EOK means we should reenter the mainloop
- * because we may be refreshing the cache
- */
- return;
+ if (dctx->check_provider) {
+ ret = check_cache(dctx, nctx, res,
+ SSS_DP_USER, cmdctx->name, 0,
+ nss_cmd_getpwnam_dp_callback);
+ if (ret != EOK) {
+ /* Anything but EOK means we should reenter the mainloop
+ * because we may be refreshing the cache
+ */
+ return;
+ }
}
switch (res->count) {
@@ -773,14 +774,16 @@ static void nss_cmd_getpwuid_callback(void *ptr, int status,
return;
}
- ret = check_cache(dctx, nctx, res,
- SSS_DP_USER, NULL, cmdctx->id,
- nss_cmd_getpwuid_dp_callback);
- if (ret != EOK) {
- /* Anything but EOK means we should reenter the mainloop
- * because we may be refreshing the cache
- */
- return;
+ if (dctx->check_provider) {
+ ret = check_cache(dctx, nctx, res,
+ SSS_DP_USER, NULL, cmdctx->id,
+ nss_cmd_getpwuid_dp_callback);
+ if (ret != EOK) {
+ /* Anything but EOK means we should reenter the mainloop
+ * because we may be refreshing the cache
+ */
+ return;
+ }
}
switch (res->count) {
@@ -1760,14 +1763,16 @@ static void nss_cmd_getgrnam_callback(void *ptr, int status,
return;
}
- ret = check_cache(dctx, nctx, res,
- SSS_DP_GROUP, cmdctx->name, 0,
- nss_cmd_getgrnam_dp_callback);
- if (ret != EOK) {
- /* Anything but EOK means we should reenter the mainloop
- * because we may be refreshing the cache
- */
- return;
+ if (dctx->check_provider) {
+ ret = check_cache(dctx, nctx, res,
+ SSS_DP_GROUP, cmdctx->name, 0,
+ nss_cmd_getgrnam_dp_callback);
+ if (ret != EOK) {
+ /* Anything but EOK means we should reenter the mainloop
+ * because we may be refreshing the cache
+ */
+ return;
+ }
}
switch (res->count) {
@@ -2103,14 +2108,16 @@ static void nss_cmd_getgrgid_callback(void *ptr, int status,
return;
}
- ret = check_cache(dctx, nctx, res,
- SSS_DP_GROUP, NULL, cmdctx->id,
- nss_cmd_getgrgid_dp_callback);
- if (ret != EOK) {
- /* Anything but EOK means we should reenter the mainloop
- * because we may be refreshing the cache
- */
- return;
+ if (dctx->check_provider) {
+ ret = check_cache(dctx, nctx, res,
+ SSS_DP_GROUP, NULL, cmdctx->id,
+ nss_cmd_getgrgid_dp_callback);
+ if (ret != EOK) {
+ /* Anything but EOK means we should reenter the mainloop
+ * because we may be refreshing the cache
+ */
+ return;
+ }
}
switch (res->count) {