Blame SOURCES/0110-LDAP-failover-does-not-work-on-non-responsive-ldaps.patch

e050a4
From 442cd658329251d8390dd5bd790d86c78ead88ab Mon Sep 17 00:00:00 2001
e050a4
From: Tomas Halman <thalman@redhat.com>
e050a4
Date: Mon, 24 Jun 2019 15:58:09 +0200
e050a4
Subject: [PATCH] LDAP: failover does not work on non-responsive ldaps
e050a4
e050a4
In case ldaps:// is used, then establishing the secure socket is
e050a4
a sychronous operation. If there's nothing on the other end, then
e050a4
the process would be stuck waiting in for the crypto library
e050a4
to finish.
e050a4
e050a4
Here we set socket read/write timeout so the operation can finish
e050a4
in reasonable time with an error. The ldap_network_timeout
e050a4
option is used for this timeout.
e050a4
e050a4
Resolves:
e050a4
https://pagure.io/SSSD/sssd/issue/2878
e050a4
e050a4
Reviewed-by: Alexey Tikhonov <atikhono@redhat.com>
e050a4
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
e050a4
(cherry picked from commit 2d657dffb419640860e46ed417137b0e2cc7d9af)
e050a4
---
e050a4
 src/util/sss_sockets.c | 26 ++++++++++++++++++++++++--
e050a4
 1 file changed, 24 insertions(+), 2 deletions(-)
e050a4
e050a4
diff --git a/src/util/sss_sockets.c b/src/util/sss_sockets.c
e050a4
index 5e9be9ebd..0e4d8df8a 100644
e050a4
--- a/src/util/sss_sockets.c
e050a4
+++ b/src/util/sss_sockets.c
e050a4
@@ -74,10 +74,11 @@ static errno_t set_fcntl_flags(int fd, int fd_flags, int fl_flags)
e050a4
     return EOK;
e050a4
 }
e050a4
 
e050a4
-static errno_t set_fd_common_opts(int fd)
e050a4
+static errno_t set_fd_common_opts(int fd, int timeout)
e050a4
 {
e050a4
     int dummy = 1;
e050a4
     int ret;
e050a4
+    struct timeval tv;
e050a4
 
e050a4
     /* SO_KEEPALIVE and TCP_NODELAY are set by OpenLDAP client libraries but
e050a4
      * failures are ignored.*/
e050a4
@@ -97,6 +98,27 @@ static errno_t set_fd_common_opts(int fd)
e050a4
                   strerror(ret));
e050a4
     }
e050a4
 
e050a4
+    if (timeout > 0) {
e050a4
+        /* Set socket read & write timeout */
e050a4
+        tv = tevent_timeval_set(timeout, 0);
e050a4
+
e050a4
+        ret = setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));
e050a4
+        if (ret != 0) {
e050a4
+            ret = errno;
e050a4
+            DEBUG(SSSDBG_FUNC_DATA,
e050a4
+                  "setsockopt SO_RCVTIMEO failed.[%d][%s].\n", ret,
e050a4
+                  strerror(ret));
e050a4
+        }
e050a4
+
e050a4
+        ret = setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv));
e050a4
+        if (ret != 0) {
e050a4
+            ret = errno;
e050a4
+            DEBUG(SSSDBG_FUNC_DATA,
e050a4
+                  "setsockopt SO_SNDTIMEO failed.[%d][%s].\n", ret,
e050a4
+                  strerror(ret));
e050a4
+        }
e050a4
+    }
e050a4
+
e050a4
     return EOK;
e050a4
 }
e050a4
 
e050a4
@@ -264,7 +286,7 @@ struct tevent_req *sssd_async_socket_init_send(TALLOC_CTX *mem_ctx,
e050a4
         goto fail;
e050a4
     }
e050a4
 
e050a4
-    ret = set_fd_common_opts(state->sd);
e050a4
+    ret = set_fd_common_opts(state->sd, timeout);
e050a4
     if (ret != EOK) {
e050a4
         DEBUG(SSSDBG_CRIT_FAILURE, "set_fd_common_opts failed.\n");
e050a4
         goto fail;
e050a4
-- 
e050a4
2.20.1
e050a4