summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLukas Slebodnik <lslebodn@redhat.com>2013-05-14 18:00:10 +0200
committerJakub Hrozek <jhrozek@redhat.com>2013-08-09 15:04:43 +0200
commit0b9e98122091c5bb6232ea4746decb6fbe2d68c0 (patch)
treeeba8755e80ab04a315a0385d4cea46fac079ebbe /src
parent6ed0eb3bf1b322a246aad6c3e02a7c3b4619d867 (diff)
downloadsssd-0b9e98122091c5bb6232ea4746decb6fbe2d68c0.tar.gz
sssd-0b9e98122091c5bb6232ea4746decb6fbe2d68c0.tar.xz
sssd-0b9e98122091c5bb6232ea4746decb6fbe2d68c0.zip
Adding option to disable retrieving large AD groups.sssd-1.9.2-113.el6
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
Diffstat (limited to 'src')
-rw-r--r--src/config/SSSDConfig/__init__.py.in1
-rw-r--r--src/config/etc/sssd.api.d/sssd-ldap.conf1
-rw-r--r--src/man/sssd-ldap.5.xml21
-rw-r--r--src/providers/ad/ad_opts.h1
-rw-r--r--src/providers/ipa/ipa_opts.h1
-rw-r--r--src/providers/ldap/ldap_opts.h1
-rw-r--r--src/providers/ldap/sdap.c26
-rw-r--r--src/providers/ldap/sdap.h4
-rw-r--r--src/providers/ldap/sdap_async.c15
-rw-r--r--src/providers/ldap/sdap_range.c13
-rw-r--r--src/providers/ldap/sdap_range.h3
11 files changed, 74 insertions, 13 deletions
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 46333e117..9235ebd55 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -209,6 +209,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 562cbd8f2..d5ee221a1 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -1201,6 +1201,27 @@
</varlistentry>
<varlistentry>
+ <term>ldap_disable_range_retrieval (boolean)</term>
+ <listitem>
+ <para>
+ Disable Active Directory range retrieval.
+ </para>
+ <para>
+ 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.
+ </para>
+ <para>
+ Default: False
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ldap_sasl_minssf (integer)</term>
<listitem>
<para>
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index c283f714a..44399104f 100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -121,6 +121,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 2ab9f8898..07960c90d 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -135,6 +135,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 371121b2c..bfe3baa56 100644
--- a/src/providers/ldap/sdap.c
+++ b/src/providers/ldap/sdap.c
@@ -97,7 +97,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;
@@ -192,23 +193,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 */
@@ -232,6 +237,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 5bbf27594..9cf83406b 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -229,6 +229,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 */
};
@@ -445,7 +446,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);
int sdap_parse_user(TALLOC_CTX *memctx, struct sdap_options *opts,
struct sdap_handle *sh, struct sdap_msg *sm,
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index e0440625d..57c11f30c 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_ */