diff options
Diffstat (limited to 'src/responder/common/responder_get_domains.c')
-rw-r--r-- | src/responder/common/responder_get_domains.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/src/responder/common/responder_get_domains.c b/src/responder/common/responder_get_domains.c index e86767f7c..1dbb9ea81 100644 --- a/src/responder/common/responder_get_domains.c +++ b/src/responder/common/responder_get_domains.c @@ -411,3 +411,124 @@ errno_t schedule_get_domains_task(TALLOC_CTX *mem_ctx, return EOK; } + +struct sss_parse_inp_state { + struct resp_ctx *rctx; + const char *rawinp; + + char *name; + char *domname; +}; + +static void sss_parse_inp_done(struct tevent_req *subreq); + +struct tevent_req * +sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, + const char *rawinp) +{ + errno_t ret; + struct tevent_req *req; + struct tevent_req *subreq; + struct sss_parse_inp_state *state; + + req = tevent_req_create(mem_ctx, &state, struct sss_parse_inp_state); + if (req == NULL) { + return NULL; + } + state->rawinp = rawinp; + state->rctx = rctx; + + /* If the subdomains haven't been checked yet, we need to always + * attach to the post-startup subdomain request and only then parse + * the input. Otherwise, we might not be able to parse input with a + * flat domain name specifier */ + if (rctx->get_domains_last_call.tv_sec > 0) { + ret = sss_parse_name_for_domains(state, rctx->domains, + rctx->default_domain, rawinp, + &state->domname, &state->name); + if (ret == EOK) { + /* Was able to use cached domains */ + goto done; + } else if (ret != EAGAIN) { + DEBUG(SSSDBG_OP_FAILURE, "Invalid name received [%s]\n", rawinp); + ret = ERR_INPUT_PARSE; + goto done; + } + } + + /* EAGAIN - check the DP for subdomains */ + + DEBUG(SSSDBG_FUNC_DATA, "Requesting info for [%s] from [%s]\n", + state->name, state->domname ? state->domname : "<ALL>"); + + /* We explicitly use force=false here. This request should decide itself + * if it's time to re-use the cached subdomain list or refresh. If the + * caller needs to specify the 'force' parameter, they should use the + * sss_dp_get_domains_send() request itself + */ + subreq = sss_dp_get_domains_send(state, rctx, false, state->domname); + if (subreq == NULL) { + ret = ENOMEM; + goto done; + } + tevent_req_set_callback(subreq, sss_parse_inp_done, req); + return req; + +done: + if (ret == EOK) { + tevent_req_done(req); + } else { + tevent_req_error(req, ret); + } + tevent_req_post(req, rctx->ev); + return req; +} + +static void sss_parse_inp_done(struct tevent_req *subreq) +{ + errno_t ret; + struct tevent_req *req = tevent_req_callback_data(subreq, + struct tevent_req); + struct sss_parse_inp_state *state = tevent_req_data(req, + struct sss_parse_inp_state); + + ret = sss_dp_get_domains_recv(subreq); + talloc_free(subreq); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + ret = sss_parse_name_for_domains(state, state->rctx->domains, + state->rctx->default_domain, + state->rawinp, + &state->domname, &state->name); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, + "Invalid name received [%s]\n", state->rawinp); + tevent_req_error(req, ERR_INPUT_PARSE); + return; + } + + /* Was able to parse the name now */ + tevent_req_done(req); +} + +errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + char **_name, char **_domname) +{ + struct sss_parse_inp_state *state = tevent_req_data(req, + struct sss_parse_inp_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + if (_name) { + *_name = talloc_steal(mem_ctx, state->name); + } + + if (_domname) { + *_domname = talloc_steal(mem_ctx, state->domname); + } + + return EOK; +} |