384 lines
13 KiB
Diff
384 lines
13 KiB
Diff
|
From a9845c875e430e00cfb49a39b09c8595ff8e3416 Mon Sep 17 00:00:00 2001
|
||
|
From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina@redhat.com>
|
||
|
Date: Tue, 1 Dec 2015 13:08:36 +0100
|
||
|
Subject: [PATCH 12/49] SDAP: Add request that iterates over all search bases
|
||
|
|
||
|
We often need to iterate over many search bases but we always use
|
||
|
mostly copy&paste iterator. This will reduce code duplication and
|
||
|
simplify code flow.
|
||
|
|
||
|
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
||
|
(cherry picked from commit d0599eaa9369fd867953e3c58b8d7bb445525ff5)
|
||
|
---
|
||
|
Makefile.am | 2 +
|
||
|
src/providers/ldap/ldap_common.h | 9 +-
|
||
|
src/providers/ldap/sdap.c | 2 +-
|
||
|
src/providers/ldap/sdap_ops.c | 232 +++++++++++++++++++++++++++++++++++++++
|
||
|
src/providers/ldap/sdap_ops.h | 44 ++++++++
|
||
|
src/providers/ldap/sdap_utils.c | 6 +-
|
||
|
6 files changed, 288 insertions(+), 7 deletions(-)
|
||
|
create mode 100644 src/providers/ldap/sdap_ops.c
|
||
|
create mode 100644 src/providers/ldap/sdap_ops.h
|
||
|
|
||
|
diff --git a/Makefile.am b/Makefile.am
|
||
|
index 1937dcbebc4f29c4ffe72eeeb67cdb5344a8e7d1..095b1cfd62f49d266df278e1736d48ed5ef4fa7a 100644
|
||
|
--- a/Makefile.am
|
||
|
+++ b/Makefile.am
|
||
|
@@ -628,6 +628,7 @@ dist_noinst_HEADERS = \
|
||
|
src/providers/ldap/sdap_users.h \
|
||
|
src/providers/ldap/sdap_dyndns.h \
|
||
|
src/providers/ldap/sdap_async_enum.h \
|
||
|
+ src/providers/ldap/sdap_ops.h \
|
||
|
src/providers/ipa/ipa_common.h \
|
||
|
src/providers/ipa/ipa_config.h \
|
||
|
src/providers/ipa/ipa_access.h \
|
||
|
@@ -2836,6 +2837,7 @@ libsss_ldap_common_la_SOURCES = \
|
||
|
src/providers/ldap/sdap_refresh.c \
|
||
|
src/providers/ldap/sdap_utils.c \
|
||
|
src/providers/ldap/sdap_domain.c \
|
||
|
+ src/providers/ldap/sdap_ops.c \
|
||
|
src/providers/ldap/sdap.c \
|
||
|
src/util/user_info_msg.c \
|
||
|
src/util/sss_ldap.c \
|
||
|
diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h
|
||
|
index ae45fb71b5cf7edab618a829057357bea2d6844b..66434dd0e8bc82649fecd67b1394cb6b102a7d49 100644
|
||
|
--- a/src/providers/ldap/ldap_common.h
|
||
|
+++ b/src/providers/ldap/ldap_common.h
|
||
|
@@ -264,9 +264,12 @@ errno_t list_missing_attrs(TALLOC_CTX *mem_ctx,
|
||
|
|
||
|
bool sdap_is_secure_uri(const char *uri);
|
||
|
|
||
|
-char *sdap_get_id_specific_filter(TALLOC_CTX *mem_ctx,
|
||
|
- const char *base_filter,
|
||
|
- const char *extra_filter);
|
||
|
+char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
|
||
|
+ const char *base_filter,
|
||
|
+ const char *extra_filter);
|
||
|
+
|
||
|
+#define sdap_get_id_specific_filter(mem_ctx, base_filter, extra_filter) \
|
||
|
+ sdap_combine_filters((mem_ctx), (base_filter), (extra_filter))
|
||
|
|
||
|
char *sdap_get_access_filter(TALLOC_CTX *mem_ctx,
|
||
|
const char *base_filter);
|
||
|
diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c
|
||
|
index fcdc4028efe97bba13f265a8cfd7c75fa6b7a07c..f9b9ff7e6913c406547f36d341300b936e121693 100644
|
||
|
--- a/src/providers/ldap/sdap.c
|
||
|
+++ b/src/providers/ldap/sdap.c
|
||
|
@@ -312,7 +312,7 @@ int sdap_get_map(TALLOC_CTX *memctx,
|
||
|
char *name;
|
||
|
int i, ret;
|
||
|
|
||
|
- map = talloc_array(memctx, struct sdap_attr_map, num_entries);
|
||
|
+ map = talloc_zero_array(memctx, struct sdap_attr_map, num_entries + 1);
|
||
|
if (!map) {
|
||
|
return ENOMEM;
|
||
|
}
|
||
|
diff --git a/src/providers/ldap/sdap_ops.c b/src/providers/ldap/sdap_ops.c
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..b2f2c35d0bf49682f522993390cfec2f451bf366
|
||
|
--- /dev/null
|
||
|
+++ b/src/providers/ldap/sdap_ops.c
|
||
|
@@ -0,0 +1,232 @@
|
||
|
+/*
|
||
|
+ Authors:
|
||
|
+ Pavel Březina <pbrezina@redhat.com>
|
||
|
+
|
||
|
+ Copyright (C) 2015 Red Hat
|
||
|
+
|
||
|
+ This program is free software; you can redistribute it and/or modify
|
||
|
+ it under the terms of the GNU General Public License as published by
|
||
|
+ the Free Software Foundation; either version 3 of the License, or
|
||
|
+ (at your option) any later version.
|
||
|
+
|
||
|
+ This program is distributed in the hope that it will be useful,
|
||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ GNU General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU General Public License
|
||
|
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
+*/
|
||
|
+
|
||
|
+#include <talloc.h>
|
||
|
+#include <tevent.h>
|
||
|
+
|
||
|
+#include "util/util.h"
|
||
|
+#include "providers/ldap/sdap.h"
|
||
|
+#include "providers/ldap/sdap_async.h"
|
||
|
+#include "providers/ldap/ldap_common.h"
|
||
|
+
|
||
|
+struct sdap_search_bases_state {
|
||
|
+ struct tevent_context *ev;
|
||
|
+ struct sdap_options *opts;
|
||
|
+ struct sdap_handle *sh;
|
||
|
+ const char *filter;
|
||
|
+ const char **attrs;
|
||
|
+ struct sdap_attr_map *map;
|
||
|
+ int map_num_attrs;
|
||
|
+ int timeout;
|
||
|
+ bool allow_paging;
|
||
|
+
|
||
|
+ size_t base_iter;
|
||
|
+ struct sdap_search_base *cur_base;
|
||
|
+ struct sdap_search_base **bases;
|
||
|
+
|
||
|
+ size_t reply_count;
|
||
|
+ struct sysdb_attrs **reply;
|
||
|
+};
|
||
|
+
|
||
|
+static errno_t sdap_search_bases_next_base(struct tevent_req *req);
|
||
|
+static void sdap_search_bases_done(struct tevent_req *subreq);
|
||
|
+
|
||
|
+struct tevent_req *sdap_search_bases_send(TALLOC_CTX *mem_ctx,
|
||
|
+ struct tevent_context *ev,
|
||
|
+ struct sdap_options *opts,
|
||
|
+ struct sdap_handle *sh,
|
||
|
+ struct sdap_search_base **bases,
|
||
|
+ struct sdap_attr_map *map,
|
||
|
+ bool allow_paging,
|
||
|
+ int timeout,
|
||
|
+ const char *filter,
|
||
|
+ const char **attrs)
|
||
|
+{
|
||
|
+ struct tevent_req *req;
|
||
|
+ struct sdap_search_bases_state *state;
|
||
|
+ errno_t ret;
|
||
|
+
|
||
|
+ req = tevent_req_create(mem_ctx, &state, struct sdap_search_bases_state);
|
||
|
+ if (req == NULL) {
|
||
|
+ return NULL;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (bases == NULL) {
|
||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "No search base specified!\n");
|
||
|
+ ret = ERR_INTERNAL;
|
||
|
+ goto immediately;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (map == NULL) {
|
||
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "No attribute map specified!\n");
|
||
|
+ ret = ERR_INTERNAL;
|
||
|
+ goto immediately;
|
||
|
+ }
|
||
|
+
|
||
|
+ state->ev = ev;
|
||
|
+ state->opts = opts;
|
||
|
+ state->sh = sh;
|
||
|
+ state->bases = bases;
|
||
|
+ state->map = map;
|
||
|
+ state->filter = filter;
|
||
|
+ state->attrs = attrs;
|
||
|
+ state->allow_paging = allow_paging;
|
||
|
+
|
||
|
+ state->timeout = timeout == 0
|
||
|
+ ? dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT)
|
||
|
+ : timeout;
|
||
|
+
|
||
|
+ for (state->map_num_attrs = 0;
|
||
|
+ state->map[state->map_num_attrs].opt_name != NULL;
|
||
|
+ state->map_num_attrs++) {
|
||
|
+ /* no op */;
|
||
|
+ }
|
||
|
+
|
||
|
+ if (state->attrs == NULL) {
|
||
|
+ ret = build_attrs_from_map(state, state->map, state->map_num_attrs,
|
||
|
+ NULL, &state->attrs, NULL);
|
||
|
+ if (ret != EOK) {
|
||
|
+ DEBUG(SSSDBG_OP_FAILURE, "Unable to build attrs from map "
|
||
|
+ "[%d]: %s\n", ret, sss_strerror(ret));
|
||
|
+ goto immediately;
|
||
|
+ }
|
||
|
+ }
|
||
|
+
|
||
|
+ state->base_iter = 0;
|
||
|
+ ret = sdap_search_bases_next_base(req);
|
||
|
+ if (ret == EAGAIN) {
|
||
|
+ /* asynchronous processing */
|
||
|
+ return req;
|
||
|
+ }
|
||
|
+
|
||
|
+immediately:
|
||
|
+ if (ret == EOK) {
|
||
|
+ tevent_req_done(req);
|
||
|
+ } else {
|
||
|
+ tevent_req_error(req, ret);
|
||
|
+ }
|
||
|
+ tevent_req_post(req, ev);
|
||
|
+
|
||
|
+ return req;
|
||
|
+}
|
||
|
+
|
||
|
+static errno_t sdap_search_bases_next_base(struct tevent_req *req)
|
||
|
+{
|
||
|
+ struct sdap_search_bases_state *state;
|
||
|
+ struct tevent_req *subreq;
|
||
|
+ char *filter;
|
||
|
+
|
||
|
+ state = tevent_req_data(req, struct sdap_search_bases_state);
|
||
|
+ state->cur_base = state->bases[state->base_iter];
|
||
|
+ if (state->cur_base == NULL) {
|
||
|
+ return EOK;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Combine lookup and search base filters. */
|
||
|
+ filter = sdap_combine_filters(state, state->filter,
|
||
|
+ state->cur_base->filter);
|
||
|
+ if (filter == NULL) {
|
||
|
+ return ENOMEM;
|
||
|
+ }
|
||
|
+
|
||
|
+ DEBUG(SSSDBG_TRACE_FUNC, "Issuing LDAP lookup with base [%s]\n",
|
||
|
+ state->cur_base->basedn);
|
||
|
+
|
||
|
+ subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
|
||
|
+ state->cur_base->basedn,
|
||
|
+ state->cur_base->scope, filter,
|
||
|
+ state->attrs, state->map,
|
||
|
+ state->map_num_attrs, state->timeout,
|
||
|
+ state->allow_paging);
|
||
|
+ if (subreq == NULL) {
|
||
|
+ return ENOMEM;
|
||
|
+ }
|
||
|
+
|
||
|
+ tevent_req_set_callback(subreq, sdap_search_bases_done, req);
|
||
|
+
|
||
|
+ state->base_iter++;
|
||
|
+ return EAGAIN;
|
||
|
+}
|
||
|
+
|
||
|
+static void sdap_search_bases_done(struct tevent_req *subreq)
|
||
|
+{
|
||
|
+ struct tevent_req *req;
|
||
|
+ struct sdap_search_bases_state *state;
|
||
|
+ struct sysdb_attrs **attrs;
|
||
|
+ size_t count;
|
||
|
+ size_t i;
|
||
|
+ int ret;
|
||
|
+
|
||
|
+ req = tevent_req_callback_data(subreq, struct tevent_req);
|
||
|
+ state = tevent_req_data(req, struct sdap_search_bases_state);
|
||
|
+
|
||
|
+ DEBUG(SSSDBG_TRACE_FUNC, "Receiving data from base [%s]\n",
|
||
|
+ state->cur_base->basedn);
|
||
|
+
|
||
|
+ ret = sdap_get_generic_recv(subreq, state, &count, &attrs);
|
||
|
+ talloc_zfree(subreq);
|
||
|
+ if (ret != EOK) {
|
||
|
+ tevent_req_error(req, ret);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Add rules to result. */
|
||
|
+ if (count > 0) {
|
||
|
+ state->reply = talloc_realloc(state, state->reply, struct sysdb_attrs *,
|
||
|
+ state->reply_count + count);
|
||
|
+ if (state->reply == NULL) {
|
||
|
+ tevent_req_error(req, ENOMEM);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+
|
||
|
+ for (i = 0; i < count; i++) {
|
||
|
+ state->reply[state->reply_count + i] = talloc_steal(state->reply,
|
||
|
+ attrs[i]);
|
||
|
+ }
|
||
|
+
|
||
|
+ state->reply_count += count;
|
||
|
+ }
|
||
|
+
|
||
|
+ /* Try next search base. */
|
||
|
+ ret = sdap_search_bases_next_base(req);
|
||
|
+ if (ret == EOK) {
|
||
|
+ tevent_req_done(req);
|
||
|
+ } else if (ret != EAGAIN) {
|
||
|
+ tevent_req_error(req, ret);
|
||
|
+ }
|
||
|
+
|
||
|
+ return;
|
||
|
+}
|
||
|
+
|
||
|
+int sdap_search_bases_recv(struct tevent_req *req,
|
||
|
+ TALLOC_CTX *mem_ctx,
|
||
|
+ size_t *reply_count,
|
||
|
+ struct sysdb_attrs ***reply)
|
||
|
+{
|
||
|
+ struct sdap_search_bases_state *state =
|
||
|
+ tevent_req_data(req, struct sdap_search_bases_state);
|
||
|
+
|
||
|
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
||
|
+
|
||
|
+ *reply_count = state->reply_count;
|
||
|
+ *reply = talloc_steal(mem_ctx, state->reply);
|
||
|
+
|
||
|
+ return EOK;
|
||
|
+}
|
||
|
diff --git a/src/providers/ldap/sdap_ops.h b/src/providers/ldap/sdap_ops.h
|
||
|
new file mode 100644
|
||
|
index 0000000000000000000000000000000000000000..bc53ff8701c26ca00d5c07b441b170d615bda2ee
|
||
|
--- /dev/null
|
||
|
+++ b/src/providers/ldap/sdap_ops.h
|
||
|
@@ -0,0 +1,44 @@
|
||
|
+/*
|
||
|
+ Authors:
|
||
|
+ Pavel Březina <pbrezina@redhat.com>
|
||
|
+
|
||
|
+ Copyright (C) 2015 Red Hat
|
||
|
+
|
||
|
+ This program is free software; you can redistribute it and/or modify
|
||
|
+ it under the terms of the GNU General Public License as published by
|
||
|
+ the Free Software Foundation; either version 3 of the License, or
|
||
|
+ (at your option) any later version.
|
||
|
+
|
||
|
+ This program is distributed in the hope that it will be useful,
|
||
|
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||
|
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||
|
+ GNU General Public License for more details.
|
||
|
+
|
||
|
+ You should have received a copy of the GNU General Public License
|
||
|
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
+*/
|
||
|
+
|
||
|
+#ifndef _SDAP_OPS_H_
|
||
|
+#define _SDAP_OPS_H_
|
||
|
+
|
||
|
+#include <talloc.h>
|
||
|
+#include <tevent.h>
|
||
|
+#include "providers/ldap/ldap_common.h"
|
||
|
+
|
||
|
+struct tevent_req *sdap_search_bases_send(TALLOC_CTX *mem_ctx,
|
||
|
+ struct tevent_context *ev,
|
||
|
+ struct sdap_options *opts,
|
||
|
+ struct sdap_handle *sh,
|
||
|
+ struct sdap_search_base **bases,
|
||
|
+ struct sdap_attr_map *map,
|
||
|
+ bool allow_paging,
|
||
|
+ int timeout,
|
||
|
+ const char *filter,
|
||
|
+ const char **attrs);
|
||
|
+
|
||
|
+int sdap_search_bases_recv(struct tevent_req *req,
|
||
|
+ TALLOC_CTX *mem_ctx,
|
||
|
+ size_t *reply_count,
|
||
|
+ struct sysdb_attrs ***reply);
|
||
|
+
|
||
|
+#endif /* _SDAP_OPS_H_ */
|
||
|
diff --git a/src/providers/ldap/sdap_utils.c b/src/providers/ldap/sdap_utils.c
|
||
|
index 9da46ea70bf80e7f4d12fdfc7d1c97e99de8d000..7a96f81a1db2644b698e5a5baaed19366a305c6b 100644
|
||
|
--- a/src/providers/ldap/sdap_utils.c
|
||
|
+++ b/src/providers/ldap/sdap_utils.c
|
||
|
@@ -149,9 +149,9 @@ errno_t deref_string_to_val(const char *str, int *val)
|
||
|
return EOK;
|
||
|
}
|
||
|
|
||
|
-char *sdap_get_id_specific_filter(TALLOC_CTX *mem_ctx,
|
||
|
- const char *base_filter,
|
||
|
- const char *extra_filter)
|
||
|
+char *sdap_combine_filters(TALLOC_CTX *mem_ctx,
|
||
|
+ const char *base_filter,
|
||
|
+ const char *extra_filter)
|
||
|
{
|
||
|
char *filter = NULL;
|
||
|
|
||
|
--
|
||
|
2.5.0
|
||
|
|