From f829604a8e7ca5a77bfac5834ca32bb465dd6538 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Mon, 3 Jan 2011 16:43:08 +0100 Subject: [PATCH 2/3] Post setgrent requests if necessary --- src/responder/nss/nsssrv_cmd.c | 122 ++++++++++++++++++++++++++---------- src/responder/nss/nsssrv_private.h | 1 + 2 files changed, 89 insertions(+), 34 deletions(-) diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c index 2decf84..ea89a9d 100644 --- a/src/responder/nss/nsssrv_cmd.c +++ b/src/responder/nss/nsssrv_cmd.c @@ -1025,8 +1025,7 @@ struct tevent_req *nss_cmd_setpwent_send(TALLOC_CTX *mem_ctx, goto error; } - state->dctx->check_provider = - NEED_CHECK_PROVIDER(state->dctx->domain->provider); + state->dctx->check_provider = true; /* Is the result context already available */ if (state->nctx->pctx) { @@ -1081,6 +1080,7 @@ struct tevent_req *nss_cmd_setpwent_send(TALLOC_CTX *mem_ctx, step_ctx->getent_ctx = state->getent_ctx; step_ctx->rctx = client->rctx; step_ctx->enum_cached = enum_cached; + step_ctx->cmd = SSS_NSS_SETPWENT; ret = nss_cmd_setpwent_step(step_ctx); if (ret != EOK) goto error; @@ -1099,6 +1099,11 @@ static void setpwent_result_timeout(struct tevent_context *ev, struct tevent_timer *te, struct timeval current_time, void *pvt); +static void no_provider_check_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data); + static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx) { errno_t ret; @@ -1124,11 +1129,7 @@ static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx) if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ - if (step_ctx->enum_cached) { - dctx->check_provider = false; - } else { - dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); - } + dctx->check_provider = true; } /* make sure to update the dctx if we changed domain */ @@ -1147,18 +1148,30 @@ static errno_t nss_cmd_setpwent_step(struct setent_step_ctx *step_ctx) if (dctx->check_provider) { /* Only do this once per provider */ dctx->check_provider = false; - timeout = SSS_CLI_SOCKET_TIMEOUT; - ret = sss_dp_send_acct_req(rctx, step_ctx, - nss_cmd_setpwent_dp_callback, step_ctx, - timeout, dom->name, true, - SSS_DP_USER, NULL, 0); - if (ret == EOK) { - return ret; + if (NEED_CHECK_PROVIDER(dom->provider)) { + timeout = SSS_CLI_SOCKET_TIMEOUT; + + ret = sss_dp_send_acct_req(rctx, step_ctx, + nss_cmd_setpwent_dp_callback, + step_ctx, timeout, dom->name, true, + SSS_DP_USER, NULL, 0); + if (ret == EOK) { + return ret; + } else { + DEBUG(2, ("Enum Cache refresh for domain [%s] failed." + " Trying to return what we have in cache!\n", + dom->name)); + } } else { - DEBUG(2, ("Enum Cache refresh for domain [%s] failed." - " Trying to return what we have in cache!\n", - dom->name)); + tv = tevent_timeval_current(); + te = tevent_add_timer(rctx->ev, step_ctx, tv, + no_provider_check_handler, step_ctx); + if (te == NULL) { + return ENOMEM; + } + + return EOK; } } @@ -2278,8 +2291,7 @@ struct tevent_req *nss_cmd_setgrent_send(TALLOC_CTX *mem_ctx, goto error; } - state->dctx->check_provider = - NEED_CHECK_PROVIDER(state->dctx->domain->provider); + state->dctx->check_provider = true; /* Is the result context already available */ if (state->nctx->gctx) { @@ -2334,6 +2346,7 @@ struct tevent_req *nss_cmd_setgrent_send(TALLOC_CTX *mem_ctx, step_ctx->getent_ctx = state->getent_ctx; step_ctx->rctx = client->rctx; step_ctx->enum_cached = enum_cached; + step_ctx->cmd = SSS_NSS_SETGRENT; ret = nss_cmd_setgrent_step(step_ctx); if (ret != EOK) goto error; @@ -2377,11 +2390,7 @@ static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx) if (dom != dctx->domain) { /* make sure we reset the check_provider flag when we check * a new domain */ - if (step_ctx->enum_cached) { - dctx->check_provider = false; - } else { - dctx->check_provider = NEED_CHECK_PROVIDER(dom->provider); - } + dctx->check_provider = true; } /* make sure to update the dctx if we changed domain */ @@ -2400,18 +2409,30 @@ static errno_t nss_cmd_setgrent_step(struct setent_step_ctx *step_ctx) if (dctx->check_provider) { /* Only do this once per provider */ dctx->check_provider = false; - timeout = SSS_CLI_SOCKET_TIMEOUT; - ret = sss_dp_send_acct_req(rctx, step_ctx, - nss_cmd_setgrent_dp_callback, step_ctx, - timeout, dom->name, true, - SSS_DP_GROUP, NULL, 0); - if (ret == EOK) { - return ret; + if (NEED_CHECK_PROVIDER(dom->provider)) { + timeout = SSS_CLI_SOCKET_TIMEOUT; + + ret = sss_dp_send_acct_req(rctx, step_ctx, + nss_cmd_setgrent_dp_callback, + step_ctx, timeout, dom->name, true, + SSS_DP_GROUP, NULL, 0); + if (ret == EOK) { + return ret; + } else { + DEBUG(2, ("Enum Cache refresh for domain [%s] failed." + " Trying to return what we have in cache!\n", + dom->name)); + } } else { - DEBUG(2, ("Enum Cache refresh for domain [%s] failed." - " Trying to return what we have in cache!\n", - dom->name)); + tv = tevent_timeval_current(); + te = tevent_add_timer(rctx->ev, step_ctx, tv, + no_provider_check_handler, step_ctx); + if (te == NULL) { + return ENOMEM; + } + + return EOK; } } @@ -2545,6 +2566,39 @@ static void nss_cmd_setgrent_done(struct tevent_req *req) nss_cmd_done(cmdctx, ret); } +static void no_provider_check_handler(struct tevent_context *ev, + struct tevent_timer *te, + struct timeval current_time, + void *private_data) +{ + struct setent_step_ctx *step_ctx = talloc_get_type(private_data, + struct setent_step_ctx); + int ret; + + switch (step_ctx->cmd) { + case SSS_NSS_SETPWENT: + DEBUG(9, ("Calling nss_cmd_setpwent_step again.\n")); + ret = nss_cmd_setpwent_step(step_ctx); + break; + case SSS_NSS_SETGRENT: + DEBUG(9, ("Calling nss_cmd_setgrent_step again.\n")); + ret = nss_cmd_setgrent_step(step_ctx); + break; + default: + DEBUG(1, ("Unexpected nss command.\n")) + return; + } + + if (ret) { + /* Notify any waiting processes of failure */ + while(step_ctx->nctx->pctx->reqs) { + tevent_req_error(step_ctx->nctx->pctx->reqs->req, ret); + /* Freeing each entry in the list removes it from the dlist */ + talloc_free(step_ctx->nctx->pctx->reqs); + } + } +} + static int nss_cmd_retgrent(struct cli_ctx *cctx, int num) { struct nss_ctx *nctx; diff --git a/src/responder/nss/nsssrv_private.h b/src/responder/nss/nsssrv_private.h index 4d9f947..be65877 100644 --- a/src/responder/nss/nsssrv_private.h +++ b/src/responder/nss/nsssrv_private.h @@ -86,6 +86,7 @@ struct setent_step_ctx { struct resp_ctx *rctx; bool enum_cached; bool check_next; + enum sss_cli_command cmd; /* Netgroup-specific */ char *name; -- 1.7.3.3