From 3828873b48096e6482329bab6da175de3f615ab8 Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Tue, 21 Feb 2012 21:03:26 -0500 Subject: LDAP: Only use paging control on requests for multiple entries The paging control can cause issues on servers that put limits on how many paging controls can be active at one time (on some servers, it is limited to one per connection). We need to reduce our usage so that we only activate the paging control when making a request that may return an arbitrary number of results. https://fedorahosted.org/sssd/ticket/1202 phase one --- src/providers/ipa/ipa_config.c | 3 +- src/providers/ipa/ipa_hbac_rules.c | 3 +- src/providers/ipa/ipa_hbac_services.c | 6 ++-- src/providers/ipa/ipa_hosts.c | 6 ++-- src/providers/ipa/ipa_netgroups.c | 15 +++++----- src/providers/ipa/ipa_selinux_maps.c | 3 +- src/providers/ldap/sdap_access.c | 3 +- src/providers/ldap/sdap_async.c | 45 ++++++++++++++++++++++++++---- src/providers/ldap/sdap_async.h | 3 +- src/providers/ldap/sdap_async_autofs.c | 5 ++-- src/providers/ldap/sdap_async_groups.c | 15 ++++++---- src/providers/ldap/sdap_async_initgroups.c | 18 ++++++++---- src/providers/ldap/sdap_async_netgroups.c | 6 ++-- src/providers/ldap/sdap_async_services.c | 3 +- src/providers/ldap/sdap_async_users.c | 3 +- src/providers/ldap/sdap_sudo.c | 3 +- 16 files changed, 100 insertions(+), 40 deletions(-) (limited to 'src') diff --git a/src/providers/ipa/ipa_config.c b/src/providers/ipa/ipa_config.c index 62a9a485d..2afa3d326 100644 --- a/src/providers/ipa/ipa_config.c +++ b/src/providers/ipa/ipa_config.c @@ -88,7 +88,8 @@ ipa_get_config_send(TALLOC_CTX *mem_ctx, LDAP_SCOPE_SUBTREE, IPA_CONFIG_FILTER, state->attrs, NULL, 0, dp_opt_get_int(opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + false); if (subreq == NULL) { ret = ENOMEM; goto done; diff --git a/src/providers/ipa/ipa_hbac_rules.c b/src/providers/ipa/ipa_hbac_rules.c index c07cf332b..49dcdfa0a 100644 --- a/src/providers/ipa/ipa_hbac_rules.c +++ b/src/providers/ipa/ipa_hbac_rules.c @@ -233,7 +233,8 @@ ipa_hbac_rule_info_next(struct tevent_req *req, state->cur_filter, state->attrs, NULL, 0, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("sdap_get_generic_send failed.\n")); return ENOMEM; diff --git a/src/providers/ipa/ipa_hbac_services.c b/src/providers/ipa/ipa_hbac_services.c index 3bbdc8ba1..4f0f5f7b1 100644 --- a/src/providers/ipa/ipa_hbac_services.c +++ b/src/providers/ipa/ipa_hbac_services.c @@ -154,7 +154,8 @@ static errno_t ipa_hbac_service_info_next(struct tevent_req *req, state->cur_filter, state->attrs, NULL, 0, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting service info\n")); return EIO; @@ -267,7 +268,8 @@ ipa_hbac_servicegroup_info_next(struct tevent_req *req, base->basedn, base->scope, state->cur_filter, state->attrs, NULL, 0, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting servicegroup info\n")); return EIO; diff --git a/src/providers/ipa/ipa_hosts.c b/src/providers/ipa/ipa_hosts.c index e939ab7f1..5e41c1ee2 100644 --- a/src/providers/ipa/ipa_hosts.c +++ b/src/providers/ipa/ipa_hosts.c @@ -169,7 +169,8 @@ static errno_t ipa_host_info_next(struct tevent_req *req, state->attrs, state->map, state->map_num_attrs, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting host info\n")); talloc_zfree(state->cur_filter); @@ -311,7 +312,8 @@ static errno_t ipa_hostgroup_info_next(struct tevent_req *req, state->cur_filter, state->attrs, hostgroup_map, HOSTGROUP_MAP_ATTRS_COUNT, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { DEBUG(SSSDBG_CRIT_FAILURE, ("Error requesting hostgroup info\n")); talloc_zfree(state->cur_filter); diff --git a/src/providers/ipa/ipa_netgroups.c b/src/providers/ipa/ipa_netgroups.c index 647818fa7..5acab31f8 100644 --- a/src/providers/ipa/ipa_netgroups.c +++ b/src/providers/ipa/ipa_netgroups.c @@ -269,7 +269,8 @@ static errno_t ipa_netgr_next_base(struct tevent_req *req) netgr_bases[state->netgr_base_iter]->scope, state->filter, state->attrs, state->opts->netgroup_map, IPA_OPTS_NETGROUP, - state->timeout); + state->timeout, + true); if (!subreq) { return ENOMEM; } @@ -449,7 +450,7 @@ static int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state, bases[state->netgr_base_iter]->basedn, bases[state->netgr_base_iter]->scope, filter, state->attrs, state->opts->netgroup_map, - IPA_OPTS_NETGROUP, state->timeout); + IPA_OPTS_NETGROUP, state->timeout, true); state->current_entity = ENTITY_NG; if (subreq == NULL) { @@ -489,9 +490,8 @@ static int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state, dp_opt_get_string(state->opts->basic, SDAP_USER_SEARCH_BASE), LDAP_SCOPE_SUBTREE, - filter, attrs, - state->opts->user_map, - SDAP_OPTS_USER, state->timeout); + filter, attrs, state->opts->user_map, + SDAP_OPTS_USER, state->timeout, true); state->current_entity = ENTITY_USER; if (subreq == NULL) { @@ -537,9 +537,8 @@ static int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state, subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, bases[state->host_base_iter]->basedn, bases[state->host_base_iter]->scope, - filter, attrs, - state->opts->host_map, - IPA_OPTS_HOST, state->timeout); + filter, attrs, state->opts->host_map, + IPA_OPTS_HOST, state->timeout, true); state->current_entity = ENTITY_HOST; if (subreq == NULL) { diff --git a/src/providers/ipa/ipa_selinux_maps.c b/src/providers/ipa/ipa_selinux_maps.c index 87650f6ce..d642da7d0 100644 --- a/src/providers/ipa/ipa_selinux_maps.c +++ b/src/providers/ipa/ipa_selinux_maps.c @@ -133,7 +133,8 @@ ipa_selinux_get_maps_next(struct tevent_req *req, state->opts->selinuxuser_map, IPA_OPTS_SELINUX_USERMAP, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { return ENOMEM; } diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c index 287ba1254..1e923fd32 100644 --- a/src/providers/ldap/sdap_access.c +++ b/src/providers/ldap/sdap_access.c @@ -940,7 +940,8 @@ static void sdap_access_filter_connect_done(struct tevent_req *subreq) state->filter, NULL, NULL, 0, dp_opt_get_int(state->sdap_ctx->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (subreq == NULL) { DEBUG(1, ("Could not start LDAP communication\n")); state->pam_status = PAM_SYSTEM_ERR; diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index 2b9268de4..306d76227 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -870,7 +870,8 @@ struct tevent_req *sdap_get_rootdse_send(TALLOC_CTX *memctx, "", LDAP_SCOPE_BASE, "(objectclass=*)", attrs, NULL, 0, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { talloc_zfree(req); return NULL; @@ -1023,6 +1024,7 @@ struct sdap_get_generic_ext_state { sdap_parse_cb parse_cb; void *cb_data; + bool allow_paging; }; static errno_t sdap_get_generic_ext_step(struct tevent_req *req); @@ -1045,6 +1047,7 @@ sdap_get_generic_ext_send(TALLOC_CTX *memctx, LDAPControl **clientctrls, int sizelimit, int timeout, + bool allow_paging, sdap_parse_cb parse_cb, void *cb_data) { @@ -1052,6 +1055,7 @@ sdap_get_generic_ext_send(TALLOC_CTX *memctx, struct sdap_get_generic_ext_state *state; struct tevent_req *req; int i; + LDAPControl *control; req = tevent_req_create(memctx, &state, struct sdap_get_generic_ext_state); if (!req) return NULL; @@ -1073,6 +1077,35 @@ sdap_get_generic_ext_send(TALLOC_CTX *memctx, state->cb_data = cb_data; state->clientctrls = clientctrls; + + /* Be extra careful and never allow paging for BASE searches, + * even if requested. + */ + if (scope == LDAP_SCOPE_BASE) { + state->allow_paging = false; + } else { + state->allow_paging = allow_paging; + } + + /* Also check for deref/asq requests and force + * paging on for those requests + */ + /* X-DEREF */ + control = ldap_control_find(LDAP_CONTROL_X_DEREF, + serverctrls, + NULL); + if (control) { + state->allow_paging = true; + } + + /* ASQ */ + control = ldap_control_find(LDAP_SERVER_ASQ_OID, + serverctrls, + NULL); + if (control) { + state->allow_paging = true; + } + for (state->nserverctrls=0; serverctrls && serverctrls[state->nserverctrls]; state->nserverctrls++) ; @@ -1135,6 +1168,7 @@ static errno_t sdap_get_generic_ext_step(struct tevent_req *req) disable_paging = dp_opt_get_bool(state->opts->basic, SDAP_DISABLE_PAGING); if (!disable_paging + && state->allow_paging && sdap_is_control_supported(state->sh, LDAP_CONTROL_PAGEDRESULTS)) { lret = ldap_create_page_control(state->sh->ldap, @@ -1347,7 +1381,8 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, const char **attrs, struct sdap_attr_map *map, int map_num_attrs, - int timeout) + int timeout, + bool allow_paging) { struct tevent_req *req = NULL; struct tevent_req *subreq = NULL; @@ -1361,7 +1396,7 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, subreq = sdap_get_generic_ext_send(state, ev, opts, sh, search_base, scope, filter, attrs, false, NULL, - NULL, 0, timeout, + NULL, 0, timeout, allow_paging, sdap_get_generic_parse_entry, state); if (!subreq) { talloc_zfree(req); @@ -1495,7 +1530,7 @@ sdap_x_deref_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, subreq = sdap_get_generic_ext_send(state, ev, opts, sh, base_dn, LDAP_SCOPE_BASE, NULL, attrs, false, state->ctrls, NULL, 0, timeout, - sdap_x_deref_parse_entry, + true, sdap_x_deref_parse_entry, state); if (!subreq) { talloc_zfree(req); @@ -1720,7 +1755,7 @@ sdap_asq_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, subreq = sdap_get_generic_ext_send(state, ev, opts, sh, base_dn, LDAP_SCOPE_BASE, NULL, attrs, false, state->ctrls, NULL, 0, timeout, - sdap_asq_search_parse_entry, + true, sdap_asq_search_parse_entry, state); if (!subreq) { talloc_zfree(req); diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index 47d101492..870f15310 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -171,7 +171,8 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, const char **attrs, struct sdap_attr_map *map, int map_num_attrs, - int timeout); + int timeout, + bool allow_paging); int sdap_get_generic_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, size_t *reply_count, struct sysdb_attrs ***reply_list); diff --git a/src/providers/ldap/sdap_async_autofs.c b/src/providers/ldap/sdap_async_autofs.c index 9025fe993..ea034c2f5 100644 --- a/src/providers/ldap/sdap_async_autofs.c +++ b/src/providers/ldap/sdap_async_autofs.c @@ -309,7 +309,7 @@ automntmaps_process_members_next_base(struct tevent_req *req) state->filter, state->attrs, state->opts->autofs_entry_map, SDAP_OPTS_AUTOFS_ENTRY, - state->timeout); + state->timeout, true); if (!subreq) { DEBUG(SSSDBG_CRIT_FAILURE, ("Cannot start search for entries\n")); return EIO; @@ -492,7 +492,8 @@ sdap_get_automntmap_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->autofs_mobject_map, SDAP_OPTS_AUTOFS_MAP, - state->timeout); + state->timeout, + false); if (!subreq) { return EIO; } diff --git a/src/providers/ldap/sdap_async_groups.c b/src/providers/ldap/sdap_async_groups.c index aefe35385..d58ed468c 100644 --- a/src/providers/ldap/sdap_async_groups.c +++ b/src/providers/ldap/sdap_async_groups.c @@ -746,7 +746,8 @@ sdap_process_missing_member_2307bis(struct tevent_req *req, grp_state->opts->user_map, SDAP_OPTS_USER, dp_opt_get_int(grp_state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { return ENOMEM; } @@ -1109,7 +1110,8 @@ next: state->opts->user_map, SDAP_OPTS_USER, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { tevent_req_error(req, ENOMEM); return; @@ -1258,7 +1260,8 @@ static errno_t sdap_get_groups_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, - state->timeout); + state->timeout, + state->enumeration); /* If we're enumerating, we need paging */ if (!subreq) { return ENOMEM; } @@ -2537,7 +2540,8 @@ static errno_t sdap_nested_group_lookup_user(struct tevent_req *req, state->opts->user_map, SDAP_OPTS_USER, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { talloc_free(sdap_attrs); return EIO; @@ -2618,7 +2622,8 @@ static errno_t sdap_nested_group_lookup_group(struct tevent_req *req) state->opts->group_map, SDAP_OPTS_GROUP, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { talloc_free(sdap_attrs); return EIO; diff --git a/src/providers/ldap/sdap_async_initgroups.c b/src/providers/ldap/sdap_async_initgroups.c index 683e51166..2f8e1ef62 100644 --- a/src/providers/ldap/sdap_async_initgroups.c +++ b/src/providers/ldap/sdap_async_initgroups.c @@ -380,7 +380,8 @@ static errno_t sdap_initgr_rfc2307_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, - state->timeout); + state->timeout, + true); if (!subreq) { return ENOMEM; } @@ -774,7 +775,8 @@ static errno_t sdap_initgr_nested_noderef_search(struct tevent_req *req) state->filter, state->grp_attrs, state->opts->group_map, SDAP_OPTS_GROUP, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { return ENOMEM; } @@ -904,7 +906,8 @@ static void sdap_initgr_nested_search(struct tevent_req *subreq) state->opts->group_map, SDAP_OPTS_GROUP, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { tevent_req_error(req, ENOMEM); return; @@ -1510,7 +1513,8 @@ static errno_t sdap_initgr_rfc2307bis_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, - state->timeout); + state->timeout, + true); if (!subreq) { talloc_zfree(req); return ENOMEM; @@ -2154,7 +2158,8 @@ static errno_t rfc2307bis_nested_groups_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, - state->timeout); + state->timeout, + true); if (!subreq) { return ENOMEM; } @@ -2472,7 +2477,8 @@ static errno_t sdap_get_initgr_next_base(struct tevent_req *req) state->user_search_bases[state->user_base_iter]->scope, state->filter, state->user_attrs, state->opts->user_map, SDAP_OPTS_USER, - state->timeout); + state->timeout, + false); if (!subreq) { return ENOMEM; } diff --git a/src/providers/ldap/sdap_async_netgroups.c b/src/providers/ldap/sdap_async_netgroups.c index 37aa2f112..931a1f86a 100644 --- a/src/providers/ldap/sdap_async_netgroups.c +++ b/src/providers/ldap/sdap_async_netgroups.c @@ -432,7 +432,8 @@ static errno_t netgr_translate_members_ldap_step(struct tevent_req *req) cn_attr, state->opts->netgroup_map, SDAP_OPTS_NETGROUP, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { DEBUG(1, ("sdap_get_generic_send failed.\n")); return ENOMEM; @@ -621,7 +622,8 @@ static errno_t sdap_get_netgroups_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->netgroup_map, SDAP_OPTS_NETGROUP, - state->timeout); + state->timeout, + false); if (!subreq) { return ENOMEM; } diff --git a/src/providers/ldap/sdap_async_services.c b/src/providers/ldap/sdap_async_services.c index 5bc044630..783861c70 100644 --- a/src/providers/ldap/sdap_async_services.c +++ b/src/providers/ldap/sdap_async_services.c @@ -148,7 +148,8 @@ sdap_get_services_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->service_map, SDAP_OPTS_SERVICES, - state->timeout); + state->timeout, + state->enumeration); /* If we're enumerating, we need paging */ if (!subreq) { return ENOMEM; } diff --git a/src/providers/ldap/sdap_async_users.c b/src/providers/ldap/sdap_async_users.c index a8595ac89..57540749c 100644 --- a/src/providers/ldap/sdap_async_users.c +++ b/src/providers/ldap/sdap_async_users.c @@ -477,7 +477,8 @@ static errno_t sdap_get_users_next_base(struct tevent_req *req) state->search_bases[state->base_iter]->scope, state->filter, state->attrs, state->opts->user_map, SDAP_OPTS_USER, - state->timeout); + state->timeout, + state->enumeration); /* If we're enumerating, we need paging */ if (!subreq) { return ENOMEM; } diff --git a/src/providers/ldap/sdap_sudo.c b/src/providers/ldap/sdap_sudo.c index 4aaf04ced..02d4f17bc 100644 --- a/src/providers/ldap/sdap_sudo.c +++ b/src/providers/ldap/sdap_sudo.c @@ -514,7 +514,8 @@ static errno_t sdap_sudo_load_sudoers_next_base(struct tevent_req *req) state->attrs, state->opts->sudorule_map, SDAP_OPTS_SUDO, - state->timeout); + state->timeout, + true); if (subreq == NULL) { return ENOMEM; } -- cgit