From 6263578b03a52b3ec3a2e33e097554241780fc20 Mon Sep 17 00:00:00 2001 From: Lukas Slebodnik Date: Tue, 14 May 2013 18:00:10 +0200 Subject: Adding option to disable retrieving large AD groups. This commit adds new option ldap_disable_range_retrieval with default value FALSE. If this option is enabled, large groups(>1500) will not be retrieved and behaviour will be similar like was before commit ae8d047122c "LDAP: Handle very large Active Directory groups" https://fedorahosted.org/sssd/ticket/1823 --- src/config/SSSDConfig/__init__.py.in | 1 + src/config/etc/sssd.api.d/sssd-ldap.conf | 1 + src/man/sssd-ldap.5.xml | 21 +++++++++++++++++++++ src/providers/ad/ad_opts.h | 1 + src/providers/ipa/ipa_opts.h | 1 + src/providers/ldap/ldap_opts.h | 1 + src/providers/ldap/sdap.c | 26 ++++++++++++++++++-------- src/providers/ldap/sdap.h | 4 +++- src/providers/ldap/sdap_async.c | 15 +++++++++++++-- src/providers/ldap/sdap_range.c | 13 ++++++++++++- src/providers/ldap/sdap_range.h | 3 ++- 11 files changed, 74 insertions(+), 13 deletions(-) (limited to 'src') diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in index bc7bb0a78..8e1142f2a 100644 --- a/src/config/SSSDConfig/__init__.py.in +++ b/src/config/SSSDConfig/__init__.py.in @@ -221,6 +221,7 @@ option_strings = { 'ldap_connection_expiration_timeout' : _('How long to retain a connection to the LDAP server before disconnecting'), 'ldap_disable_paging' : _('Disable the LDAP paging control'), + 'ldap_disable_range_retrieval' : _('Disable Active Directory range retrieval'), # [provider/ldap/id] 'ldap_search_timeout' : _('Length of time to wait for a search request'), diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf index 40e2aa09d..14e979da3 100644 --- a/src/config/etc/sssd.api.d/sssd-ldap.conf +++ b/src/config/etc/sssd.api.d/sssd-ldap.conf @@ -35,6 +35,7 @@ ldap_sasl_canonicalize = bool, None, false ldap_sasl_minssf = int, None, false ldap_connection_expire_timeout = int, None, false ldap_disable_paging = bool, None, false +ldap_disable_range_retrieval = bool, None, false [provider/ldap/id] ldap_search_timeout = int, None, false diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml index 799213300..37df5ec1b 100644 --- a/src/man/sssd-ldap.5.xml +++ b/src/man/sssd-ldap.5.xml @@ -1200,6 +1200,27 @@ + + ldap_disable_range_retrieval (boolean) + + + Disable Active Directory range retrieval. + + + Active Directory limits the number of members to be + retrieved in a single lookup using the MaxValRange + policy (which defaults to 1500 members). If a group + contains more members, the reply would include an + AD-specific range extension. This option disables + parsing of the range extension, therefore large + groups will appear as having no members. + + + Default: False + + + + ldap_sasl_minssf (integer) diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h index 6e9d843c1..218614dca 100644 --- a/src/providers/ad/ad_opts.h +++ b/src/providers/ad/ad_opts.h @@ -122,6 +122,7 @@ struct dp_option ad_def_ldap_opts[] = { { "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, + { "ldap_disable_range_retrieval", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, DP_OPTION_TERMINATOR }; diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h index de9592b85..57b17e5a1 100644 --- a/src/providers/ipa/ipa_opts.h +++ b/src/providers/ipa/ipa_opts.h @@ -146,6 +146,7 @@ struct dp_option ipa_def_ldap_opts[] = { { "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, + { "ldap_disable_range_retrieval", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, DP_OPTION_TERMINATOR }; diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h index 2ed89f977..807716c18 100644 --- a/src/providers/ldap/ldap_opts.h +++ b/src/providers/ldap/ldap_opts.h @@ -113,6 +113,7 @@ struct dp_option default_basic_opts[] = { { "ldap_groups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_initgroups_use_matching_rule_in_chain", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, { "ldap_rfc2307_fallback_to_local_users", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, + { "ldap_disable_range_retrieval", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, DP_OPTION_TERMINATOR }; diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index 3a820f62f..daa081ce7 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -95,7 +95,8 @@ int sdap_get_map(TALLOC_CTX *memctx, int sdap_parse_entry(TALLOC_CTX *memctx, struct sdap_handle *sh, struct sdap_msg *sm, struct sdap_attr_map *map, int attrs_num, - struct sysdb_attrs **_attrs, char **_dn) + struct sysdb_attrs **_attrs, char **_dn, + bool disable_range_retrieval) { struct sysdb_attrs *attrs; BerElement *ber = NULL; @@ -190,23 +191,27 @@ int sdap_parse_entry(TALLOC_CTX *memctx, while (str) { base64 = false; - ret = sdap_parse_range(tmp_ctx, str, &base_attr, &range_offset); - if (ret == EAGAIN) { + ret = sdap_parse_range(tmp_ctx, str, &base_attr, &range_offset, + disable_range_retrieval); + switch(ret) { + case EAGAIN: /* This attribute contained range values and needs more to * be retrieved */ /* TODO: return the set of attributes that need additional retrieval * For now, we'll continue below and treat it as regular values. */ - - } else if (ret != EOK) { + /* FALLTHROUGH */ + case ECANCELED: + /* FALLTHROUGH */ + case EOK: + break; + default: DEBUG(SSSDBG_MINOR_FAILURE, - ("Could not determine if attribute [%s] was ranged\n", - str)); + ("Could not determine if attribute [%s] was ranged\n", str)); goto done; } - if (map) { for (a = 1; a < attrs_num; a++) { /* check if this attr is valid with the chosen schema */ @@ -230,6 +235,11 @@ int sdap_parse_entry(TALLOC_CTX *memctx, store = true; } + if (ret == ECANCELED) { + ret = EOK; + store = false; + } + if (store) { vals = ldap_get_values_len(sh->ldap, sm->msg, str); if (!vals) { diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 4c9023fe8..162250fff 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -217,6 +217,7 @@ enum sdap_basic_opt { SDAP_AD_MATCHING_RULE_GROUPS, SDAP_AD_MATCHING_RULE_INITGROUPS, SDAP_RFC2307_FALLBACK_TO_LOCAL_USERS, + SDAP_DISABLE_RANGE_RETRIEVAL, SDAP_OPTS_BASIC /* opts counter */ }; @@ -433,7 +434,8 @@ int sdap_get_map(TALLOC_CTX *memctx, int sdap_parse_entry(TALLOC_CTX *memctx, struct sdap_handle *sh, struct sdap_msg *sm, struct sdap_attr_map *map, int attrs_num, - struct sysdb_attrs **_attrs, char **_dn); + struct sysdb_attrs **_attrs, char **_dn, + bool disable_range_retrieval); errno_t sdap_parse_deref(TALLOC_CTX *mem_ctx, struct sdap_attr_map_info *minfo, diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index 5eac1d436..b2bf0360e 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -1469,6 +1469,7 @@ struct sdap_get_generic_state { int map_num_attrs; struct sdap_reply sreply; + struct sdap_options *opts; }; static void sdap_get_generic_done(struct tevent_req *subreq); @@ -1498,6 +1499,7 @@ struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, state->map = map; state->map_num_attrs = map_num_attrs; + state->opts = opts; subreq = sdap_get_generic_ext_send(state, ev, opts, sh, search_base, scope, filter, attrs, false, NULL, @@ -1521,9 +1523,12 @@ static errno_t sdap_get_generic_parse_entry(struct sdap_handle *sh, struct sdap_get_generic_state *state = talloc_get_type(pvt, struct sdap_get_generic_state); + bool disable_range_rtrvl = dp_opt_get_bool(state->opts->basic, + SDAP_DISABLE_RANGE_RETRIEVAL); + ret = sdap_parse_entry(state, sh, msg, state->map, state->map_num_attrs, - &attrs, NULL); + &attrs, NULL, disable_range_rtrvl); if (ret != EOK) { DEBUG(3, ("sdap_parse_entry failed [%d]: %s\n", ret, strerror(ret))); return ret; @@ -1811,6 +1816,7 @@ struct sdap_asq_search_state { struct sdap_attr_map_info *maps; int num_maps; LDAPControl **ctrls; + struct sdap_options *opts; struct sdap_deref_reply dreply; }; @@ -1842,6 +1848,7 @@ sdap_asq_search_send(TALLOC_CTX *memctx, struct tevent_context *ev, state->maps = maps; state->num_maps = num_maps; state->ctrls = talloc_zero_array(state, LDAPControl *, 2); + state->opts = opts; if (state->ctrls == NULL) { talloc_zfree(req); return NULL; @@ -1925,6 +1932,7 @@ static errno_t sdap_asq_search_parse_entry(struct sdap_handle *sh, char *tmp; char *dn; TALLOC_CTX *tmp_ctx; + bool disable_range_rtrvl; tmp_ctx = talloc_new(NULL); if (!tmp_ctx) return ENOMEM; @@ -1984,9 +1992,12 @@ static errno_t sdap_asq_search_parse_entry(struct sdap_handle *sh, continue; } + disable_range_rtrvl = dp_opt_get_bool(state->opts->basic, + SDAP_DISABLE_RANGE_RETRIEVAL); + ret = sdap_parse_entry(res[mi], sh, msg, map, num_attrs, - &res[mi]->attrs, NULL); + &res[mi]->attrs, NULL, disable_range_rtrvl); if (ret != EOK) { DEBUG(3, ("sdap_parse_entry failed [%d]: %s\n", ret, strerror(ret))); goto done; diff --git a/src/providers/ldap/sdap_range.c b/src/providers/ldap/sdap_range.c index a26443c82..c4bf43539 100644 --- a/src/providers/ldap/sdap_range.c +++ b/src/providers/ldap/sdap_range.c @@ -29,7 +29,8 @@ errno_t sdap_parse_range(TALLOC_CTX *mem_ctx, const char *attr_desc, char **base_attr, - uint32_t *range_offset) + uint32_t *range_offset, + bool disable_range_retrieval) { errno_t ret; TALLOC_CTX *tmp_ctx; @@ -84,6 +85,16 @@ errno_t sdap_parse_range(TALLOC_CTX *mem_ctx, ("[%s] contains sub-attribute other than a range, returning whole\n", attr_desc)); goto done; + } else if (disable_range_retrieval) { + /* This is range sub-attribute, but we want to ignore it. + */ + *base_attr = talloc_strdup(mem_ctx, attr_desc); + if (!*base_attr) { + ret = ENOMEM; + } else { + ret = ECANCELED; + } + goto done; } /* Get the end of the range */ diff --git a/src/providers/ldap/sdap_range.h b/src/providers/ldap/sdap_range.h index 1dc3ba8f9..f11b3be60 100644 --- a/src/providers/ldap/sdap_range.h +++ b/src/providers/ldap/sdap_range.h @@ -28,6 +28,7 @@ errno_t sdap_parse_range(TALLOC_CTX *mem_ctx, const char *attr_desc, char **base_attr, - uint32_t *range_offset); + uint32_t *range_offset, + bool disable_range_retrieval); #endif /* SDAP_RANGE_H_ */ -- cgit