From 179ac94a4910150b846ff1c959e766c5a31274cf Mon Sep 17 00:00:00 2001 From: Jakub Hrozek Date: Fri, 8 May 2015 14:49:09 +0200 Subject: LDAP: Add sdap_lookup_type enum MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Related: https://fedorahosted.org/sssd/ticket/2553 Change the boolan parameter of sdap_get_users_send and sdap_get_groups_send to a tri-state that controls whether we expect only a single entry (ie don't use the paging control), multiple entries with a search limit (wildcard request) or multiple entries with no limit (enumeration). Reviewed-by: Pavel Březina --- src/providers/ldap/ldap_auth.c | 2 +- src/providers/ldap/ldap_id.c | 16 +++++++------- src/providers/ldap/sdap_async.h | 12 +++++++--- src/providers/ldap/sdap_async_enum.c | 4 ++-- src/providers/ldap/sdap_async_groups.c | 40 ++++++++++++++++++++++++---------- src/providers/ldap/sdap_async_users.c | 32 ++++++++++++++++++++------- 6 files changed, 73 insertions(+), 33 deletions(-) diff --git a/src/providers/ldap/ldap_auth.c b/src/providers/ldap/ldap_auth.c index 817179426..217e80fd0 100644 --- a/src/providers/ldap/ldap_auth.c +++ b/src/providers/ldap/ldap_auth.c @@ -418,7 +418,7 @@ static struct tevent_req *get_user_dn_send(TALLOC_CTX *memctx, sh, attrs, filter, dp_opt_get_int(opts->basic, SDAP_SEARCH_TIMEOUT), - false); + SDAP_LOOKUP_SINGLE); if (!subreq) { ret = ENOMEM; goto done; diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 61f09fc41..73840d288 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -396,12 +396,12 @@ static void users_get_search(struct tevent_req *req) struct users_get_state *state = tevent_req_data(req, struct users_get_state); struct tevent_req *subreq; - bool multiple_results; + enum sdap_entry_lookup_type lookup_type; if (state->filter_type == BE_FILTER_WILDCARD) { - multiple_results = true; + lookup_type = SDAP_LOOKUP_WILDCARD; } else { - multiple_results = false; + lookup_type = SDAP_LOOKUP_SINGLE; } subreq = sdap_get_users_send(state, state->ev, @@ -412,7 +412,7 @@ static void users_get_search(struct tevent_req *req) state->attrs, state->filter, dp_opt_get_int(state->ctx->opts->basic, SDAP_SEARCH_TIMEOUT), - multiple_results); + lookup_type); if (!subreq) { tevent_req_error(req, ENOMEM); return; @@ -901,12 +901,12 @@ static void groups_get_search(struct tevent_req *req) struct groups_get_state *state = tevent_req_data(req, struct groups_get_state); struct tevent_req *subreq; - bool multiple_results; + enum sdap_entry_lookup_type lookup_type; if (state->filter_type == BE_FILTER_WILDCARD) { - multiple_results = true; + lookup_type = SDAP_LOOKUP_WILDCARD; } else { - multiple_results = false; + lookup_type = SDAP_LOOKUP_SINGLE; } subreq = sdap_get_groups_send(state, state->ev, @@ -916,7 +916,7 @@ static void groups_get_search(struct tevent_req *req) state->attrs, state->filter, dp_opt_get_int(state->ctx->opts->basic, SDAP_SEARCH_TIMEOUT), - multiple_results, + lookup_type, state->no_members); if (!subreq) { tevent_req_error(req, ENOMEM); diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index b23dfc313..09bc0d654 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -59,6 +59,12 @@ errno_t sdap_connect_host_recv(TALLOC_CTX *mem_ctx, struct sdap_handle **_sh); /* Search users in LDAP, return them as attrs */ +enum sdap_entry_lookup_type { + SDAP_LOOKUP_SINGLE, /* Direct single-user/group lookup */ + SDAP_LOOKUP_WILDCARD, /* Multiple entries with a limit */ + SDAP_LOOKUP_ENUMERATE, /* Fetch all entries from the server */ +}; + struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx, struct tevent_context *ev, struct sss_domain_info *dom, @@ -68,7 +74,7 @@ struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx, const char **attrs, const char *filter, int timeout, - bool enumeration); + enum sdap_entry_lookup_type lookup_type); int sdap_search_user_recv(TALLOC_CTX *memctx, struct tevent_req *req, char **higher_usn, struct sysdb_attrs ***users, size_t *count); @@ -84,7 +90,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, const char **attrs, const char *filter, int timeout, - bool enumeration); + enum sdap_entry_lookup_type lookup_type); int sdap_get_users_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **timestamp); @@ -96,7 +102,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, const char **attrs, const char *filter, int timeout, - bool enumeration, + enum sdap_entry_lookup_type lookup_type, bool no_members); int sdap_get_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **timestamp); diff --git a/src/providers/ldap/sdap_async_enum.c b/src/providers/ldap/sdap_async_enum.c index 35afc55f8..f22276c3c 100644 --- a/src/providers/ldap/sdap_async_enum.c +++ b/src/providers/ldap/sdap_async_enum.c @@ -635,7 +635,7 @@ static struct tevent_req *enum_users_send(TALLOC_CTX *memctx, state->attrs, state->filter, dp_opt_get_int(state->ctx->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), - true); + SDAP_LOOKUP_ENUMERATE); if (!subreq) { ret = ENOMEM; goto fail; @@ -811,7 +811,7 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx, state->attrs, state->filter, dp_opt_get_int(state->ctx->opts->basic, SDAP_ENUM_SEARCH_TIMEOUT), - true, false); + SDAP_LOOKUP_ENUMERATE, false); if (!subreq) { ret = ENOMEM; goto fail; diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index e785307e6..ad0354df1 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.c @@ -1721,7 +1721,7 @@ struct sdap_get_groups_state { const char *base_filter; char *filter; int timeout; - bool enumeration; + enum sdap_entry_lookup_type lookup_type; bool no_members; char *higher_usn; @@ -1752,7 +1752,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, const char **attrs, const char *filter, int timeout, - bool enumeration, + enum sdap_entry_lookup_type lookup_type, bool no_members) { errno_t ret; @@ -1775,7 +1775,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, state->groups = NULL; state->count = 0; state->timeout = timeout; - state->enumeration = enumeration; + state->lookup_type = lookup_type; state->no_members = no_members; state->base_filter = filter; state->base_iter = 0; @@ -1855,6 +1855,7 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_get_groups_state *state; + bool need_paging = false; state = tevent_req_data(req, struct sdap_get_groups_state); @@ -1870,6 +1871,19 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req) "Searching for groups with base [%s]\n", state->search_bases[state->base_iter]->basedn); + switch (state->lookup_type) { + case SDAP_LOOKUP_SINGLE: + need_paging = false; + break; + /* Only requests that can return multiple entries should require + * the paging control + */ + case SDAP_LOOKUP_WILDCARD: + case SDAP_LOOKUP_ENUMERATE: + need_paging = true; + break; + } + subreq = sdap_get_and_parse_generic_send( state, state->ev, state->opts, state->ldap_sh != NULL ? state->ldap_sh : state->sh, @@ -1878,7 +1892,7 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req) state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, 0, NULL, NULL, 0, state->timeout, - state->enumeration); /* If we're enumerating, we need paging */ + need_paging); if (!subreq) { return ENOMEM; } @@ -1914,14 +1928,17 @@ static void sdap_get_groups_process(struct tevent_req *subreq) DEBUG(SSSDBG_TRACE_FUNC, "Search for groups, returned %zu results.\n", count); - if (!state->enumeration && count > 1) { + if (state->lookup_type == SDAP_LOOKUP_SINGLE && count > 1) { DEBUG(SSSDBG_MINOR_FAILURE, "Individual group search returned multiple results\n"); tevent_req_error(req, EINVAL); return; } - if (state->enumeration || count == 0) { + if (state->lookup_type == SDAP_LOOKUP_WILDCARD || \ + state->lookup_type == SDAP_LOOKUP_ENUMERATE || \ + count == 0) { + /* No users found in this search or looking up multiple entries */ next_base = true; } @@ -2003,7 +2020,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq) * LDAP_MATCHING_RULE_IN_CHAIN available in * AD 2008 and later */ - if (!state->enumeration) { + if (state->lookup_type == SDAP_LOOKUP_SINGLE) { if ((state->opts->schema_type != SDAP_SCHEMA_RFC2307) && (dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0) && !dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_GROUPS)) { @@ -2026,7 +2043,7 @@ static void sdap_get_groups_process(struct tevent_req *subreq) /* If we're using LDAP_MATCHING_RULE_IN_CHAIN, start a subreq to * retrieve the members so we can save them in a single step. */ - if (!state->enumeration + if (state->lookup_type == SDAP_LOOKUP_SINGLE && (state->opts->schema_type != SDAP_SCHEMA_RFC2307) && state->opts->support_matching_rule && dp_opt_get_bool(state->opts->basic, SDAP_AD_MATCHING_RULE_GROUPS)) { @@ -2050,7 +2067,8 @@ static void sdap_get_groups_process(struct tevent_req *subreq) return; } - if (state->enumeration + if ((state->lookup_type == SDAP_LOOKUP_ENUMERATE + || state->lookup_type == SDAP_LOOKUP_WILDCARD) && state->opts->schema_type != SDAP_SCHEMA_RFC2307 && dp_opt_get_int(state->opts->basic, SDAP_NESTING_LEVEL) != 0) { DEBUG(SSSDBG_TRACE_ALL, "Saving groups without members first " @@ -2069,7 +2087,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], - state->enumeration); + state->lookup_type == SDAP_LOOKUP_ENUMERATE); if (!subreq) { tevent_req_error(req, ENOMEM); @@ -2116,7 +2134,7 @@ static void sdap_get_groups_done(struct tevent_req *subreq) ret = sdap_save_groups(state, state->sysdb, state->dom, state->opts, state->groups, state->count, !state->dom->ignore_group_members, NULL, - !state->enumeration, + state->lookup_type == SDAP_LOOKUP_SINGLE, &state->higher_usn); if (ret) { DEBUG(SSSDBG_OP_FAILURE, "Failed to store groups.\n"); diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c index 216b49477..f66ae2604 100644 --- a/src/providers/ldap/sdap_async_users.c +++ b/src/providers/ldap/sdap_async_users.c @@ -606,7 +606,7 @@ struct sdap_search_user_state { const char *base_filter; const char *filter; int timeout; - bool enumeration; + enum sdap_entry_lookup_type lookup_type; char *higher_usn; struct sysdb_attrs **users; @@ -628,7 +628,7 @@ struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx, const char **attrs, const char *filter, int timeout, - bool enumeration) + enum sdap_entry_lookup_type lookup_type) { errno_t ret; struct tevent_req *req; @@ -649,7 +649,7 @@ struct tevent_req *sdap_search_user_send(TALLOC_CTX *memctx, state->base_filter = filter; state->base_iter = 0; state->search_bases = search_bases; - state->enumeration = enumeration; + state->lookup_type = lookup_type; if (!state->search_bases) { DEBUG(SSSDBG_CRIT_FAILURE, @@ -673,6 +673,7 @@ static errno_t sdap_search_user_next_base(struct tevent_req *req) { struct tevent_req *subreq; struct sdap_search_user_state *state; + bool need_paging = false; state = tevent_req_data(req, struct sdap_search_user_state); @@ -688,6 +689,19 @@ static errno_t sdap_search_user_next_base(struct tevent_req *req) "Searching for users with base [%s]\n", state->search_bases[state->base_iter]->basedn); + switch (state->lookup_type) { + case SDAP_LOOKUP_SINGLE: + need_paging = false; + break; + /* Only requests that can return multiple entries should require + * the paging control + */ + case SDAP_LOOKUP_WILDCARD: + case SDAP_LOOKUP_ENUMERATE: + need_paging = true; + break; + } + subreq = sdap_get_and_parse_generic_send( state, state->ev, state->opts, state->sh, state->search_bases[state->base_iter]->basedn, @@ -695,7 +709,7 @@ static errno_t sdap_search_user_next_base(struct tevent_req *req) state->filter, state->attrs, state->opts->user_map, state->opts->user_map_cnt, 0, NULL, NULL, 0, state->timeout, - state->enumeration); /* If we're enumerating, we need paging */ + need_paging); if (subreq == NULL) { return ENOMEM; } @@ -726,8 +740,10 @@ static void sdap_search_user_process(struct tevent_req *subreq) DEBUG(SSSDBG_TRACE_FUNC, "Search for users, returned %zu results.\n", count); - if (state->enumeration || count == 0) { - /* No users found in this search or enumerating */ + if (state->lookup_type == SDAP_LOOKUP_WILDCARD || \ + state->lookup_type == SDAP_LOOKUP_ENUMERATE || \ + count == 0) { + /* No users found in this search or looking up multiple entries */ next_base = true; } @@ -827,7 +843,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, const char **attrs, const char *filter, int timeout, - bool enumeration) + enum sdap_entry_lookup_type lookup_type) { errno_t ret; struct tevent_req *req; @@ -842,7 +858,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, state->dom = dom; subreq = sdap_search_user_send(state, ev, dom, opts, search_bases, - sh, attrs, filter, timeout, enumeration); + sh, attrs, filter, timeout, lookup_type); if (subreq == NULL) { ret = ENOMEM; goto done; -- cgit