|
|
44f86b |
From ee16c609497f29731c5a590821d27d0db0ffc91f Mon Sep 17 00:00:00 2001
|
|
|
44f86b |
From: Iker Pedrosa <ipedrosa@redhat.com>
|
|
|
44f86b |
Date: Wed, 3 Mar 2021 15:34:49 +0100
|
|
|
44f86b |
Subject: [PATCH] ldap: retry ldap_install_tls() when watchdog interruption
|
|
|
44f86b |
MIME-Version: 1.0
|
|
|
44f86b |
Content-Type: text/plain; charset=UTF-8
|
|
|
44f86b |
Content-Transfer-Encoding: 8bit
|
|
|
44f86b |
|
|
|
44f86b |
When the call to ldap_install_tls() fails because the watchdog
|
|
|
44f86b |
interrupted it, retry it. The watchdog interruption is detected by
|
|
|
44f86b |
checking the value of the ticks before and after the call to
|
|
|
44f86b |
ldap_install_tls().
|
|
|
44f86b |
|
|
|
44f86b |
Resolves: https://github.com/SSSD/sssd/issues/5531
|
|
|
44f86b |
|
|
|
44f86b |
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
|
|
44f86b |
---
|
|
|
44f86b |
src/providers/ldap/sdap_async_connection.c | 27 +++++++++++++++++++++-
|
|
|
44f86b |
src/util/sss_ldap.c | 12 ++++++++++
|
|
|
44f86b |
src/util/util.h | 1 +
|
|
|
44f86b |
src/util/util_errors.c | 3 +++
|
|
|
44f86b |
src/util/util_errors.h | 3 +++
|
|
|
44f86b |
src/util/util_watchdog.c | 5 ++++
|
|
|
44f86b |
6 files changed, 50 insertions(+), 1 deletion(-)
|
|
|
44f86b |
|
|
|
44f86b |
diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c
|
|
|
44f86b |
index afa31ea0f..db963044e 100644
|
|
|
44f86b |
--- a/src/providers/ldap/sdap_async_connection.c
|
|
|
44f86b |
+++ b/src/providers/ldap/sdap_async_connection.c
|
|
|
44f86b |
@@ -30,6 +30,8 @@
|
|
|
44f86b |
#include "providers/ldap/sdap_async_private.h"
|
|
|
44f86b |
#include "providers/ldap/ldap_common.h"
|
|
|
44f86b |
|
|
|
44f86b |
+#define MAX_RETRY_ATTEMPTS 1
|
|
|
44f86b |
+
|
|
|
44f86b |
/* ==Connect-to-LDAP-Server=============================================== */
|
|
|
44f86b |
|
|
|
44f86b |
struct sdap_rebind_proc_params {
|
|
|
44f86b |
@@ -1447,6 +1449,8 @@ struct sdap_cli_connect_state {
|
|
|
44f86b |
enum connect_tls force_tls;
|
|
|
44f86b |
bool do_auth;
|
|
|
44f86b |
bool use_tls;
|
|
|
44f86b |
+
|
|
|
44f86b |
+ int retry_attempts;
|
|
|
44f86b |
};
|
|
|
44f86b |
|
|
|
44f86b |
static int sdap_cli_resolve_next(struct tevent_req *req);
|
|
|
44f86b |
@@ -1599,16 +1603,37 @@ static void sdap_cli_connect_done(struct tevent_req *subreq)
|
|
|
44f86b |
talloc_zfree(state->sh);
|
|
|
44f86b |
ret = sdap_connect_recv(subreq, state, &state->sh);
|
|
|
44f86b |
talloc_zfree(subreq);
|
|
|
44f86b |
- if (ret) {
|
|
|
44f86b |
+ if (ret == ERR_TLS_HANDSHAKE_INTERRUPTED &&
|
|
|
44f86b |
+ state->retry_attempts < MAX_RETRY_ATTEMPTS) {
|
|
|
44f86b |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
44f86b |
+ "TLS handshake was interruped, provider will retry\n");
|
|
|
44f86b |
+ state->retry_attempts++;
|
|
|
44f86b |
+ subreq = sdap_connect_send(state, state->ev, state->opts,
|
|
|
44f86b |
+ state->service->uri,
|
|
|
44f86b |
+ state->service->sockaddr,
|
|
|
44f86b |
+ state->use_tls);
|
|
|
44f86b |
+
|
|
|
44f86b |
+ if (!subreq) {
|
|
|
44f86b |
+ tevent_req_error(req, ENOMEM);
|
|
|
44f86b |
+ return;
|
|
|
44f86b |
+ }
|
|
|
44f86b |
+
|
|
|
44f86b |
+ tevent_req_set_callback(subreq, sdap_cli_connect_done, req);
|
|
|
44f86b |
+ return;
|
|
|
44f86b |
+ } else if (ret != EOK) {
|
|
|
44f86b |
+ state->retry_attempts = 0;
|
|
|
44f86b |
/* retry another server */
|
|
|
44f86b |
be_fo_set_port_status(state->be, state->service->name,
|
|
|
44f86b |
state->srv, PORT_NOT_WORKING);
|
|
|
44f86b |
+
|
|
|
44f86b |
ret = sdap_cli_resolve_next(req);
|
|
|
44f86b |
if (ret != EOK) {
|
|
|
44f86b |
tevent_req_error(req, ret);
|
|
|
44f86b |
}
|
|
|
44f86b |
+
|
|
|
44f86b |
return;
|
|
|
44f86b |
}
|
|
|
44f86b |
+ state->retry_attempts = 0;
|
|
|
44f86b |
|
|
|
44f86b |
if (state->use_rootdse) {
|
|
|
44f86b |
/* fetch the rootDSE this time */
|
|
|
44f86b |
diff --git a/src/util/sss_ldap.c b/src/util/sss_ldap.c
|
|
|
44f86b |
index 9d1e95217..652b08ea7 100644
|
|
|
44f86b |
--- a/src/util/sss_ldap.c
|
|
|
44f86b |
+++ b/src/util/sss_ldap.c
|
|
|
44f86b |
@@ -234,6 +234,8 @@ static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq)
|
|
|
44f86b |
int ret;
|
|
|
44f86b |
int lret;
|
|
|
44f86b |
int optret;
|
|
|
44f86b |
+ int ticks_before_install;
|
|
|
44f86b |
+ int ticks_after_install;
|
|
|
44f86b |
|
|
|
44f86b |
ret = sssd_async_socket_init_recv(subreq, &state->sd);
|
|
|
44f86b |
talloc_zfree(subreq);
|
|
|
44f86b |
@@ -261,7 +263,9 @@ static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq)
|
|
|
44f86b |
}
|
|
|
44f86b |
|
|
|
44f86b |
if (ldap_is_ldaps_url(state->uri)) {
|
|
|
44f86b |
+ ticks_before_install = get_watchdog_ticks();
|
|
|
44f86b |
lret = ldap_install_tls(state->ldap);
|
|
|
44f86b |
+ ticks_after_install = get_watchdog_ticks();
|
|
|
44f86b |
if (lret != LDAP_SUCCESS) {
|
|
|
44f86b |
if (lret == LDAP_LOCAL_ERROR) {
|
|
|
44f86b |
DEBUG(SSSDBG_FUNC_DATA, "TLS/SSL already in place.\n");
|
|
|
44f86b |
@@ -283,6 +287,14 @@ static void sss_ldap_init_sys_connect_done(struct tevent_req *subreq)
|
|
|
44f86b |
"Check for certificate issues.");
|
|
|
44f86b |
}
|
|
|
44f86b |
|
|
|
44f86b |
+ if (ticks_after_install > ticks_before_install) {
|
|
|
44f86b |
+ ret = ERR_TLS_HANDSHAKE_INTERRUPTED;
|
|
|
44f86b |
+ DEBUG(SSSDBG_CRIT_FAILURE,
|
|
|
44f86b |
+ "Assuming %s\n",
|
|
|
44f86b |
+ sss_ldap_err2string(ret));
|
|
|
44f86b |
+ goto fail;
|
|
|
44f86b |
+ }
|
|
|
44f86b |
+
|
|
|
44f86b |
ret = EIO;
|
|
|
44f86b |
goto fail;
|
|
|
44f86b |
}
|
|
|
44f86b |
diff --git a/src/util/util.h b/src/util/util.h
|
|
|
44f86b |
index 486394448..94c2e6e3b 100644
|
|
|
44f86b |
--- a/src/util/util.h
|
|
|
44f86b |
+++ b/src/util/util.h
|
|
|
44f86b |
@@ -737,6 +737,7 @@ int sss_unique_filename(TALLOC_CTX *owner, char *path_tmpl);
|
|
|
44f86b |
/* from util_watchdog.c */
|
|
|
44f86b |
int setup_watchdog(struct tevent_context *ev, int interval);
|
|
|
44f86b |
void teardown_watchdog(void);
|
|
|
44f86b |
+int get_watchdog_ticks(void);
|
|
|
44f86b |
|
|
|
44f86b |
/* from files.c */
|
|
|
44f86b |
int sss_remove_tree(const char *root);
|
|
|
44f86b |
diff --git a/src/util/util_errors.c b/src/util/util_errors.c
|
|
|
44f86b |
index c35a99a54..0eeaa346c 100644
|
|
|
44f86b |
--- a/src/util/util_errors.c
|
|
|
44f86b |
+++ b/src/util/util_errors.c
|
|
|
44f86b |
@@ -121,6 +121,9 @@ struct err_string error_to_str[] = {
|
|
|
44f86b |
{ "The last GetAccountDomain() result is still valid" }, /* ERR_GET_ACCT_DOM_CACHED */
|
|
|
44f86b |
{ "ID is outside the allowed range" }, /* ERR_ID_OUTSIDE_RANGE */
|
|
|
44f86b |
{ "Group ID is duplicated" }, /* ERR_GID_DUPLICATED */
|
|
|
44f86b |
+
|
|
|
44f86b |
+ { "TLS handshake was interrupted"}, /* ERR_TLS_HANDSHAKE_INTERRUPTED */
|
|
|
44f86b |
+
|
|
|
44f86b |
{ "ERR_LAST" } /* ERR_LAST */
|
|
|
44f86b |
};
|
|
|
44f86b |
|
|
|
44f86b |
diff --git a/src/util/util_errors.h b/src/util/util_errors.h
|
|
|
44f86b |
index 470f62f9e..366b75650 100644
|
|
|
44f86b |
--- a/src/util/util_errors.h
|
|
|
44f86b |
+++ b/src/util/util_errors.h
|
|
|
44f86b |
@@ -143,6 +143,9 @@ enum sssd_errors {
|
|
|
44f86b |
ERR_GET_ACCT_DOM_CACHED,
|
|
|
44f86b |
ERR_ID_OUTSIDE_RANGE,
|
|
|
44f86b |
ERR_GID_DUPLICATED,
|
|
|
44f86b |
+
|
|
|
44f86b |
+ ERR_TLS_HANDSHAKE_INTERRUPTED,
|
|
|
44f86b |
+
|
|
|
44f86b |
ERR_LAST /* ALWAYS LAST */
|
|
|
44f86b |
};
|
|
|
44f86b |
|
|
|
44f86b |
diff --git a/src/util/util_watchdog.c b/src/util/util_watchdog.c
|
|
|
44f86b |
index 69160fbdf..7642bfd53 100644
|
|
|
44f86b |
--- a/src/util/util_watchdog.c
|
|
|
44f86b |
+++ b/src/util/util_watchdog.c
|
|
|
44f86b |
@@ -259,3 +259,8 @@ void teardown_watchdog(void)
|
|
|
44f86b |
/* and kill the watchdog event */
|
|
|
44f86b |
talloc_free(watchdog_ctx.te);
|
|
|
44f86b |
}
|
|
|
44f86b |
+
|
|
|
44f86b |
+int get_watchdog_ticks(void)
|
|
|
44f86b |
+{
|
|
|
44f86b |
+ return __sync_add_and_fetch(&watchdog_ctx.ticks, 0);
|
|
|
44f86b |
+}
|
|
|
44f86b |
--
|
|
|
44f86b |
2.26.3
|
|
|
44f86b |
|