>From 2958bf480c08bd4e7393444e57ad57ade27929bd Mon Sep 17 00:00:00 2001 From: Stephen Gallagher Date: Tue, 23 Apr 2013 22:59:48 +0200 Subject: [PATCH] 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. --- src/providers/ipa/ipa_auth.c | 3 ++- src/providers/ipa/ipa_hbac_hosts.c | 12 ++++++--- src/providers/ipa/ipa_hbac_rules.c | 3 ++- src/providers/ipa/ipa_hbac_services.c | 6 +++-- src/providers/ldap/ldap_id.c | 6 +++-- src/providers/ldap/ldap_id_enum.c | 6 +++-- src/providers/ldap/sdap_access.c | 3 ++- src/providers/ldap/sdap_async.c | 19 ++++++++++--- src/providers/ldap/sdap_async.h | 9 ++++--- src/providers/ldap/sdap_async_accounts.c | 44 +++++++++++++++++++++---------- src/providers/ldap/sdap_async_netgroups.c | 5 ++-- 11 files changed, 81 insertions(+), 35 deletions(-) diff --git a/src/providers/ipa/ipa_auth.c b/src/providers/ipa/ipa_auth.c index d8d8ad5aeea65586cd7a4a8f072fefd60f1849ff..3b125e30d8ca7eafa9572eb7459fd17f5de00878 100644 --- a/src/providers/ipa/ipa_auth.c +++ b/src/providers/ipa/ipa_auth.c @@ -155,7 +155,8 @@ static void get_password_migration_flag_auth_done(struct tevent_req *subreq) state->sh, search_base, LDAP_SCOPE_SUBTREE, IPA_CONFIG_FILTER, attrs, NULL, 0, dp_opt_get_int(state->sdap_auth_ctx->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { tevent_req_error(req, ENOMEM); return; diff --git a/src/providers/ipa/ipa_hbac_hosts.c b/src/providers/ipa/ipa_hbac_hosts.c index 5626bd22e8e34b2f4e464d81566be6bc78fd80bd..667cf90661ecdd7920c2a3172e9b26aa12afe722 100644 --- a/src/providers/ipa/ipa_hbac_hosts.c +++ b/src/providers/ipa/ipa_hbac_hosts.c @@ -125,7 +125,8 @@ ipa_hbac_host_info_send(TALLOC_CTX *mem_ctx, LDAP_SCOPE_SUB, host_filter, state->attrs, NULL, 0, dp_opt_get_int(opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { DEBUG(1, ("Error requesting host info\n")); ret = EIO; @@ -211,7 +212,8 @@ ipa_hbac_host_info_done(struct tevent_req *subreq) hostgroup_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(1, ("Error requesting host info\n")); goto error; @@ -372,7 +374,8 @@ ipa_hbac_get_hostgroups_send(TALLOC_CTX *mem_ctx, LDAP_SCOPE_BASE, NULL, state->attrs, hostgroup_map, HOSTGROUP_MAP_ATTRS_COUNT, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + false); if (!subreq) { ret = ENOMEM; goto error; @@ -437,7 +440,8 @@ next: LDAP_SCOPE_BASE, NULL, state->attrs, hostgroup_map, HOSTGROUP_MAP_ATTRS_COUNT, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + false); if (!subreq) { ret = ENOMEM; goto done; diff --git a/src/providers/ipa/ipa_hbac_rules.c b/src/providers/ipa/ipa_hbac_rules.c index 43e1e42634ac638324f3bc0d6e99e9814a283924..1818a5c1d00b2aa8e11d83cdbdf4e8d5c619ac4d 100644 --- a/src/providers/ipa/ipa_hbac_rules.c +++ b/src/providers/ipa/ipa_hbac_rules.c @@ -162,7 +162,8 @@ ipa_hbac_rule_info_send(TALLOC_CTX *mem_ctx, LDAP_SCOPE_SUB, rule_filter, rule_attrs, NULL, 0, dp_opt_get_int(state->opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { DEBUG(1, ("sdap_get_generic_send failed.\n")); ret = ENOMEM; diff --git a/src/providers/ipa/ipa_hbac_services.c b/src/providers/ipa/ipa_hbac_services.c index d5390e51964b32973a9de86e56d3e1a5b36d7247..b636576ad6cdddf2591e49c6c401e7035802c6bc 100644 --- a/src/providers/ipa/ipa_hbac_services.c +++ b/src/providers/ipa/ipa_hbac_services.c @@ -98,7 +98,8 @@ ipa_hbac_service_info_send(TALLOC_CTX *mem_ctx, LDAP_SCOPE_SUB, service_filter, state->attrs, NULL, 0, dp_opt_get_int(opts->basic, - SDAP_ENUM_SEARCH_TIMEOUT)); + SDAP_ENUM_SEARCH_TIMEOUT), + true); if (subreq == NULL) { DEBUG(1, ("Error requesting service info\n")); ret = EIO; @@ -170,7 +171,8 @@ ipa_hbac_service_info_done(struct tevent_req *subreq) state->search_base, LDAP_SCOPE_SUB, servicegroup_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(1, ("Error requesting host info\n")); ret = EIO; diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 709f2ca0527572b1234ae5c965fc3ffdbee165c1..02f55d8b913a55b3cdba34298d80fe3ee860318e 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -171,7 +171,8 @@ static void users_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); /* No enumeration */ if (!subreq) { tevent_req_error(req, ENOMEM); return; @@ -407,7 +408,8 @@ static void groups_get_connect_done(struct tevent_req *subreq) state->ctx->opts, 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); /* No enumeration */ 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 2e47722a1a7b90adfed92c18f033c889d38b7fe9..5817765871cc2fa3e88e288973022c6c7b60cf63 100644 --- a/src/providers/ldap/ldap_id_enum.c +++ b/src/providers/ldap/ldap_id_enum.c @@ -479,7 +479,8 @@ static struct tevent_req *enum_users_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); /* Enumeration */ if (!subreq) { ret = ENOMEM; goto fail; @@ -589,7 +590,8 @@ static struct tevent_req *enum_groups_send(TALLOC_CTX *memctx, state->ctx->opts, 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); /* Enumeration */ if (!subreq) { ret = ENOMEM; goto fail; diff --git a/src/providers/ldap/sdap_access.c b/src/providers/ldap/sdap_access.c index 8757510c37b0ed4328d8c23d624b8a03ee9bcc35..712c76f5e1efa99c5a7def6226d126ef252dca5f 100644 --- a/src/providers/ldap/sdap_access.c +++ b/src/providers/ldap/sdap_access.c @@ -745,7 +745,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 3202f015223538ef1e00fc005441f1feac2a18a1..640ee66bf89fd30079ac1a273c093537964bdefb 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -681,7 +681,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; @@ -757,6 +758,7 @@ struct sdap_get_generic_state { struct sdap_attr_map *map; int map_num_attrs; int timeout; + bool allow_paging; struct sdap_op *op; @@ -784,7 +786,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) { errno_t ret; struct sdap_get_generic_state *state; @@ -810,6 +813,15 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, state->cookie.bv_len = 0; state->cookie.bv_val = NULL; + /* 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; + } + ret = sdap_get_generic_step(req); if (ret != EOK) { tevent_req_error(req, ret); @@ -851,7 +863,8 @@ static errno_t sdap_get_generic_step(struct tevent_req *req) } } - if (sdap_is_control_supported(state->sh, + if (state->allow_paging && + sdap_is_control_supported(state->sh, LDAP_CONTROL_PAGEDRESULTS)) { lret = ldap_create_page_control(state->sh->ldap, state->sh->page_size, diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index 346940b0000e46c758c01fdb87e4354b8b3a655a..5c011b301d5a0dd442f5297c8c45ebdac2857da0 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -48,7 +48,8 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, struct sdap_handle *sh, const char **attrs, const char *wildcard, - int timeout); + int timeout, + bool enumeration); int sdap_get_users_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **timestamp); @@ -60,7 +61,8 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, struct sdap_handle *sh, const char **attrs, const char *wildcard, - int timeout); + int timeout, + bool enumeration); int sdap_get_groups_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, char **timestamp); @@ -147,7 +149,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_accounts.c b/src/providers/ldap/sdap_async_accounts.c index 8fdadb1b2dbef7ccc49b175c4547593f5542e25b..f4a460af97e4d2ac759ab213ceda764cba31ed51 100644 --- a/src/providers/ldap/sdap_async_accounts.c +++ b/src/providers/ldap/sdap_async_accounts.c @@ -428,6 +428,7 @@ struct sdap_get_users_state { struct sysdb_ctx *sysdb; const char **attrs; const char *filter; + bool enumeration; char *higher_usn; struct sysdb_attrs **users; @@ -444,7 +445,8 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, struct sdap_handle *sh, const char **attrs, const char *filter, - int timeout) + int timeout, + bool enumeration) { struct tevent_req *req, *subreq; struct sdap_get_users_state *state; @@ -462,6 +464,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, state->higher_usn = NULL; state->users = NULL; state->count = 0; + state->enumeration = enumeration; subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, dp_opt_get_string(state->opts->basic, @@ -469,7 +472,7 @@ struct tevent_req *sdap_get_users_send(TALLOC_CTX *memctx, LDAP_SCOPE_SUBTREE, state->filter, state->attrs, state->opts->user_map, SDAP_OPTS_USER, - timeout); + timeout, state->enumeration); if (!subreq) { talloc_zfree(req); return NULL; @@ -1458,7 +1461,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; } @@ -1659,7 +1663,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; @@ -1711,6 +1716,7 @@ struct sdap_get_groups_state { struct sysdb_ctx *sysdb; const char **attrs; const char *filter; + bool enumeration; char *higher_usn; struct sysdb_attrs **groups; @@ -1732,7 +1738,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) { struct tevent_req *req, *subreq; struct sdap_get_groups_state *state; @@ -1750,6 +1757,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, state->higher_usn = NULL; state->groups = NULL; state->count = 0; + state->enumeration = enumeration; subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh, dp_opt_get_string(state->opts->basic, @@ -1757,7 +1765,7 @@ struct tevent_req *sdap_get_groups_send(TALLOC_CTX *memctx, LDAP_SCOPE_SUBTREE, state->filter, state->attrs, state->opts->group_map, SDAP_OPTS_GROUP, - timeout); + timeout, state->enumeration); if (!subreq) { talloc_zfree(req); return NULL; @@ -2320,7 +2328,8 @@ struct tevent_req *sdap_initgr_rfc2307_send(TALLOC_CTX *memctx, filter, attrs, state->opts->group_map, SDAP_OPTS_GROUP, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + true); if (!subreq) { talloc_zfree(req); return NULL; @@ -2646,7 +2655,8 @@ static struct tevent_req *sdap_initgr_nested_send(TALLOC_CTX *memctx, 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) { talloc_zfree(req); return NULL; @@ -2696,7 +2706,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; @@ -3243,7 +3254,8 @@ struct tevent_req *sdap_get_initgr_send(TALLOC_CTX *memctx, filter, state->ldap_attrs, state->opts->user_map, SDAP_OPTS_USER, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + false); if (!subreq) { talloc_zfree(req); return NULL; @@ -3835,7 +3847,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; @@ -3878,7 +3891,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; @@ -4242,7 +4256,8 @@ static struct tevent_req *sdap_initgr_rfc2307bis_send( filter, attrs, state->opts->group_map, SDAP_OPTS_GROUP, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + true); if (!subreq) { talloc_zfree(req); return NULL; @@ -4820,7 +4835,8 @@ static errno_t rfc2307bis_nested_groups_step(struct tevent_req *req) filter, attrs, state->opts->group_map, SDAP_OPTS_GROUP, dp_opt_get_int(state->opts->basic, - SDAP_SEARCH_TIMEOUT)); + SDAP_SEARCH_TIMEOUT), + true); if (!subreq) { ret = EIO; goto error; diff --git a/src/providers/ldap/sdap_async_netgroups.c b/src/providers/ldap/sdap_async_netgroups.c index 1f6c6d063d09d8715f91a3fb43876004fb148418..36dcd40d90b7b4ec24d7c8c83e933f5fe17721d2 100644 --- a/src/providers/ldap/sdap_async_netgroups.c +++ b/src/providers/ldap/sdap_async_netgroups.c @@ -469,7 +469,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; @@ -610,7 +611,7 @@ struct tevent_req *sdap_get_netgroups_send(TALLOC_CTX *memctx, LDAP_SCOPE_SUBTREE, state->filter, state->attrs, state->opts->netgroup_map, - SDAP_OPTS_NETGROUP, timeout); + SDAP_OPTS_NETGROUP, timeout, false); if (!subreq) { talloc_zfree(req); return NULL; -- 1.8.1.4