From 15ddc4a007b49691ca1a11e8711e7a4f3b844851 Mon Sep 17 00:00:00 2001
From: Stephan Bosch <stephan.bosch@dovecot.fi>
Date: Fri, 15 Dec 2017 12:46:54 +0100
Subject: [PATCH] lib-sieve: Added sieve_script_env_init() to initialize struct
 sieve_script_env from struct mail_user.

---
 src/lib-sieve/sieve.c                    |  8 ++++
 src/lib-sieve/sieve.h                    |  7 ++++
 src/plugins/imapsieve/imap-sieve.c       | 47 ++++++++++++++----------
 src/plugins/lda-sieve/lda-sieve-plugin.c | 13 +++++--
 src/sieve-tools/sieve-filter.c           |  5 ++-
 src/sieve-tools/sieve-test.c             |  8 +++-
 src/testsuite/testsuite-script.c         | 20 ++++++++--
 src/testsuite/testsuite.c                |  6 ++-
 8 files changed, 81 insertions(+), 33 deletions(-)

diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c
index ddbaf266e..bded5d827 100644
--- a/src/lib-sieve/sieve.c
+++ b/src/lib-sieve/sieve.c
@@ -543,6 +543,14 @@ int sieve_test
  * Script execution
  */
 
+int sieve_script_env_init(struct sieve_script_env *senv,
+	struct mail_user *user, const char **error_r ATTR_UNUSED)
+{
+	i_zero(senv);
+	senv->user = user;
+	return 0;
+}
+
 int sieve_execute
 (struct sieve_binary *sbin, const struct sieve_message_data *msgdata,
 	const struct sieve_script_env *senv,
diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h
index 54b1ac244..8f68d2e5d 100644
--- a/src/lib-sieve/sieve.h
+++ b/src/lib-sieve/sieve.h
@@ -164,6 +164,13 @@ int sieve_test
  * Script execution
  */
 
+/* sieve_script_env_init:
+ *
+ *   Initializes the scirpt environment from the given mail_user.
+ */
+int sieve_script_env_init(struct sieve_script_env *senv,
+	struct mail_user *user, const char **error_r);
+
 /* sieve_execute:
  *
  *   Executes the binary, including the result.
diff --git a/src/plugins/imapsieve/imap-sieve.c b/src/plugins/imapsieve/imap-sieve.c
index 61cdd15ef..712d08ec1 100644
--- a/src/plugins/imapsieve/imap-sieve.c
+++ b/src/plugins/imapsieve/imap-sieve.c
@@ -713,6 +713,7 @@ int imap_sieve_run_mail
 	struct imap_sieve_context context;
 	struct sieve_trace_config trace_config;
 	struct sieve_trace_log *trace_log;
+	const char *error;
 	int ret;
 
 	i_zero(&context);
@@ -744,26 +745,32 @@ int imap_sieve_run_mail
 
 		/* Compose script execution environment */
 
-		i_zero(&scriptenv);
-		i_zero(&estatus);
-		scriptenv.default_mailbox = mailbox_get_vname(mail->box);
-		scriptenv.user = user;
-		scriptenv.smtp_start = imap_sieve_smtp_start;
-		scriptenv.smtp_add_rcpt = imap_sieve_smtp_add_rcpt;
-		scriptenv.smtp_send = imap_sieve_smtp_send;
-		scriptenv.smtp_abort = imap_sieve_smtp_abort;
-		scriptenv.smtp_finish = imap_sieve_smtp_finish;
-		scriptenv.duplicate_mark = imap_sieve_duplicate_mark;
-		scriptenv.duplicate_check = imap_sieve_duplicate_check;
-		scriptenv.duplicate_flush = imap_sieve_duplicate_flush;
-		scriptenv.exec_status = &estatus;
-		scriptenv.trace_log = trace_log;
-		scriptenv.trace_config = trace_config;
-		scriptenv.script_context = (void *)&context;
-
-		/* Execute script(s) */
-
-		ret = imap_sieve_run_scripts(isrun, &msgdata, &scriptenv);
+		if (sieve_script_env_init(&scriptenv, user, &error) < 0) {
+			sieve_sys_error(svinst,
+				"Failed to initialize script execution: %s",
+				error);
+			ret = -1;
+		} else {
+			scriptenv.default_mailbox = mailbox_get_vname(mail->box);
+			scriptenv.smtp_start = imap_sieve_smtp_start;
+			scriptenv.smtp_add_rcpt = imap_sieve_smtp_add_rcpt;
+			scriptenv.smtp_send = imap_sieve_smtp_send;
+			scriptenv.smtp_abort = imap_sieve_smtp_abort;
+			scriptenv.smtp_finish = imap_sieve_smtp_finish;
+			scriptenv.duplicate_mark = imap_sieve_duplicate_mark;
+			scriptenv.duplicate_check = imap_sieve_duplicate_check;
+			scriptenv.duplicate_flush = imap_sieve_duplicate_flush;
+			scriptenv.trace_log = trace_log;
+			scriptenv.trace_config = trace_config;
+			scriptenv.script_context = (void *)&context;
+
+			i_zero(&estatus);
+			scriptenv.exec_status = &estatus;
+
+			/* Execute script(s) */
+
+			ret = imap_sieve_run_scripts(isrun, &msgdata, &scriptenv);
+		}
 	} T_END;
 
 	if ( trace_log != NULL )
diff --git a/src/plugins/lda-sieve/lda-sieve-plugin.c b/src/plugins/lda-sieve/lda-sieve-plugin.c
index 2d5a32570..836010658 100644
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c
@@ -800,6 +800,7 @@ static int lda_sieve_execute
 	struct sieve_trace_config trace_config;
 	struct sieve_trace_log *trace_log;
 	bool debug = mdctx->rcpt_user->mail_debug;
+	const char *error;
 	int ret;
 
 	/* Check whether there are any scripts to execute at all */
@@ -855,13 +856,17 @@ static int lda_sieve_execute
 
 	/* Compose script execution environment */
 
-	i_zero(&scriptenv);
-	i_zero(&estatus);
+	if (sieve_script_env_init(&scriptenv, mdctx->rcpt_user, &error) < 0) {
+		sieve_sys_error(svinst,
+			"Failed to initialize script execution: %s", error);
+		if ( trace_log != NULL )
+			sieve_trace_log_free(&trace_log);
+		return -1;
+	}
 
 	scriptenv.default_mailbox = mdctx->rcpt_default_mailbox;
 	scriptenv.mailbox_autocreate = mdctx->set->lda_mailbox_autocreate;
 	scriptenv.mailbox_autosubscribe = mdctx->set->lda_mailbox_autosubscribe;
-	scriptenv.user = mdctx->rcpt_user;
 	scriptenv.smtp_start = lda_sieve_smtp_start;
 	scriptenv.smtp_add_rcpt = lda_sieve_smtp_add_rcpt;
 	scriptenv.smtp_send = lda_sieve_smtp_send;
@@ -874,6 +879,8 @@ static int lda_sieve_execute
 	scriptenv.script_context = (void *) mdctx;
 	scriptenv.trace_log = trace_log;
 	scriptenv.trace_config = trace_config;
+
+	i_zero(&estatus);
 	scriptenv.exec_status = &estatus;
 
 	srctx->scriptenv = &scriptenv;
diff --git a/src/sieve-tools/sieve-filter.c b/src/sieve-tools/sieve-filter.c
index a3a901508..30e86523c 100644
--- a/src/sieve-tools/sieve-filter.c
+++ b/src/sieve-tools/sieve-filter.c
@@ -366,6 +366,7 @@ int main(int argc, char **argv)
 	struct mailbox *src_box = NULL, *move_box = NULL;
 	enum mailbox_flags open_flags = MAILBOX_FLAG_IGNORE_ACLS;
 	enum mail_error error;
+	const char *errstr;
 	int c;
 
 	sieve_tool = sieve_tool_init("sieve-filter", &argc, &argv,
@@ -541,10 +542,10 @@ int main(int argc, char **argv)
 	}
 
 	/* Compose script environment */
-	i_zero(&scriptenv);
+	if (sieve_script_env_init(&scriptenv, mail_user, &errstr) < 0)
+		i_fatal("Failed to initialize script execution: %s", errstr);
 	scriptenv.mailbox_autocreate = FALSE;
 	scriptenv.default_mailbox = dst_mailbox;
-	scriptenv.user = mail_user;
 
 	/* Compose filter context */
 	i_zero(&sfdata);
diff --git a/src/sieve-tools/sieve-test.c b/src/sieve-tools/sieve-test.c
index de0496b86..81b31afa0 100644
--- a/src/sieve-tools/sieve-test.c
+++ b/src/sieve-tools/sieve-test.c
@@ -316,9 +316,11 @@ int main(int argc, char **argv)
 		}
 
 		/* Compose script environment */
-		i_zero(&scriptenv);
+		if (sieve_script_env_init(&scriptenv,
+			sieve_tool_get_mail_user(sieve_tool), &errstr) < 0)
+			i_fatal("Failed to initialize script execution: %s", errstr);
+
 		scriptenv.default_mailbox = mailbox;
-		scriptenv.user = sieve_tool_get_mail_user(sieve_tool);
 		scriptenv.smtp_start = sieve_smtp_start;
 		scriptenv.smtp_add_rcpt = sieve_smtp_add_rcpt;
 		scriptenv.smtp_send = sieve_smtp_send;
@@ -328,6 +330,8 @@ int main(int argc, char **argv)
 		scriptenv.duplicate_check = duplicate_check;
 		scriptenv.trace_log = trace_log;
 		scriptenv.trace_config = trace_config;
+
+		i_zero(&estatus);
 		scriptenv.exec_status = &estatus;
 
 		/* Run the test */
diff --git a/src/testsuite/testsuite-script.c b/src/testsuite/testsuite-script.c
index 6d3a1cc67..b7d534707 100644
--- a/src/testsuite/testsuite-script.c
+++ b/src/testsuite/testsuite-script.c
@@ -88,11 +88,13 @@ bool testsuite_script_is_subtest(const struct sieve_runtime_env *renv)
 
 bool testsuite_script_run(const struct sieve_runtime_env *renv)
 {
+	const struct sieve_script_env *senv = renv->scriptenv;
 	struct testsuite_interpreter_context *ictx =
 		testsuite_interpreter_context_get(renv->interp, testsuite_ext);
 	struct sieve_script_env scriptenv;
 	struct sieve_result *result;
 	struct sieve_interpreter *interp;
+	const char *error;
 	int ret;
 
 	i_assert(ictx != NULL);
@@ -106,7 +108,12 @@ bool testsuite_script_run(const struct sieve_runtime_env *renv)
 	testsuite_log_clear_messages();
 
 	/* Compose script execution environment */
-	i_zero(&scriptenv);
+	if (sieve_script_env_init(&scriptenv, senv->user, &error) < 0) {
+		sieve_runtime_error(renv, NULL,
+			"testsuite: failed to initialize script execution: %s",
+			error);
+		return FALSE;
+	}
 	scriptenv.default_mailbox = "INBOX";
 	scriptenv.smtp_start = NULL;
 	scriptenv.smtp_add_rcpt = NULL;
@@ -114,7 +121,6 @@ bool testsuite_script_run(const struct sieve_runtime_env *renv)
 	scriptenv.smtp_finish = NULL;
 	scriptenv.duplicate_mark = NULL;
 	scriptenv.duplicate_check = NULL;
-	scriptenv.user = renv->scriptenv->user;
 	scriptenv.trace_log = renv->scriptenv->trace_log;
 	scriptenv.trace_config = renv->scriptenv->trace_config;
 
@@ -168,9 +174,11 @@ bool testsuite_script_multiscript
 (const struct sieve_runtime_env *renv, ARRAY_TYPE (const_string) *scriptfiles)
 {
 	struct sieve_instance *svinst = testsuite_sieve_instance;
+	const struct sieve_script_env *senv = renv->scriptenv;
 	struct sieve_script_env scriptenv;
 	struct sieve_multiscript *mscript;
 	const char *const *scripts;
+	const char *error;
 	unsigned int count, i;
 	bool more = TRUE;
 	bool result = TRUE;
@@ -178,7 +186,12 @@ bool testsuite_script_multiscript
 	testsuite_log_clear_messages();
 
 	/* Compose script execution environment */
-	i_zero(&scriptenv);
+	if (sieve_script_env_init(&scriptenv, senv->user, &error) < 0) {
+		sieve_runtime_error(renv, NULL,
+			"testsuite: failed to initialize script execution: %s",
+			error);
+		return FALSE;
+	}
 	scriptenv.default_mailbox = "INBOX";
 	scriptenv.smtp_start = NULL;
 	scriptenv.smtp_add_rcpt = NULL;
@@ -186,7 +199,6 @@ bool testsuite_script_multiscript
 	scriptenv.smtp_finish = NULL;
 	scriptenv.duplicate_mark = NULL;
 	scriptenv.duplicate_check = NULL;
-	scriptenv.user = renv->scriptenv->user;
 	scriptenv.trace_log = renv->scriptenv->trace_log;
 	scriptenv.trace_config = renv->scriptenv->trace_config;
 
diff --git a/src/testsuite/testsuite.c b/src/testsuite/testsuite.c
index 212d2b390..5cfc31e61 100644
--- a/src/testsuite/testsuite.c
+++ b/src/testsuite/testsuite.c
@@ -182,8 +182,10 @@ int main(int argc, char **argv)
 		testsuite_mailstore_init();
 		testsuite_message_init();
 
-		i_zero(&scriptenv);
-		scriptenv.user = testsuite_mailstore_get_user();
+		if (sieve_script_env_init(&scriptenv,
+			testsuite_mailstore_get_user(), &error) < 0)
+			i_fatal("Failed to initialize script execution: %s", error);
+
 		scriptenv.default_mailbox = "INBOX";
 		scriptenv.smtp_start = testsuite_smtp_start;
 		scriptenv.smtp_add_rcpt = testsuite_smtp_add_rcpt;
-- 
GitLab