From e87b2a6e94c1066b3044fe683825ff5b4f8716c2 Mon Sep 17 00:00:00 2001 From: Pavel Březina Date: Tue, 27 Jan 2015 14:01:08 +0100 Subject: cache_req: parse input name if needed The input name is now parse automatically by cache_req if none particullar domain is specified. The parsed named is returned from _recv as an output parameter. Reviewed-by: Jakub Hrozek --- src/responder/common/responder_cache_req.c | 123 +++++++++++++++++++++++++---- src/responder/common/responder_cache_req.h | 19 ++--- src/responder/ifp/ifpsrv_cmd.c | 2 +- 3 files changed, 119 insertions(+), 25 deletions(-) (limited to 'src/responder') diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c index ed5c7a249..57cb3a811 100644 --- a/src/responder/common/responder_cache_req.c +++ b/src/responder/common/responder_cache_req.c @@ -117,6 +117,23 @@ fail: return NULL; } +static errno_t +cache_req_input_set_orig_name(struct cache_req_input *input, + const char *name) +{ + const char *dup; + + dup = talloc_strdup(input, name); + if (dup == NULL) { + return ENOMEM; + } + + talloc_zfree(input->orig_name); + input->orig_name = dup; + + return EOK; +} + static errno_t cache_req_input_set_domain(struct cache_req_input *input, struct sss_domain_info *domain, @@ -595,7 +612,13 @@ struct cache_req_state { bool check_next; }; +static void cache_req_input_parsed(struct tevent_req *subreq); + +static errno_t cache_req_select_domains(struct tevent_req *req, + const char *domain); + static errno_t cache_req_next_domain(struct tevent_req *req); + static void cache_req_done(struct tevent_req *subreq); struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx, @@ -609,6 +632,7 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx, { struct cache_req_state *state = NULL; struct tevent_req *req = NULL; + struct tevent_req *subreq = NULL; errno_t ret; req = tevent_req_create(mem_ctx, &state, struct cache_req_state); @@ -624,24 +648,20 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx, state->cache_refresh_percent = cache_refresh_percent; state->input = input; - if (domain != NULL) { - /* single-domain search */ - state->domain = responder_get_domain(state->rctx, domain); - if (state->domain == NULL) { - ret = EINVAL; + if (state->input->orig_name != NULL && domain == NULL) { + /* Parse input name first, since it may contain domain name. */ + subreq = sss_parse_inp_send(state, rctx, input->orig_name); + if (subreq == NULL) { + ret = ENOMEM; goto immediately; } - state->check_next = false; + tevent_req_set_callback(subreq, cache_req_input_parsed, req); } else { - /* multi-domain search */ - state->domain = state->rctx->domains; - state->check_next = true; - } - - ret = cache_req_next_domain(req); - if (ret != EAGAIN) { - goto immediately; + ret = cache_req_select_domains(req, domain); + if (ret != EAGAIN) { + goto immediately; + } } return req; @@ -657,6 +677,63 @@ immediately: return req; } +static void cache_req_input_parsed(struct tevent_req *subreq) +{ + struct tevent_req *req; + struct cache_req_state *state; + char *name; + char *domain; + errno_t ret; + + req = tevent_req_callback_data(subreq, struct tevent_req); + state = tevent_req_data(req, struct cache_req_state); + + ret = sss_parse_inp_recv(subreq, state, &name, &domain); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + + if (strcmp(name, state->input->orig_name) != 0) { + /* The name has changed during input parse phase. */ + ret = cache_req_input_set_orig_name(state->input, name); + if (ret != EOK) { + tevent_req_error(req, ret); + return; + } + } + + ret = cache_req_select_domains(req, domain); + if (ret != EAGAIN) { + tevent_req_error(req, ret); + return; + } +} + +static errno_t cache_req_select_domains(struct tevent_req *req, + const char *domain) +{ + struct cache_req_state *state = NULL; + + state = tevent_req_data(req, struct cache_req_state); + + if (domain != NULL) { + /* single-domain search */ + state->domain = responder_get_domain(state->rctx, domain); + if (state->domain == NULL) { + return ERR_DOMAIN_NOT_FOUND; + } + + state->check_next = false; + } else { + /* multi-domain search */ + state->domain = state->rctx->domains; + state->check_next = true; + } + + return cache_req_next_domain(req); +} + static errno_t cache_req_next_domain(struct tevent_req *req) { struct cache_req_state *state = NULL; @@ -744,13 +821,29 @@ static void cache_req_done(struct tevent_req *subreq) errno_t cache_req_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **_result, - struct sss_domain_info **_domain) + struct sss_domain_info **_domain, + char **_name) { struct cache_req_state *state = NULL; + char *name; + state = tevent_req_data(req, struct cache_req_state); TEVENT_REQ_RETURN_ON_ERROR(req); + if (_name != NULL) { + if (state->input->dom_objname == NULL) { + *_name = NULL; + } else { + name = talloc_strdup(mem_ctx, state->input->orig_name); + if (name == NULL) { + return ENOMEM; + } + + *_name = name; + } + } + if (_result != NULL) { *_result = talloc_steal(mem_ctx, state->result); } diff --git a/src/responder/common/responder_cache_req.h b/src/responder/common/responder_cache_req.h index 3b8f3f713..088e8efe0 100644 --- a/src/responder/common/responder_cache_req.h +++ b/src/responder/common/responder_cache_req.h @@ -60,7 +60,8 @@ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx, errno_t cache_req_recv(TALLOC_CTX *mem_ctx, struct tevent_req *req, struct ldb_result **_result, - struct sss_domain_info **_domain); + struct sss_domain_info **_domain, + char **_name); struct tevent_req * cache_req_user_by_name_send(TALLOC_CTX *mem_ctx, @@ -72,8 +73,8 @@ cache_req_user_by_name_send(TALLOC_CTX *mem_ctx, const char *domain, const char *name); -#define cache_req_user_by_name_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain) +#define cache_req_user_by_name_recv(mem_ctx, req, _result, _domain, _name) \ + cache_req_recv(mem_ctx, req, _result, _domain, _name) struct tevent_req * cache_req_user_by_id_send(TALLOC_CTX *mem_ctx, @@ -86,7 +87,7 @@ cache_req_user_by_id_send(TALLOC_CTX *mem_ctx, uid_t uid); #define cache_req_user_by_id_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain) + cache_req_recv(mem_ctx, req, _result, _domain, NULL) struct tevent_req * cache_req_group_by_name_send(TALLOC_CTX *mem_ctx, @@ -98,8 +99,8 @@ cache_req_group_by_name_send(TALLOC_CTX *mem_ctx, const char *domain, const char *name); -#define cache_req_group_by_name_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain) +#define cache_req_group_by_name_recv(mem_ctx, req, _result, _domain, _name) \ + cache_req_recv(mem_ctx, req, _result, _domain, _name) struct tevent_req * cache_req_group_by_id_send(TALLOC_CTX *mem_ctx, @@ -112,7 +113,7 @@ cache_req_group_by_id_send(TALLOC_CTX *mem_ctx, gid_t gid); #define cache_req_group_by_id_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain) + cache_req_recv(mem_ctx, req, _result, _domain, NULL) struct tevent_req * cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx, @@ -124,7 +125,7 @@ cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx, const char *domain, const char *name); -#define cache_req_initgr_by_name_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain) +#define cache_req_initgr_by_name_recv(mem_ctx, req, _result, _domain, _name) \ + cache_req_recv(mem_ctx, req, _result, _domain, _name) #endif /* RESPONDER_CACHE_H_ */ diff --git a/src/responder/ifp/ifpsrv_cmd.c b/src/responder/ifp/ifpsrv_cmd.c index 0a4bd0530..a2e9d8205 100644 --- a/src/responder/ifp/ifpsrv_cmd.c +++ b/src/responder/ifp/ifpsrv_cmd.c @@ -532,7 +532,7 @@ static void ifp_user_get_attr_done(struct tevent_req *subreq) req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct ifp_user_get_attr_state); - ret = cache_req_recv(state, subreq, &state->res, &state->dom); + ret = cache_req_recv(state, subreq, &state->res, &state->dom, NULL); talloc_zfree(subreq); if (ret != EOK) { tevent_req_error(req, ret); -- cgit