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

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