From 7caf7ed4f2eae1ec1c0717b4ee6ce78bdacd5926 Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Tue, 15 Apr 2014 17:24:55 +0200 Subject: RESPONDERS: Add a new request sss_parse_inp_send MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The responders were copying code to parse input and on encountering an uknown domain, send the discover subdomain request. This patch adds a reusable request that can always be called in responders and in case the name can be parsed, just shortcut. Reviewed-by: Pavel Březina --- src/responder/common/responder.h | 7 ++ src/responder/common/responder_get_domains.c | 121 +++++++++++++++++++++++++++ 2 files changed, 128 insertions(+) (limited to 'src/responder/common') diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h index 479cd4c5e..167f45cb1 100644 --- a/src/responder/common/responder.h +++ b/src/responder/common/responder.h @@ -313,4 +313,11 @@ errno_t csv_string_to_uid_array(TALLOC_CTX *mem_ctx, const char *cvs_string, errno_t check_allowed_uids(uid_t uid, size_t allowed_uids_count, uid_t *allowed_uids); + +struct tevent_req * +sss_parse_inp_send(TALLOC_CTX *mem_ctx, struct resp_ctx *rctx, + const char *rawinp); +errno_t sss_parse_inp_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + char **_name, char **_domname); + #endif /* __SSS_RESPONDER_H__ */ 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 : ""); + + /* 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; +} -- cgit