summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2011-10-03 14:23:22 -0400
committerStephen Gallagher <sgallagh@redhat.com>2011-11-02 11:12:12 -0400
commit1bbd4c57fc31cec302244725e698413623818d19 (patch)
tree878378cef60528db6c3b67fe0eae19211714fc87 /src
parentf26b61dfe246c750a42f1f9fb28f9df5981bc841 (diff)
downloadsssd-1bbd4c57fc31cec302244725e698413623818d19.tar.gz
sssd-1bbd4c57fc31cec302244725e698413623818d19.tar.bz2
sssd-1bbd4c57fc31cec302244725e698413623818d19.zip
LDAP: Add support for multiple search bases for group enumeration
Diffstat (limited to 'src')
-rw-r--r--src/providers/ldap/ldap_id.c3
-rw-r--r--src/providers/ldap/ldap_id_enum.c3
-rw-r--r--src/providers/ldap/sdap_async.h3
-rw-r--r--src/providers/ldap/sdap_async_groups.c116
4 files changed, 101 insertions, 24 deletions
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index c381c19b..d3001848 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -408,7 +408,8 @@ static void groups_get_connect_done(struct tevent_req *subreq)
sdap_id_op_handle(state->op),
state->attrs, state->filter,
dp_opt_get_int(state->ctx->opts->basic,
- SDAP_SEARCH_TIMEOUT));
+ SDAP_SEARCH_TIMEOUT),
+ false);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
diff --git a/src/providers/ldap/ldap_id_enum.c b/src/providers/ldap/ldap_id_enum.c
index 9923379d..7a8d0712 100644
--- a/src/providers/ldap/ldap_id_enum.c
+++ b/src/providers/ldap/ldap_id_enum.c
@@ -607,7 +607,8 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx,
sdap_id_op_handle(state->op),
state->attrs, state->filter,
dp_opt_get_int(state->ctx->opts->basic,
- SDAP_ENUM_SEARCH_TIMEOUT));
+ SDAP_ENUM_SEARCH_TIMEOUT),
+ true);
if (!subreq) {
ret = ENOMEM;
goto fail;
diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h
index 262c04a0..e628c7da 100644
--- a/src/providers/ldap/sdap_async.h
+++ b/src/providers/ldap/sdap_async.h
@@ -63,7 +63,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
struct sdap_handle *sh,
const char **attrs,
const char *filter,
- int timeout);
+ int timeout,
+ bool enumeration);
int sdap_get_groups_recv(struct tevent_req *req,
TALLOC_CTX *mem_ctx, char **timestamp);
diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c
index 602bd263..f50acdd9 100644
--- a/src/providers/ldap/sdap_async_groups.c
+++ b/src/providers/ldap/sdap_async_groups.c
@@ -1196,6 +1196,7 @@ struct sdap_get_groups_state {
const char *base_filter;
char *filter;
int timeout;
+ bool enumeration;
char *higher_usn;
struct sysdb_attrs **groups;
@@ -1222,7 +1223,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
struct sdap_handle *sh,
const char **attrs,
const char *filter,
- int timeout)
+ int timeout,
+ bool enumeration)
{
errno_t ret;
struct tevent_req *req;
@@ -1241,6 +1243,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx,
state->groups = NULL;
state->count = 0;
state->timeout = timeout;
+ state->enumeration = enumeration;
state->base_filter = filter;
state->base_iter = 0;
state->search_bases = search_bases;
@@ -1305,21 +1308,89 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
tevent_req_data(req, struct sdap_get_groups_state);
int ret;
int i;
- bool enumeration = false;
+ bool next_base = false;
+ size_t count;
+ struct sysdb_attrs **groups;
ret = sdap_get_generic_recv(subreq, state,
- &state->count, &state->groups);
+ &count, &groups);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
return;
}
- DEBUG(6, ("Search for groups, returned %d results.\n", state->count));
+ DEBUG(6, ("Search for groups, returned %d results.\n", count));
+
+ if (!state->enumeration && count > 1) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Individual group search returned multiple results\n"));
+ tevent_req_error(req, EINVAL);
+ return;
+ }
+
+ if (state->enumeration || count == 0) {
+ next_base = true;
+ }
+
+ /* Add this batch of groups to the list */
+ if (count > 0) {
+ state->groups =
+ talloc_realloc(state,
+ state->groups,
+ struct sysdb_attrs *,
+ state->count + count + 1);
+ if (!state->groups) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ /* Copy the new groups into the list
+ * They're already allocated on 'state'
+ */
+ for (i = 0; i < count; i++) {
+ state->groups[state->count + i] = groups[i];
+ }
+
+ state->count += count;
+ state->groups[state->count] = NULL;
+ }
+
+ if (!state->enumeration && count > 1) {
+ DEBUG(SSSDBG_MINOR_FAILURE,
+ ("Individual group search returned multiple results\n"));
+ tevent_req_error(req, EINVAL);
+ return;
+ }
- switch(state->count) {
- case 0:
- /* No groups found in this search */
+ if (state->enumeration || count == 0) {
+ next_base = true;
+ }
+
+ /* Add this batch of groups to the list */
+ if (count > 0) {
+ state->groups =
+ talloc_realloc(state,
+ state->groups,
+ struct sysdb_attrs *,
+ state->count + count + 1);
+ if (!state->groups) {
+ tevent_req_error(req, ENOMEM);
+ return;
+ }
+
+ /* Copy the new groups into the list
+ * They're already allocated on 'state'
+ */
+ for (i = 0; i < count; i++) {
+ state->groups[state->count + i] = groups[i];
+ }
+
+ state->count += count;
+ state->groups[state->count] = NULL;
+ }
+
+ if (next_base) {
state->base_iter++;
if (state->search_bases[state->base_iter]) {
/* There are more search bases to try */
@@ -1329,12 +1400,22 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
}
return;
}
+ }
+ /* No more search bases
+ * Return ENOENT if no groups were found
+ */
+ if (state->count == 0) {
tevent_req_error(req, ENOENT);
return;
+ }
- case 1:
- /* Single group search */
+ /* Check whether we need to do nested searches
+ * for RFC2307bis/FreeIPA/ActiveDirectory
+ * We don't need to do this for enumeration,
+ * because all groups will be picked up anyway.
+ */
+ if (!state->enumeration) {
if ((state->opts->schema_type != SDAP_SCHEMA_RFC2307) &&
(dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0)) {
@@ -1368,17 +1449,10 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
tevent_req_set_callback(subreq, sdap_nested_done, req);
return;
- } else {
- /* RFC2307 or disabled nested groups */
- break;
}
-
- default:
- /* Enumeration */
- enumeration = true;
- break;
}
+ /* We have all of the groups. Save them to the sysdb */
state->check_count = state->count;
ret = sysdb_transaction_start(state->sysdb);
@@ -1388,9 +1462,9 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
return;
}
- if (enumeration && (state->opts->schema_type != SDAP_SCHEMA_RFC2307) &&
- (dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0)) {
-
+ if (state->enumeration
+ && state->opts->schema_type != SDAP_SCHEMA_RFC2307
+ && dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0) {
DEBUG(9, ("Saving groups without members first "
"to allow unrolling of nested groups.\n"));
ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts,
@@ -1406,7 +1480,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq)
subreq = sdap_process_group_send(state, state->ev, state->dom,
state->sysdb, state->opts,
state->sh, state->groups[i],
- enumeration);
+ state->enumeration);
if (!subreq) {
tevent_req_error(req, ENOMEM);