diff options
| author | Pavel Březina <pbrezina@redhat.com> | 2016-10-14 12:15:50 +0200 |
|---|---|---|
| committer | Lukas Slebodnik <lslebodn@redhat.com> | 2016-12-19 23:22:54 +0100 |
| commit | b206e1abb7f6ea373d12537b3338552aed6b656d (patch) | |
| tree | 7ac5b5d24dbeee268bbdb6d26f19586b84ed8cdb /src/responder/common/cache_req | |
| parent | f63607bfcc01ad426efa20ed8ec65f429c9b2bd6 (diff) | |
| download | sssd-b206e1abb7f6ea373d12537b3338552aed6b656d.tar.gz sssd-b206e1abb7f6ea373d12537b3338552aed6b656d.tar.xz sssd-b206e1abb7f6ea373d12537b3338552aed6b656d.zip | |
cache_req: encapsulate output data into structure
In enumeration calls we want to get objects from all domains, not
only from the first matched domain. We move the cache search result
into a structure that contains combination of domain and ldb_result.
This is preparation for enumeration support inside cache_req.
Resolves:
https://fedorahosted.org/sssd/ticket/3151
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
Diffstat (limited to 'src/responder/common/cache_req')
| -rw-r--r-- | src/responder/common/cache_req/cache_req.c | 152 | ||||
| -rw-r--r-- | src/responder/common/cache_req/cache_req.h | 71 | ||||
| -rw-r--r-- | src/responder/common/cache_req/cache_req_private.h | 6 |
3 files changed, 179 insertions, 50 deletions
diff --git a/src/responder/common/cache_req/cache_req.c b/src/responder/common/cache_req/cache_req.c index 21ac8204b..e71a59a25 100644 --- a/src/responder/common/cache_req/cache_req.c +++ b/src/responder/common/cache_req/cache_req.c @@ -256,9 +256,10 @@ struct cache_req_state { struct cache_req *cr; /* work data */ - struct ldb_result *result; struct sss_domain_info *domain; struct sss_domain_info *selected_domain; + struct cache_req_result **results; + size_t num_results; bool check_next; }; @@ -479,21 +480,73 @@ static errno_t cache_req_next_domain(struct tevent_req *req) return ENOENT; } +static errno_t +cache_req_add_result(struct cache_req_state *state, + struct cache_req_result *new) +{ + struct cache_req_result **results = state->results; + size_t index; + size_t count; + + /* Make space for new results. */ + index = state->num_results; + count = state->num_results + 1; + + results = talloc_realloc(state, results, struct cache_req_result *, count + 1); + if (results == NULL) { + return ENOMEM; + } + + results[index] = talloc_steal(results, new); + results[index + 1] = NULL; + state->results = results; + state->num_results = count; + + return EOK; +} + +static errno_t +cache_req_create_and_add_result(struct cache_req_state *state, + struct sss_domain_info *domain, + struct ldb_result *ldb_result, + const char *name) +{ + struct cache_req_result *item; + errno_t ret; + + CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, + "Found %u entries in domain %s\n", + ldb_result->count, domain->name); + + item = cache_req_create_result(state, domain, ldb_result, name); + if (item == NULL) { + return ENOMEM; + } + + ret = cache_req_add_result(state, item); + if (ret != EOK) { + talloc_free(item); + } + + return ret; +} + static void cache_req_done(struct tevent_req *subreq) { struct cache_req_state *state; + struct ldb_result *result; struct tevent_req *req; errno_t ret; req = tevent_req_callback_data(subreq, struct tevent_req); state = tevent_req_data(req, struct cache_req_state); - ret = cache_req_search_recv(state, subreq, &state->result); + ret = cache_req_search_recv(state, subreq, &result); talloc_zfree(subreq); if (ret == EOK) { - CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Success\n"); - tevent_req_done(req); - return; + ret = cache_req_create_and_add_result(state, state->selected_domain, + result, state->cr->data->name.lookup); + goto done; } if (state->check_next == false) { @@ -503,16 +556,31 @@ static void cache_req_done(struct tevent_req *subreq) return; } - CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Not found\n"); - tevent_req_error(req, ret); - return; + goto done; } ret = cache_req_next_domain(req); if (ret != EAGAIN) { + goto done; + } + + return; + +done: + switch (ret) { + case EOK: + CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Success\n"); + tevent_req_done(req); + break; + case ENOENT: + CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Not found\n"); + tevent_req_error(req, ret); + break; + default: CACHE_REQ_DEBUG(SSSDBG_TRACE_FUNC, state->cr, "Finished: Error %d: %s\n", ret, sss_strerror(ret)); tevent_req_error(req, ret); + break; } return; @@ -520,36 +588,33 @@ 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, - char **_name) + struct cache_req_result ***_results) { - struct cache_req_state *state = NULL; - char *name; + struct cache_req_state *state; state = tevent_req_data(req, struct cache_req_state); TEVENT_REQ_RETURN_ON_ERROR(req); - if (_name != NULL) { - if (state->cr->data->name.lookup == NULL) { - *_name = NULL; - } else { - name = talloc_strdup(mem_ctx, state->cr->data->name.lookup); - if (name == NULL) { - return ENOMEM; - } - - *_name = name; - } + if (_results != NULL) { + *_results = talloc_steal(mem_ctx, state->results); } - if (_result != NULL) { - *_result = talloc_steal(mem_ctx, state->result); - } + return EOK; +} - if (_domain != NULL) { - *_domain = state->selected_domain; +errno_t cache_req_single_domain_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + struct cache_req_result **_result) +{ + struct cache_req_state *state; + + state = tevent_req_data(req, struct cache_req_state); + + TEVENT_REQ_RETURN_ON_ERROR(req); + + if (_result != NULL) { + *_result = talloc_steal(mem_ctx, state->results[0]); } return EOK; @@ -577,3 +642,32 @@ cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx, return req; } + +struct cache_req_result * +cache_req_create_result(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_result *ldb_result, + const char *lookup_name) +{ + struct cache_req_result *result; + + result = talloc_zero(mem_ctx, struct cache_req_result); + if (result == NULL) { + return NULL; + } + + result->domain = domain; + result->ldb_result = talloc_steal(result, ldb_result); + result->count = ldb_result != NULL ? ldb_result->count : 0; + result->msgs = ldb_result != NULL ? ldb_result->msgs : NULL; + + if (lookup_name != NULL) { + result->lookup_name = talloc_strdup(result, lookup_name); + if (result->lookup_name == NULL) { + talloc_free(result); + return NULL; + } + } + + return result; +} diff --git a/src/responder/common/cache_req/cache_req.h b/src/responder/common/cache_req/cache_req.h index d220c5133..54cb8ad1a 100644 --- a/src/responder/common/cache_req/cache_req.h +++ b/src/responder/common/cache_req/cache_req.h @@ -69,6 +69,33 @@ cache_req_data_sid(TALLOC_CTX *mem_ctx, const char *sid, const char **attrs); +/* Output data. */ + +struct cache_req_result { + /** + * SSSD domain where the result was obtained. + */ + struct sss_domain_info *domain; + + /** + * Result from ldb lookup. + */ + struct ldb_result *ldb_result; + + /** + * Shortcuts into ldb_result. This shortens the code a little since + * callers usually don't don't need to work with ldb_result directly. + */ + unsigned int count; + struct ldb_message **msgs; + + /** + * If name was used as a lookup parameter, @lookup_name contains name + * normalized to @domain rules. + */ + const char *lookup_name; +}; + /* Generic request. */ struct tevent_req *cache_req_send(TALLOC_CTX *mem_ctx, @@ -81,9 +108,11 @@ 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, - char **_name); + struct cache_req_result ***_results); + +errno_t cache_req_single_domain_recv(TALLOC_CTX *mem_ctx, + struct tevent_req *req, + struct cache_req_result **_result); /* Plug-ins. */ @@ -96,8 +125,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, _name) \ - cache_req_recv(mem_ctx, req, _result, _domain, _name) +#define cache_req_user_by_name_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) struct tevent_req * cache_req_user_by_id_send(TALLOC_CTX *mem_ctx, @@ -108,8 +137,8 @@ cache_req_user_by_id_send(TALLOC_CTX *mem_ctx, const char *domain, uid_t uid); -#define cache_req_user_by_id_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain, NULL) +#define cache_req_user_by_id_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result); struct tevent_req * cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx, @@ -120,8 +149,8 @@ cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx, const char *domain, const char *pem_cert); -#define cache_req_user_by_cert_recv(mem_ctx, req, _result, _domain, _name) \ - cache_req_recv(mem_ctx, req, _result, _domain, _name) +#define cache_req_user_by_cert_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) struct tevent_req * cache_req_group_by_name_send(TALLOC_CTX *mem_ctx, @@ -132,8 +161,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, _name) \ - cache_req_recv(mem_ctx, req, _result, _domain, _name) +#define cache_req_group_by_name_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) struct tevent_req * cache_req_group_by_id_send(TALLOC_CTX *mem_ctx, @@ -144,8 +173,8 @@ cache_req_group_by_id_send(TALLOC_CTX *mem_ctx, const char *domain, gid_t gid); -#define cache_req_group_by_id_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain, NULL) +#define cache_req_group_by_id_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) struct tevent_req * cache_req_initgr_by_name_send(TALLOC_CTX *mem_ctx, @@ -156,8 +185,8 @@ 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, _name) \ - cache_req_recv(mem_ctx, req, _result, _domain, _name) +#define cache_req_initgr_by_name_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) struct tevent_req * cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx, @@ -166,8 +195,8 @@ cache_req_user_by_filter_send(TALLOC_CTX *mem_ctx, const char *domain, const char *filter); -#define cache_req_user_by_filter_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain, NULL) +#define cache_req_user_by_filter_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) struct tevent_req * cache_req_group_by_filter_send(TALLOC_CTX *mem_ctx, @@ -176,8 +205,8 @@ cache_req_group_by_filter_send(TALLOC_CTX *mem_ctx, const char *domain, const char *filter); -#define cache_req_group_by_filter_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain, NULL) +#define cache_req_group_by_filter_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) struct tevent_req * cache_req_object_by_sid_send(TALLOC_CTX *mem_ctx, @@ -189,7 +218,7 @@ cache_req_object_by_sid_send(TALLOC_CTX *mem_ctx, const char *sid, const char **attrs); -#define cache_req_object_by_sid_recv(mem_ctx, req, _result, _domain) \ - cache_req_recv(mem_ctx, req, _result, _domain, NULL) +#define cache_req_object_by_sid_recv(mem_ctx, req, _result) \ + cache_req_single_domain_recv(mem_ctx, req, _result) #endif /* _CACHE_REQ_H_ */ diff --git a/src/responder/common/cache_req/cache_req_private.h b/src/responder/common/cache_req/cache_req_private.h index d4ac7a909..60a180b6e 100644 --- a/src/responder/common/cache_req/cache_req_private.h +++ b/src/responder/common/cache_req/cache_req_private.h @@ -88,4 +88,10 @@ cache_req_steal_data_and_send(TALLOC_CTX *mem_ctx, const char *domain, struct cache_req_data *data); +struct cache_req_result * +cache_req_create_result(TALLOC_CTX *mem_ctx, + struct sss_domain_info *domain, + struct ldb_result *ldb_result, + const char *lookup_name); + #endif /* _CACHE_REQ_PRIVATE_H_ */ |
