[SSSD] [PATCH] LDAP: Only use paging control on requests for multiple entries (1.5 backport)

Jakub Hrozek jhrozek at redhat.com
Mon Apr 29 14:50:14 UTC 2013


On Mon, Apr 29, 2013 at 04:43:36PM +0200, Jakub Hrozek wrote:
> On Mon, Apr 29, 2013 at 03:28:33PM +0200, Lukas Slebodnik wrote:
> > On (24/04/13 23:59), Jakub Hrozek wrote:
> > >On Wed, Apr 24, 2013 at 11:56:48PM +0200, Jakub Hrozek wrote:
> > >> This is a backport of Stephen's patch
> > >> 2f3ee3f49019f5b60adbe073070f31e6e2d7c7ab for the 1.5 branch. A customer
> > >> running RHEL5 was hit by the issue so a backport was needed for the
> > >> sssd-1-5 branch as well.
> > >
> > >The subject should say this is a 1.5 backport only.
> > 
> > You should also backport 8270b1b8505e4bce5ec065daa8fcdf985e1fc9f5
> > "LDAP: Add option to disable paging control"
> > 
> > LS
> 
> Yes, it's not strictly necessary but might come handy. New patches are
> attached.

One more patch is attached to amend the man page.
-------------- next part --------------
>From 5eda1a79323ab6d7d2a685685095bf8d3ad25ae1 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh at redhat.com>
Date: Mon, 16 Jan 2012 16:27:01 -0500
Subject: [PATCH 1/3] LDAP: Add option to disable paging control

Fixes https://fedorahosted.org/sssd/ticket/967

Conflicts:

	src/config/SSSDConfig.py
	src/config/etc/sssd.api.d/sssd-ipa.conf
	src/config/etc/sssd.api.d/sssd-ldap.conf
	src/man/sssd-ldap.5.xml
	src/providers/ipa/ipa_common.c
	src/providers/ipa/ipa_common.h
	src/providers/ldap/ldap_common.c
	src/providers/ldap/sdap.h
---
 src/config/SSSDConfig.py                 |  2 ++
 src/config/etc/sssd.api.d/sssd-ipa.conf  |  1 +
 src/config/etc/sssd.api.d/sssd-ldap.conf |  1 +
 src/man/sssd-ldap.5.xml                  | 24 ++++++++++++++++++++++++
 src/providers/ipa/ipa_common.c           |  3 ++-
 src/providers/ipa/ipa_common.h           |  2 +-
 src/providers/ldap/ldap_common.c         |  3 ++-
 src/providers/ldap/sdap.h                |  1 +
 src/providers/ldap/sdap_async.c          |  8 ++++++--
 9 files changed, 40 insertions(+), 5 deletions(-)

diff --git a/src/config/SSSDConfig.py b/src/config/SSSDConfig.py
index 2f71c7eeca5f5a39e670d217cf42adffc4e79886..a6ef63a6a356aab84edc83460cb30460bf31753e 100644
--- a/src/config/SSSDConfig.py
+++ b/src/config/SSSDConfig.py
@@ -156,6 +156,8 @@ option_strings = {
     'ldap_entry_usn' : _('entryUSN attribute'),
     'ldap_rootdse_last_usn' : _('lastUSN attribute'),
 
+    'ldap_disable_paging' : _('Disable the LDAP paging control'),
+
     # [provider/ldap/id]
     'ldap_search_timeout' : _('Length of time to wait for a search request'),
     'ldap_enumeration_search_timeout' : _('Length of time to wait for a enumeration request'),
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 1a19300a8822d6927901848d26a12f4c16a766d9..e79919066d1b37dab080a516f1060974d34244da 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -35,6 +35,7 @@ ldap_referrals = bool, None, false
 ldap_krb5_ticket_lifetime = int, None, false
 ldap_dns_service_name = str, None, false
 ldap_deref = str, None, false
+ldap_disable_paging = bool, None, false
 
 [provider/ipa/id]
 ldap_search_timeout = int, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index d84ceaed51161a133741ecca7231656f901f2fb7..a386aa42dd50dd41986b339c4ba801878219f3e2 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -29,6 +29,7 @@ ldap_dns_service_name = str, None, false
 ldap_deref = str, None, false
 ldap_page_size = int, None, false
 ldap_sasl_canonicalize = bool, None, false
+ldap_disable_paging = 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 271efd4dd617923cc1a0dd5dff33156d399004d1..55dc3f9cb864115c020d319ca7c571598dfcc280 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -864,6 +864,30 @@
                 </varlistentry>
 
                 <varlistentry>
+                    <term>ldap_disable_paging</term>
+                    <listitem>
+                        <para>
+                            Disable the LDAP paging control. This option
+                            should be used if the LDAP server reports that it
+                            supports the LDAP paging control in its RootDSE
+                            but it is not enabled or does not behave properly.
+                        </para>
+                        <para>
+                            Example: OpenLDAP servers with the paging control
+                            module installed on the server but not enabled
+                            will report it in the RootDSE but be unable to use
+                            it.
+                        </para>
+                        <para>
+                            Example: 389 DS has a bug where it can only
+                            support a one paging control at a time on a single
+                            connection. On busy clients, this can result in
+                            some requests being denied.
+                        </para>
+                    </listitem>
+                </varlistentry>
+                
+                <varlistentry>
                     <term>ldap_tls_reqcert (string)</term>
                     <listitem>
                         <para>
diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 5be1fc08b319f450243fd1e3434938aedebab162..3176e54653cf93c5be717e3b57c237d536a0863d 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -96,7 +96,8 @@ struct dp_option ipa_def_ldap_opts[] = {
      */
     { "ldap_auth_disable_tls_never_use_in_production", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
     { "ldap_page_size", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER },
-    { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }
+    { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+    { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }
 };
 
 struct sdap_attr_map ipa_attr_map[] = {
diff --git a/src/providers/ipa/ipa_common.h b/src/providers/ipa/ipa_common.h
index 08a3ddef09519adcb33aabefc7842b7be6f06db8..0bfe054b4bb2be163ae52797409a1c2531035579 100644
--- a/src/providers/ipa/ipa_common.h
+++ b/src/providers/ipa/ipa_common.h
@@ -35,7 +35,7 @@ struct ipa_service {
 /* the following defines are used to keep track of the options in the ldap
  * module, so that if they change and ipa is not updated correspondingly
  * this will trigger a runtime abort error */
-#define IPA_OPTS_BASIC_TEST 50
+#define IPA_OPTS_BASIC_TEST 51
 
 /* the following define is used to keep track of the options in the krb5
  * module, so that if they change and ipa is not updated correspondingly
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c
index 253cf25db3b68c74e64bcd948d81abab7f991812..0fc61ea0ad5deae523f6e0993f9427bed384bd55 100644
--- a/src/providers/ldap/ldap_common.c
+++ b/src/providers/ldap/ldap_common.c
@@ -87,7 +87,8 @@ struct dp_option default_basic_opts[] = {
      */
     { "ldap_auth_disable_tls_never_use_in_production", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
     { "ldap_page_size", DP_OPT_NUMBER, { .number = 1000 }, NULL_NUMBER },
-    { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }
+    { "ldap_sasl_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE },
+    { "ldap_disable_paging", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }
 };
 
 struct sdap_attr_map generic_attr_map[] = {
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 44b2eab1ce0743f6d03d4bb38a8e8f8266b0dd12..ffde57a407bae7b7cb60ebb356081e3b95c70a3c 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -196,6 +196,7 @@ enum sdap_basic_opt {
     SDAP_DISABLE_AUTH_TLS,
     SDAP_PAGE_SIZE,
     SDAP_SASL_CANONICALIZE,
+    SDAP_DISABLE_PAGING,
 
     SDAP_OPTS_BASIC /* opts counter */
 };
diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c
index 3202f015223538ef1e00fc005441f1feac2a18a1..6412666d040683e6dff5094abc63f23d0c46307a 100644
--- a/src/providers/ldap/sdap_async.c
+++ b/src/providers/ldap/sdap_async.c
@@ -829,6 +829,7 @@ static errno_t sdap_get_generic_step(struct tevent_req *req)
     int optret;
     errno_t ret;
     int msgid;
+    bool disable_paging;
 
     LDAPControl *page_control = NULL;
     LDAPControl *m_controls[2] = { NULL, NULL };
@@ -851,8 +852,11 @@ static errno_t sdap_get_generic_step(struct tevent_req *req)
         }
     }
 
-    if (sdap_is_control_supported(state->sh,
-                                  LDAP_CONTROL_PAGEDRESULTS)) {
+    disable_paging = dp_opt_get_bool(state->opts->basic, SDAP_DISABLE_PAGING);
+
+    if (!disable_paging
+            && sdap_is_control_supported(state->sh,
+                                         LDAP_CONTROL_PAGEDRESULTS)) {
         lret = ldap_create_page_control(state->sh->ldap,
                                         state->sh->page_size,
                                         state->cookie.bv_val ?
-- 
1.8.1.4

-------------- next part --------------
>From 7d736f95e4bad4a34eab42612a893b536d21cdd1 Mon Sep 17 00:00:00 2001
From: Stephen Gallagher <sgallagh at redhat.com>
Date: Mon, 9 Apr 2012 14:40:20 -0400
Subject: [PATCH 2/3] MAN: Improve ldap_disable_paging documentation

---
 src/man/sssd-ldap.5.xml | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 55dc3f9cb864115c020d319ca7c571598dfcc280..9e0695f6bdfabbfe48acac8c653a6576697d6815 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -864,7 +864,7 @@
                 </varlistentry>
 
                 <varlistentry>
-                    <term>ldap_disable_paging</term>
+                    <term>ldap_disable_paging (boolean)</term>
                     <listitem>
                         <para>
                             Disable the LDAP paging control. This option
@@ -884,6 +884,9 @@
                             connection. On busy clients, this can result in
                             some requests being denied.
                         </para>
+                        <para>
+                            Default: False
+                        </para>
                     </listitem>
                 </varlistentry>
                 
-- 
1.8.1.4

-------------- next part --------------
>From 8cd7248d1a74d5c7f3b3750b50b3b3eb26886603 Mon Sep 17 00:00:00 2001
From: Jakub Hrozek <jhrozek at redhat.com>
Date: Mon, 29 Apr 2013 16:42:46 +0200
Subject: [PATCH 3/3] 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           | 22 ++++++++++++----
 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, 82 insertions(+), 37 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 6412666d040683e6dff5094abc63f23d0c46307a..1547e88505afe1e81470ff84d2700ad6a841c9cb 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);
@@ -854,9 +866,9 @@ static errno_t sdap_get_generic_step(struct tevent_req *req)
 
     disable_paging = dp_opt_get_bool(state->opts->basic, SDAP_DISABLE_PAGING);
 
-    if (!disable_paging
-            && sdap_is_control_supported(state->sh,
-                                         LDAP_CONTROL_PAGEDRESULTS)) {
+    if (!disable_paging && state->allow_paging &&
+        sdap_is_control_supported(state->sh,
+                                  LDAP_CONTROL_PAGEDRESULTS)) {
         lret = ldap_create_page_control(state->sh->ldap,
                                         state->sh->page_size,
                                         state->cookie.bv_val ?
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



More information about the sssd-devel mailing list