From eec154e47f486c86d25de5c282ea31a88624d2fb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eero=20H=C3=A4kkinen?= Date: Thu, 22 Jan 2026 13:50:45 +0200 Subject: [PATCH 1/3] lib-ldap: Convert ssl_min_protocol properly to int --- src/lib-ldap/ldap-utils.c | 44 +++++++++++++++++++++++++++++++++++---- 1 file changed, 40 insertions(+), 4 deletions(-) diff --git a/src/lib-ldap/ldap-utils.c b/src/lib-ldap/ldap-utils.c index 5a7e94839f9..79345cf8386 100644 --- a/src/lib-ldap/ldap-utils.c +++ b/src/lib-ldap/ldap-utils.c @@ -38,6 +38,30 @@ int ldap_set_tls_options(LDAP *ld ATTR_UNUSED, bool starttls ATTR_UNUSED, return 0; } #else +static const struct { + const char *name; + int opt; +} protocol_versions[] = { + { "ANY", LDAP_OPT_X_TLS_PROTOCOL_SSL3 }, + { "TLSv1", LDAP_OPT_X_TLS_PROTOCOL_TLS1_0 }, + { "TLSv1.1", LDAP_OPT_X_TLS_PROTOCOL_TLS1_1 }, + { "TLSv1.2", LDAP_OPT_X_TLS_PROTOCOL_TLS1_2 }, + { "TLSv1.3", LDAP_OPT_X_TLS_PROTOCOL_TLS1_3 }, + { "LATEST", LDAP_OPT_X_TLS_PROTOCOL_TLS1_3 } +}; + +static int ldap_min_protocol_to_option(const char *min_protocol, int *opt_r) +{ + unsigned int i = 0; + for (; i < N_ELEMENTS(protocol_versions); i++) { + if (strcasecmp(protocol_versions[i].name, min_protocol) == 0) { + *opt_r = protocol_versions[i].opt; + return 0; + } + } + return -1; +} + int ldap_set_tls_options(LDAP *ld, bool starttls, const char *uris, const struct ssl_settings *ssl_set, const char **error_r) @@ -70,10 +94,6 @@ int ldap_set_tls_options(LDAP *ld, bool starttls, const char *uris, ssl_set->ssl_cipher_list, "ssl_cipher_list", error_r) < 0) return -1; - if (ldap_set_opt_str(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, - ssl_set->ssl_min_protocol, - "ssl_min_protocol", error_r) < 0) - return -1; if (ldap_set_opt_str(ld, LDAP_OPT_X_TLS_ECNAME, ssl_set->ssl_curve_list, "ssl_curve_list", error_r) < 0) @@ -93,6 +113,22 @@ int ldap_set_tls_options(LDAP *ld, bool starttls, const char *uris, "ssl_client_require_valid_cert", requires ? "yes" : "no", error_r) < 0) return -1; + + if (ldap_min_protocol_to_option( + *ssl_set->ssl_min_protocol != '\0' + ? ssl_set->ssl_min_protocol + : "ANY", + &opt) < 0) { + *error_r = t_strdup_printf("Can't set option %s to %s: %s", + "ssl_min_protocol", ssl_set->ssl_min_protocol, + "Unknown value"); + return -1; + } + if (ldap_set_opt(ld, LDAP_OPT_X_TLS_PROTOCOL_MIN, &opt, + "ssl_min_protocol", ssl_set->ssl_min_protocol, + error_r) < 0) + return -1; + return 0; } From 5bdc89f020bed927428cb5ce4df9cd81d72e7a15 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eero=20H=C3=A4kkinen?= Date: Thu, 22 Jan 2026 14:01:42 +0200 Subject: [PATCH 2/3] lib-ldap: Do not override the tls_protocol_min setting with a lower one --- src/lib-ldap/ldap-connection.c | 5 ----- 1 file changed, 5 deletions(-) diff --git a/src/lib-ldap/ldap-connection.c b/src/lib-ldap/ldap-connection.c index 0c00a5565be..bf78e43b310 100644 --- a/src/lib-ldap/ldap-connection.c +++ b/src/lib-ldap/ldap-connection.c @@ -59,11 +59,6 @@ int ldap_connection_setup(struct ldap_connection *conn, const char **error_r) conn->set->uris, conn->ssl_set, error_r) < 0) return -1; -#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN - /* refuse to connect to SSLv2 as it's completely insecure */ - opt = LDAP_OPT_X_TLS_PROTOCOL_SSL3; - ldap_set_option(conn->conn, LDAP_OPT_X_TLS_PROTOCOL_MIN, &opt); -#endif opt = conn->set->timeout_secs; /* default timeout */ ldap_set_option(conn->conn, LDAP_OPT_TIMEOUT, &opt); From f043a7a075b23654519465c1aba6c7187281a72e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Eero=20H=C3=A4kkinen?= Date: Thu, 22 Jan 2026 14:24:20 +0200 Subject: [PATCH 3/3] lib-ldap: Create a new TLS context for all LDAP TLS connections Additionally, do not set the global peer certificate checking strategy (the global LDAP_OPT_X_TLS_REQUIRE_CERT option). It is not needed and has no effect after a new TLS context is created. --- src/lib-ldap/ldap-connection.c | 5 ----- src/lib-ldap/ldap-utils.c | 14 ++++++-------- 2 files changed, 6 insertions(+), 13 deletions(-) diff --git a/src/lib-ldap/ldap-connection.c b/src/lib-ldap/ldap-connection.c index bf78e43b310..626f23ebc2d 100644 --- a/src/lib-ldap/ldap-connection.c +++ b/src/lib-ldap/ldap-connection.c @@ -74,11 +74,6 @@ int ldap_connection_setup(struct ldap_connection *conn, const char **error_r) ldap_set_option(conn->conn, LDAP_OPT_REFERRALS, 0); -#ifdef LDAP_OPT_X_TLS_NEWCTX - opt = 0; - ldap_set_option(conn->conn, LDAP_OPT_X_TLS_NEWCTX, &opt); -#endif - return 0; } diff --git a/src/lib-ldap/ldap-utils.c b/src/lib-ldap/ldap-utils.c index 79345cf8386..f8886be19d5 100644 --- a/src/lib-ldap/ldap-utils.c +++ b/src/lib-ldap/ldap-utils.c @@ -101,14 +101,6 @@ int ldap_set_tls_options(LDAP *ld, bool starttls, const char *uris, bool requires = ssl_set->ssl_client_require_valid_cert; int opt = requires ? LDAP_OPT_X_TLS_HARD : LDAP_OPT_X_TLS_ALLOW; - - /* required for Bookworm */ - if (ldap_set_opt(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, &opt, - "ssl_client_require_valid_cert", - requires ? "yes" : "no", error_r) < 0) - return -1; - - /* required for RHEL9 */ if (ldap_set_opt(ld, LDAP_OPT_X_TLS_REQUIRE_CERT, &opt, "ssl_client_require_valid_cert", requires ? "yes" : "no", error_r) < 0) @@ -129,6 +121,12 @@ int ldap_set_tls_options(LDAP *ld, bool starttls, const char *uris, error_r) < 0) return -1; +#ifdef LDAP_OPT_X_TLS_NEWCTX + bool is_server = false; + opt = is_server; + ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &opt); +#endif + return 0; }