summaryrefslogtreecommitdiffstats
path: root/src/responder/common/cache_req
diff options
context:
space:
mode:
authorPavel Březina <pbrezina@redhat.com>2016-10-14 12:15:50 +0200
committerLukas Slebodnik <lslebodn@redhat.com>2016-12-19 23:22:54 +0100
commitb206e1abb7f6ea373d12537b3338552aed6b656d (patch)
tree7ac5b5d24dbeee268bbdb6d26f19586b84ed8cdb /src/responder/common/cache_req
parentf63607bfcc01ad426efa20ed8ec65f429c9b2bd6 (diff)
downloadsssd-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.c152
-rw-r--r--src/responder/common/cache_req/cache_req.h71
-rw-r--r--src/responder/common/cache_req/cache_req_private.h6
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_ */