]> git.ipfire.org Git - thirdparty/samba.git/commitdiff
s3:libads: Do not reduce the page size in case of immediate timeouts
authorPavel Filipenský <pfilipensky@samba.org>
Mon, 19 Jan 2026 18:50:37 +0000 (19:50 +0100)
committerAndreas Schneider <asn@cryptomilk.org>
Wed, 21 Jan 2026 11:38:40 +0000 (11:38 +0000)
Signed-off-by: Pavel Filipenský <pfilipensky@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org>
Autobuild-Date(master): Wed Jan 21 11:38:40 UTC 2026 on atb-devel-224

source3/libads/ldap_utils.c

index dee6ea42356f6c372403eace22bc45f0de598132..fd154c6b6e52d73eca3b65b6a714423029fdfa0f 100644 (file)
@@ -52,6 +52,28 @@ static ADS_STATUS ads_ranged_search_internal(ADS_STRUCT *ads,
                                             int *num_retries,
                                             bool *more_values);
 
+/*
+ * Do not reduce the page size in case of immediate timeouts. E.g. kernel
+ * detected broken connection but samba hasn't tried to use the socket yet.
+ * time() uses resolution in seconds, so it is avoided for timeouts < 1s and
+ * might be avoided for timeouts < 2s.
+ */
+static inline void adjust_ldap_page_size(ADS_STRUCT *ads,
+                                        time_t start,
+                                        time_t end)
+{
+       if (ads->config.ldap_page_size >= (lp_ldap_page_size() / 4) &&
+           lp_ldap_page_size() > 4 && end - start > 1)
+       {
+               int new_page_size = (ads->config.ldap_page_size / 2);
+               DBG_WARNING("Reducing LDAP page size from %d to %d due to "
+                           "IO_TIMEOUT\n",
+                           ads->config.ldap_page_size,
+                           new_page_size);
+               ads->config.ldap_page_size = new_page_size;
+       }
+}
+
 /*
   a wrapper around ldap_search_s that retries depending on the error code
   this is supposed to catch dropped connections and auto-reconnect
@@ -64,6 +86,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
        ADS_STATUS status;
        int count = 3;
        char *bp;
+       time_t search_start, search_end;
 
        *res = NULL;
 
@@ -83,6 +106,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
        /* when binding anonymously, we cannot use the paged search LDAP
         * control - Guenther */
 
+       search_start = time(NULL);
        if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
                status = ads_do_search(ads, bp, scope, expr, attrs, res);
        } else {
@@ -100,13 +124,10 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
                char *cred_name = NULL;
                NTSTATUS ntstatus;
 
-               if (NT_STATUS_EQUAL(ads_ntstatus(status), NT_STATUS_IO_TIMEOUT) &&
-                   ads->config.ldap_page_size >= (lp_ldap_page_size() / 4) &&
-                   lp_ldap_page_size() > 4) {
-                       int new_page_size = (ads->config.ldap_page_size / 2);
-                       DEBUG(1, ("Reducing LDAP page size from %d to %d due to IO_TIMEOUT\n",
-                                 ads->config.ldap_page_size, new_page_size));
-                       ads->config.ldap_page_size = new_page_size;
+               search_end = time(NULL);
+               if (NT_STATUS_EQUAL(ads_ntstatus(status), NT_STATUS_IO_TIMEOUT))
+               {
+                       adjust_ldap_page_size(ads, search_start, search_end);
                }
 
                if (*res)
@@ -162,6 +183,7 @@ static ADS_STATUS ads_do_search_retry_internal(ADS_STRUCT *ads, const char *bind
                /* when binding anonymously, we cannot use the paged search LDAP
                 * control - Guenther */
 
+               search_start = time(NULL);
                if (ads->auth.flags & ADS_AUTH_ANON_BIND) {
                        status = ads_do_search(ads, bp, scope, expr, attrs, res);
                } else {