From 6f91db4aff9845bea9d0e42bcf1fc0bca709fe60 Mon Sep 17 00:00:00 2001
From: Timo Sirainen <timo.sirainen@open-xchange.com>
Date: Fri, 13 Dec 2024 17:31:12 +0200
Subject: [PATCH] lib-sieve: storage: ldap: Replace tls_* settings with the
 global ssl_* settings

---
 src/lib-sieve/storage/ldap/Makefile.am        | 13 +++-
 src/lib-sieve/storage/ldap/sieve-ldap-db.c    | 61 +++----------------
 .../ldap/sieve-ldap-storage-settings.c        | 43 -------------
 .../ldap/sieve-ldap-storage-settings.h        |  7 ---
 .../storage/ldap/sieve-ldap-storage.c         | 13 +++-
 .../storage/ldap/sieve-ldap-storage.h         |  1 +
 6 files changed, 28 insertions(+), 110 deletions(-)

diff --git a/src/lib-sieve/storage/ldap/Makefile.am b/src/lib-sieve/storage/ldap/Makefile.am
index 9ec5b25af..9de57b810 100644
--- a/src/lib-sieve/storage/ldap/Makefile.am
+++ b/src/lib-sieve/storage/ldap/Makefile.am
@@ -5,6 +5,7 @@ sieve_plugin_LTLIBRARIES =
 
 AM_CPPFLAGS = \
 	$(LIBDOVECOT_INCLUDE) \
+	$(LIBDOVECOT_LDAP_INCLUDE) \
 	-I$(top_srcdir) \
 	-I$(top_srcdir)/src/lib-sieve
 
@@ -15,7 +16,10 @@ ldap_sources = \
 	sieve-ldap-storage-settings.c
 
 libsieve_storage_ldap_la_SOURCES = $(ldap_sources)
-libsieve_storage_ldap_la_LIBADD = $(LDAP_LIBS)
+libsieve_storage_ldap_la_LIBADD = \
+	$(LIBDOVECOT) \
+	$(LIBDOVECOT_LDAP) \
+	$(DOVECOT_LDAP_LIBS)
 
 noinst_HEADERS = \
 	sieve-ldap-db.h \
@@ -26,8 +30,11 @@ if LDAP_PLUGIN
 sieve_plugin_LTLIBRARIES += lib10_sieve_storage_ldap_plugin.la
 
 lib10_sieve_storage_ldap_plugin_la_LDFLAGS = -module -avoid-version
-lib10_sieve_storage_ldap_plugin_la_LIBADD = $(LDAP_LIBS)
-lib10_sieve_storage_ldap_plugin_la_DEPENDENCIES = $(LDAP_LIBS)
+lib10_sieve_storage_ldap_plugin_la_LIBADD = \
+	$(LIBDOVECOT) \
+	$(LIBDOVECOT_LDAP) \
+	$(DOVECOT_LDAP_LIBS)
+lib10_sieve_storage_ldap_plugin_la_DEPENDENCIES = $(LIBDOVECOT_LDAP_DEPS)
 lib10_sieve_storage_ldap_plugin_la_CPPFLAGS = $(AM_CPPFLAGS) -DPLUGIN_BUILD
 lib10_sieve_storage_ldap_plugin_la_SOURCES = $(ldap_sources)
 endif
diff --git a/src/lib-sieve/storage/ldap/sieve-ldap-db.c b/src/lib-sieve/storage/ldap/sieve-ldap-db.c
index c660f4635..b056dd67e 100644
--- a/src/lib-sieve/storage/ldap/sieve-ldap-db.c
+++ b/src/lib-sieve/storage/ldap/sieve-ldap-db.c
@@ -22,6 +22,7 @@
 #include "env-util.h"
 #include "var-expand.h"
 #include "istream.h"
+#include "ldap-utils.h"
 
 #include <stddef.h>
 #include <unistd.h>
@@ -640,64 +641,12 @@ db_ldap_set_opt(struct ldap_connection *conn, int opt, const void *value,
 	return 0;
 }
 
-static int
-db_ldap_set_opt_str(struct ldap_connection *conn, int opt, const char *value,
-		    const char *optname)
-{
-	if (value != NULL)
-		return db_ldap_set_opt(conn, opt, value, optname, value);
-	return 0;
-}
-
-static int db_ldap_set_tls_options(struct ldap_connection *conn)
-{
-	const struct sieve_ldap_settings *set = conn->lstorage->ldap_set;
-
-	if (!set->starttls)
-		return 0;
-
-#ifdef OPENLDAP_TLS_OPTIONS
-	if (db_ldap_set_opt_str(conn, LDAP_OPT_X_TLS_CACERTFILE,
-				set->tls_ca_cert_file, "tls_ca_cert_file") < 0)
-		return -1;
-	if (db_ldap_set_opt_str(conn, LDAP_OPT_X_TLS_CACERTDIR,
-				set->tls_ca_cert_dir, "tls_ca_cert_dir") < 0)
-		return -1;
-	if (db_ldap_set_opt_str(conn, LDAP_OPT_X_TLS_CERTFILE,
-				set->tls_cert_file, "tls_cert_file") < 0)
-		return -1;
-	if (db_ldap_set_opt_str(conn, LDAP_OPT_X_TLS_KEYFILE,
-				set->tls_key_file, "tls_key_file") < 0)
-		return -1;
-	if (db_ldap_set_opt_str(conn, LDAP_OPT_X_TLS_CIPHER_SUITE,
-				set->tls_cipher_suite, "tls_cipher_suite") < 0)
-		return -1;
-	if (*set->tls_require_cert != '\0') {
-		if (db_ldap_set_opt(conn, LDAP_OPT_X_TLS_REQUIRE_CERT,
-				    &set->parsed.tls_require_cert,
-				    "tls_require_cert",
-				    set->tls_require_cert) < 0)
-			return -1;
-	}
-#else
-	if (*set->tls_ca_cert_file != '\0' ||
-	    *set->tls_ca_cert_dir != '\0' ||
-	    *set->tls_cert_file != '\0' ||
-	    *set->tls_key_file != '\0' ||
-	    *set->tls_cipher_suite != '\0') {
-		e_warning(&conn->lstorage->storage, "db: "
-			  "tls_* settings ignored, "
-			  "your LDAP library doesn't seem to support them");
-	}
-#endif
-	return 0;
-}
-
 static int db_ldap_set_options(struct ldap_connection *conn)
 {
 	const struct sieve_ldap_settings *set = conn->lstorage->ldap_set;
 	struct sieve_storage *storage = &conn->lstorage->storage;
 	unsigned int ldap_version;
+	const char *error;
 	int value;
 
 	if (db_ldap_set_opt(conn, LDAP_OPT_DEREF, &set->parsed.deref,
@@ -728,8 +677,12 @@ static int db_ldap_set_options(struct ldap_connection *conn)
 	if (db_ldap_set_opt(conn, LDAP_OPT_PROTOCOL_VERSION, &ldap_version,
 			    "ldap_version", dec2str(ldap_version)) < 0)
 		return -1;
-	if (db_ldap_set_tls_options(conn) < 0)
+
+	if (ldap_set_tls_options(conn->ld, set->starttls, set->uris,
+				 conn->lstorage->ssl_set, &error) < 0) {
+		e_error(storage->event, "db: %s", error);
 		return -1;
+	}
 	return 0;
 }
 
diff --git a/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.c b/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.c
index 3dadcd66d..e6e5fc287 100644
--- a/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.c
+++ b/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.c
@@ -32,12 +32,6 @@ static const struct setting_define sieve_ldap_setting_defines[] = {
 	DEF(BOOLLIST, auth_sasl_mechanisms),
 	DEF(STR, auth_sasl_realm),
 	DEF(STR, auth_sasl_authz_id),
-	DEF(STR, tls_ca_cert_file),
-	DEF(STR, tls_ca_cert_dir),
-	DEF(STR, tls_cert_file),
-	DEF(STR, tls_key_file),
-	DEF(STR, tls_cipher_suite),
-	DEF(STR, tls_require_cert),
 	DEF(ENUM, deref),
 	DEF(ENUM, scope),
 	DEF(STR, base),
@@ -55,12 +49,6 @@ const struct sieve_ldap_settings sieve_ldap_default_settings = {
 	.auth_sasl_mechanisms = ARRAY_INIT,
 	.auth_sasl_realm = "",
 	.auth_sasl_authz_id = "",
-	.tls_ca_cert_file = "",
-	.tls_ca_cert_dir = "",
-	.tls_cert_file = "",
-	.tls_key_file = "",
-	.tls_cipher_suite = "",
-	.tls_require_cert = "",
 	.deref = "never:searching:finding:always",
 	.scope = "subtree:onelevel:base",
 	.base = "",
@@ -136,25 +124,6 @@ static int ldap_scope_from_str(const char *str, int *scope_r)
 	return 0;
 }
 
-#ifdef OPENLDAP_TLS_OPTIONS
-static int ldap_tls_require_cert_from_str(const char *str, int *opt_x_tls_r)
-{
-	if (strcasecmp(str, "never") == 0)
-		*opt_x_tls_r = LDAP_OPT_X_TLS_NEVER;
-	else if (strcasecmp(str, "hard") == 0)
-		*opt_x_tls_r = LDAP_OPT_X_TLS_HARD;
-	else if (strcasecmp(str, "demand") == 0)
-		*opt_x_tls_r = LDAP_OPT_X_TLS_DEMAND;
-	else if (strcasecmp(str, "allow") == 0)
-		*opt_x_tls_r = LDAP_OPT_X_TLS_ALLOW;
-	else if (strcasecmp(str, "try") == 0)
-		*opt_x_tls_r = LDAP_OPT_X_TLS_TRY;
-	else
-		return -1;
-	return 0;
-}
-#endif
-
 static bool
 sieve_ldap_settings_check(void *_set, pool_t pool ATTR_UNUSED,
 			  const char **error_r)
@@ -179,18 +148,6 @@ sieve_ldap_settings_check(void *_set, pool_t pool ATTR_UNUSED,
 		return FALSE;
 	}
 
-#ifdef OPENLDAP_TLS_OPTIONS
-	if (*set->tls_require_cert != '\0' &&
-	    ldap_tls_require_cert_from_str(
-		set->tls_require_cert,
-		&set->parsed.tls_require_cert) < 0) {
-		*error_r = t_strdup_printf("ldap: "
-			"Invalid tls_require_cert option '%s'",
-			set->tls_require_cert);
-		return FALSE;
-	}
-#endif
-
 	return TRUE;
 }
 /* </settings checks> */
diff --git a/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.h b/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.h
index de3e35806..a1da98d9a 100644
--- a/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.h
+++ b/src/lib-sieve/storage/ldap/sieve-ldap-storage-settings.h
@@ -13,13 +13,6 @@ struct sieve_ldap_settings {
 	const char *auth_sasl_realm;
 	const char *auth_sasl_authz_id;
 
-	const char *tls_ca_cert_file;
-	const char *tls_ca_cert_dir;
-	const char *tls_cert_file;
-	const char *tls_key_file;
-	const char *tls_cipher_suite;
-	const char *tls_require_cert;
-
 	const char *deref;
 	const char *scope;
 	const char *base;
diff --git a/src/lib-sieve/storage/ldap/sieve-ldap-storage.c b/src/lib-sieve/storage/ldap/sieve-ldap-storage.c
index 3777448d0..f5414dc33 100644
--- a/src/lib-sieve/storage/ldap/sieve-ldap-storage.c
+++ b/src/lib-sieve/storage/ldap/sieve-ldap-storage.c
@@ -3,7 +3,8 @@
 
 #include "lib.h"
 #include "settings.h"
-//#include "ldap.h"
+#include "ldap-utils.h"
+#include "iostream-ssl.h"
 
 #include "sieve-common.h"
 
@@ -47,7 +48,8 @@ sieve_ldap_storage_init(struct sieve_storage *storage)
 	struct sieve_ldap_storage *lstorage =
 		container_of(storage, struct sieve_ldap_storage, storage);
 	const struct sieve_ldap_settings *ldap_set;
-	const struct sieve_ldap_storage_settings *set;
+	const struct sieve_ldap_storage_settings *set = NULL;
+	const struct ssl_settings *ssl_set;
 	const char *error;
 	int ret;
 
@@ -70,14 +72,18 @@ sieve_ldap_storage_init(struct sieve_storage *storage)
 
 	if (settings_get(storage->event,
 			 &sieve_ldap_storage_setting_parser_info, 0,
-			 &set, &error) < 0) {
+			 &set, &error) < 0 ||
+	    settings_get(storage->event, &ssl_setting_parser_info, 0,
+			 &ssl_set, &error) < 0) {
 		sieve_storage_set_critical(storage, "%s", error);
+		settings_free(set);
 		settings_free(ldap_set);
 		return -1;
 	}
 
 	lstorage->ldap_set = ldap_set;
 	lstorage->set = set;
+	lstorage->ssl_set = ssl_set;
 	lstorage->conn = sieve_ldap_db_init(lstorage);
 
 	return 0;
@@ -89,6 +95,7 @@ static void sieve_ldap_storage_destroy(struct sieve_storage *storage)
 		container_of(storage, struct sieve_ldap_storage, storage);
 
 	sieve_ldap_db_unref(&lstorage->conn);
+	settings_free(lstorage->ssl_set);
 	settings_free(lstorage->ldap_set);
 	settings_free(lstorage->set);
 }
diff --git a/src/lib-sieve/storage/ldap/sieve-ldap-storage.h b/src/lib-sieve/storage/ldap/sieve-ldap-storage.h
index 394ddcc2c..00466b78f 100644
--- a/src/lib-sieve/storage/ldap/sieve-ldap-storage.h
+++ b/src/lib-sieve/storage/ldap/sieve-ldap-storage.h
@@ -23,6 +23,7 @@ struct sieve_ldap_storage {
 
 	const struct sieve_ldap_settings *ldap_set;
 	const struct sieve_ldap_storage_settings *set;
+	const struct ssl_settings *ssl_set;
 	time_t set_mtime;
 
 	struct ldap_connection *conn;
-- 
GitLab