diff --git a/src/lib-sieve/Makefile.am b/src/lib-sieve/Makefile.am index aba132bae375da55c5cb21e815aac342ede16d23..22420fae996d5c32bdeb1914b3141671381ec2ac 100644 --- a/src/lib-sieve/Makefile.am +++ b/src/lib-sieve/Makefile.am @@ -98,6 +98,7 @@ libdovecot_sieve_la_LIBADD = \ libdovecot_sieve_la_SOURCES = \ sieve-settings.old.c \ + sieve-settings.c \ sieve-message.c \ sieve-smtp.c \ sieve-lexer.c \ @@ -144,6 +145,7 @@ headers = \ sieve-types.h \ sieve-common.h \ sieve-limits.h \ + sieve-settings.h \ sieve-settings.old.h \ sieve-message.h \ sieve-smtp.h \ diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 28a798c9e055b539880ff4f4008d7993a34b6014..1de8e988e08678b443a7f406f679ea4070d5613e 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -151,7 +151,7 @@ cmd_redirect_validate(struct sieve_validator *validator, return result; } - if (svinst->max_redirects == 0) { + if (svinst->set->max_redirects == 0) { sieve_command_validate_error(validator, cmd, "local policy prohibits the use of a redirect action"); return FALSE; @@ -233,7 +233,7 @@ cmd_redirect_operation_execute(const struct sieve_runtime_env *renv, return SIEVE_EXEC_FAILURE; } - if (svinst->max_redirects == 0) { + if (svinst->set->max_redirects == 0) { sieve_runtime_error(renv, NULL, "local policy prohibits the use of a redirect action"); return SIEVE_EXEC_FAILURE; @@ -309,7 +309,8 @@ act_redirect_send(const struct sieve_action_exec_env *aenv, struct mail *mail, struct sieve_instance *svinst = eenv->svinst; struct sieve_message_context *msgctx = aenv->msgctx; const struct sieve_script_env *senv = eenv->scriptenv; - struct sieve_address_source env_from = svinst->redirect_from; + struct sieve_address_source env_from = + svinst->set->parsed.redirect_envelope_from; struct istream *input; struct ostream *output; const struct smtp_address *sender; @@ -357,7 +358,7 @@ act_redirect_send(const struct sieve_action_exec_env *aenv, struct mail *mail, if (ret < 0) sender = NULL; else if (ret == 0) - sender = svinst->user_email; + sender = svinst->set->parsed.user_email; } /* Open SMTP transport */ @@ -376,7 +377,7 @@ act_redirect_send(const struct sieve_action_exec_env *aenv, struct mail *mail, /* Prepend sieve headers (should not affect signatures) */ rfc2822_header_append(hdr, "X-Sieve", SIEVE_IMPLEMENTATION, FALSE, NULL); - if (svinst->user_email == NULL && + if (svinst->set->parsed.user_email == NULL && (eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) user_email = sieve_message_get_final_recipient(msgctx); else @@ -654,7 +655,7 @@ act_redirect_commit(const struct sieve_action_exec_env *aenv, void *tr_context) destination */ sieve_action_duplicate_mark( aenv, trans->dupeid, strlen(trans->dupeid), - ioloop_time + svinst->redirect_duplicate_period); + ioloop_time + svinst->set->redirect_duplicate_period); eenv->exec_status->significant_action_executed = TRUE; diff --git a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c index 29ff02d00ac519bab9629b2b8db80bb809d33f27..5620e28deef434821dbc47dba08962104cd343ba 100644 --- a/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c +++ b/src/lib-sieve/plugins/enotify/mailto/ntfy-mailto.c @@ -575,8 +575,8 @@ ntfy_mailto_send(const struct sieve_enotify_exec_env *nenv, } else if (ret == 0) { if (mtactx->from_address != NULL) from_smtp = mtactx->from_address; - else if (svinst->user_email != NULL) - from_smtp = svinst->user_email; + else if (svinst->set->parsed.user_email != NULL) + from_smtp = svinst->set->parsed.user_email; else { from_smtp = sieve_get_postmaster_smtp(senv); if (from == NULL) @@ -763,7 +763,7 @@ ntfy_mailto_action_execute(const struct sieve_enotify_exec_env *nenv, const char *const *hdsp; int ret; - owner_email = svinst->user_email; + owner_email = svinst->set->parsed.user_email; if (owner_email == NULL && (nenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) == 0) owner_email = sieve_message_get_final_recipient(nenv->msgctx); diff --git a/src/lib-sieve/plugins/vacation/cmd-vacation.c b/src/lib-sieve/plugins/vacation/cmd-vacation.c index 2748574e638ffa6dc59e9ccacda4b8020a05b8bc..cdda942136e01eb924ec2986f2be5da1270301c7 100644 --- a/src/lib-sieve/plugins/vacation/cmd-vacation.c +++ b/src/lib-sieve/plugins/vacation/cmd-vacation.c @@ -1437,8 +1437,8 @@ act_vacation_commit(const struct sieve_action_exec_env *aenv, if (extctx->use_original_recipient) orig_recipient = sieve_message_get_orig_recipient(aenv->msgctx); /* Fetch explicitly configured user email address */ - if (svinst->user_email != NULL) - user_email = svinst->user_email; + if (svinst->set->parsed.user_email != NULL) + user_email = svinst->set->parsed.user_email; /* Is the original message directly addressed to the user or the addresses * specified using the :addresses tag? diff --git a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c index ee20f5a5eb8d1f946871c009159e9fa7582dbb37..11a09bb05aa2959bac735c5800a24629ede493db 100644 --- a/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c +++ b/src/lib-sieve/plugins/vnd.dovecot/report/cmd-report.c @@ -566,8 +566,8 @@ act_report_send(const struct sieve_action_exec_env *aenv, smtp_address_encode_path(orig_recipient)); } } - if (svinst->user_email != NULL) - user = svinst->user_email; + if (svinst->set->parsed.user_email != NULL) + user = svinst->set->parsed.user_email; else if ((eenv->flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0 || (user = sieve_message_get_orig_recipient(msgctx)) == NULL) user = sieve_get_user_email(svinst); diff --git a/src/lib-sieve/sieve-actions.c b/src/lib-sieve/sieve-actions.c index 2b653869b3e6abd90388e989df1e21994949a85f..f7e01ff8d7aaf27b216c6ab886d36317432b8598 100644 --- a/src/lib-sieve/sieve-actions.c +++ b/src/lib-sieve/sieve-actions.c @@ -916,7 +916,7 @@ int sieve_act_redirect_add_to_result(const struct sieve_runtime_env *renv, act->to_address = smtp_address_clone(pool, to_address); if (sieve_result_add_action(renv, NULL, name, &act_redirect, seffects, - act, svinst->max_redirects, + act, svinst->set->max_redirects, TRUE) < 0) return SIEVE_EXEC_FAILURE; diff --git a/src/lib-sieve/sieve-address-source.c b/src/lib-sieve/sieve-address-source.c index 4560e5636caee068f36545451467c0e7d59ee8f9..db8979a2d89f3ea512dc83bd000bd0d540154995 100644 --- a/src/lib-sieve/sieve-address-source.c +++ b/src/lib-sieve/sieve-address-source.c @@ -77,7 +77,7 @@ int sieve_address_source_get_address(struct sieve_address_source *asrc, enum sieve_address_source_type type = asrc->type; if (type == SIEVE_ADDRESS_SOURCE_USER_EMAIL && - svinst->user_email == NULL) + svinst->set->parsed.user_email == NULL) type = SIEVE_ADDRESS_SOURCE_RECIPIENT; if ((flags & SIEVE_EXECUTE_FLAG_NO_ENVELOPE) != 0) { @@ -104,7 +104,7 @@ int sieve_address_source_get_address(struct sieve_address_source *asrc, *addr_r = sieve_message_get_orig_recipient(msgctx); return 1; case SIEVE_ADDRESS_SOURCE_USER_EMAIL: - *addr_r = svinst->user_email; + *addr_r = svinst->set->parsed.user_email; return 1; case SIEVE_ADDRESS_SOURCE_POSTMASTER: *addr_r = sieve_get_postmaster_smtp(senv); diff --git a/src/lib-sieve/sieve-address-source.h b/src/lib-sieve/sieve-address-source.h index b7a2f9ebfc85b88a11642e70f26d5faa0e5bc5ac..5a300ff7a404914462f2d1b826968b57d7f645a9 100644 --- a/src/lib-sieve/sieve-address-source.h +++ b/src/lib-sieve/sieve-address-source.h @@ -3,6 +3,8 @@ #include "sieve-common.h" +struct sieve_message_context; + enum sieve_address_source_type { SIEVE_ADDRESS_SOURCE_DEFAULT = 0, SIEVE_ADDRESS_SOURCE_SENDER, diff --git a/src/lib-sieve/sieve-binary.c b/src/lib-sieve/sieve-binary.c index 9d620a7eb88dbb2f1ba0831b72858089d4a6adf5..774ce705951d411e814408d2d29a8b9522dbd1d1 100644 --- a/src/lib-sieve/sieve-binary.c +++ b/src/lib-sieve/sieve-binary.c @@ -195,7 +195,7 @@ void sieve_binary_get_resource_usage(struct sieve_binary *sbin, { struct sieve_binary_header *header = &sbin->header; time_t update_time = header->resource_usage.update_time; - unsigned int timeout = sbin->svinst->resource_usage_timeout_secs; + unsigned int timeout = sbin->svinst->set->resource_usage_timeout; if (update_time != 0 && (ioloop_time - update_time) > (time_t)timeout) i_zero(&header->resource_usage); diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index 53068dd3f45eb1145eaa28ebc1ffc9a5ef99b1df..6d1c78ad555f54ec537d4c7811f3e58a5dcdef99 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -4,6 +4,9 @@ #include "lib.h" #include "sieve.h" +#ifndef SETTINGS_PLUGIN +#include "sieve-settings.h" +#endif #include <sys/types.h> @@ -162,8 +165,6 @@ extern struct event_category event_category_sieve; * Sieve engine instance */ -#include "sieve-address-source.h" - struct sieve_instance { /* Main engine pool */ pool_t pool; @@ -201,14 +202,8 @@ struct sieve_instance { enum sieve_delivery_phase delivery_phase; /* Settings */ - size_t max_script_size; - unsigned int max_actions; - unsigned int max_redirects; - unsigned int max_cpu_time_secs; - unsigned int resource_usage_timeout_secs; - const struct smtp_address *user_email, *user_email_implicit; - struct sieve_address_source redirect_from; - unsigned int redirect_duplicate_period; + const struct sieve_settings *set; + const struct smtp_address *user_email_implicit; }; /* diff --git a/src/lib-sieve/sieve-interpreter.c b/src/lib-sieve/sieve-interpreter.c index e0bd6ee3159eeddf89755321d80338a88a6536be..67a3286ef9ff7e83f92478be3ab19236a59a53e7 100644 --- a/src/lib-sieve/sieve-interpreter.c +++ b/src/lib-sieve/sieve-interpreter.c @@ -935,8 +935,8 @@ int sieve_interpreter_continue(struct sieve_interpreter *interp, if (interrupted != NULL) *interrupted = FALSE; - if (svinst->max_cpu_time_secs > 0) { - climit = cpu_limit_init(svinst->max_cpu_time_secs, + if (svinst->set->max_cpu_time > 0) { + climit = cpu_limit_init(svinst->set->max_cpu_time, CPU_LIMIT_TYPE_USER); } diff --git a/src/lib-sieve/sieve-lexer.c b/src/lib-sieve/sieve-lexer.c index 409f5e1a54b703e6e2ea91077c405634d0cc7b7a..f916bfabec859b759f6f749c9b143a66378b8540 100644 --- a/src/lib-sieve/sieve-lexer.c +++ b/src/lib-sieve/sieve-lexer.c @@ -66,11 +66,11 @@ sieve_lexer_create(struct sieve_script *script, /* Check script size */ if (i_stream_stat(stream, TRUE, &st) >= 0 && st->st_size > 0 && - svinst->max_script_size > 0 && - (uoff_t)st->st_size > svinst->max_script_size) { + svinst->set->max_script_size > 0 && + (uoff_t)st->st_size > svinst->set->max_script_size) { sieve_error(ehandler, sieve_script_name(script), "sieve script is too large (max %zu bytes)", - svinst->max_script_size); + svinst->set->max_script_size); if (error_code_r != NULL) *error_code_r = SIEVE_ERROR_NOT_POSSIBLE; return NULL; diff --git a/src/lib-sieve/sieve-result.c b/src/lib-sieve/sieve-result.c index 1ed4adf105ad06709ae6429d877f3bbf40f15a06..5b8da5edbd4647d15e76fb9f5875a7f1b754785a 100644 --- a/src/lib-sieve/sieve-result.c +++ b/src/lib-sieve/sieve-result.c @@ -537,14 +537,15 @@ _sieve_result_add_action(const struct sieve_runtime_env *renv, raction = kaction; } else { /* Check policy limit on total number of actions */ - if (svinst->max_actions > 0 && - result->action_count >= svinst->max_actions) + if (svinst->set->max_actions > 0 && + result->action_count >= svinst->set->max_actions) { sieve_runtime_error( renv, action.location, "total number of actions exceeds policy limit " "(%u > %u)", - result->action_count+1, svinst->max_actions); + result->action_count+1, + svinst->set->max_actions); return -1; } diff --git a/src/lib-sieve/sieve-settings.c b/src/lib-sieve/sieve-settings.c new file mode 100644 index 0000000000000000000000000000000000000000..744cb5f0210b5779eb40490affea10eab496cb52 --- /dev/null +++ b/src/lib-sieve/sieve-settings.c @@ -0,0 +1,106 @@ +/* Copyright (c) 2024 Pigeonhole authors, see the included COPYING file + */ + +#include "lib.h" +#include "array.h" +#include "settings.h" +#include "settings-parser.h" + +#include "sieve-limits.h" +#include "sieve-settings.h" + +#include <ctype.h> + +static bool sieve_settings_check(void *_set, pool_t pool, const char **error_r); + +#undef DEF +#define DEF(type, name) SETTING_DEFINE_STRUCT_##type( \ + SIEVE_SETTINGS_FILTER"_"#name, name, struct sieve_settings) + +static const struct setting_define sieve_setting_defines[] = { + DEF(BOOL, enabled), + + DEF(SIZE, max_script_size), + DEF(UINT, max_actions), + DEF(UINT, max_redirects), + DEF(TIME, max_cpu_time), + DEF(TIME, resource_usage_timeout), + + DEF(STR, redirect_envelope_from), + DEF(UINT, redirect_duplicate_period), + + DEF(STR, user_email), + DEF(STR, user_log), + + DEF(STR, trace_dir), + DEF(ENUM, trace_level), + DEF(BOOL, trace_debug), + DEF(BOOL, trace_addresses), + + SETTING_DEFINE_LIST_END, +}; + +static const struct sieve_settings sieve_default_settings = { + .enabled = TRUE, + + .max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE, + .max_actions = SIEVE_DEFAULT_MAX_ACTIONS, + .max_redirects = SIEVE_DEFAULT_MAX_REDIRECTS, + .max_cpu_time = 0, /* FIXME: svinst->env_location == SIEVE_ENV_LOCATION_MS */ + + .resource_usage_timeout = + SIEVE_DEFAULT_RESOURCE_USAGE_TIMEOUT_SECS, + .redirect_envelope_from = "", + .redirect_duplicate_period = DEFAULT_REDIRECT_DUPLICATE_PERIOD, + + .user_email = "", + .user_log = "", + + .trace_dir = "", + .trace_level = "none:actions:commands:tests:matching", + .trace_debug = FALSE, + .trace_addresses = FALSE, +}; + +const struct setting_parser_info sieve_setting_parser_info = { + .name = "sieve", + + .defines = sieve_setting_defines, + .defaults = &sieve_default_settings, + + .struct_size = sizeof(struct sieve_settings), + + .check_func = sieve_settings_check, + + .pool_offset1 = 1 + offsetof(struct sieve_settings, pool), +}; + +/* <settings checks> */ +static bool +sieve_settings_check(void *_set, pool_t pool, const char **error_r) +{ + struct sieve_settings *set = _set; + struct smtp_address *address = NULL; + const char *error; + + if (!sieve_address_source_parse( + pool, set->redirect_envelope_from, + &set->parsed.redirect_envelope_from)) { + *error_r = t_strdup_printf("Invalid address source '%s'", + set->redirect_envelope_from); + return FALSE; + } + + if (*set->user_email != '\0' && + smtp_address_parse_path(pool, set->user_email, + SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL, + &address, &error) < 0) { + *error_r = t_strdup_printf( + "Invalid SMTP address '%s': %s", + set->user_email, error); + return FALSE; + } + set->parsed.user_email = address; + return TRUE; +} +/* </settings checks> */ diff --git a/src/lib-sieve/sieve-settings.h b/src/lib-sieve/sieve-settings.h new file mode 100644 index 0000000000000000000000000000000000000000..568963eac260f971b56207ff80f9557fef5ac44c --- /dev/null +++ b/src/lib-sieve/sieve-settings.h @@ -0,0 +1,43 @@ +#ifndef SIEVE_SETTINGS_H +#define SIEVE_SETTINGS_H + +#include "smtp-address.h" + +#include "sieve-config.h" +#include "sieve-address-source.h" + +#define SIEVE_SETTINGS_FILTER "sieve" + +struct sieve_address_source; + +struct sieve_settings { + pool_t pool; + + bool enabled; + + size_t max_script_size; + unsigned int max_actions; + unsigned int max_redirects; + unsigned int max_cpu_time; + unsigned int resource_usage_timeout; + + const char* redirect_envelope_from; + unsigned int redirect_duplicate_period; + + const char *user_email; + const char *user_log; + + const char *trace_dir; + const char *trace_level; + bool trace_debug; + bool trace_addresses; + + struct { + struct sieve_address_source redirect_envelope_from; + const struct smtp_address *user_email; + } parsed; +}; + +extern const struct setting_parser_info sieve_setting_parser_info; + +#endif diff --git a/src/lib-sieve/sieve-settings.old.c b/src/lib-sieve/sieve-settings.old.c index 7068c2691f2ef9a00a0b829b094f7109ccc34362..adf2752c4b0f617cc54ef3967927e7bf6f6519e7 100644 --- a/src/lib-sieve/sieve-settings.old.c +++ b/src/lib-sieve/sieve-settings.old.c @@ -189,82 +189,3 @@ bool sieve_setting_get_duration_value(struct sieve_instance *svinst, *value_r = (unsigned int)(value * multiply); return TRUE; } - -/* - * Main Sieve engine settings - */ - -void sieve_settings_load(struct sieve_instance *svinst) -{ - const char *str_setting, *error; - unsigned long long int uint_setting; - size_t size_setting; - sieve_number_t period; - - svinst->max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE; - if (sieve_setting_get_size_value(svinst, "sieve_max_script_size", - &size_setting)) - svinst->max_script_size = size_setting; - - svinst->max_actions = SIEVE_DEFAULT_MAX_ACTIONS; - if (sieve_setting_get_uint_value(svinst, "sieve_max_actions", - &uint_setting)) - svinst->max_actions = (unsigned int)uint_setting; - - svinst->max_redirects = SIEVE_DEFAULT_MAX_REDIRECTS; - if (sieve_setting_get_uint_value(svinst, "sieve_max_redirects", - &uint_setting)) - svinst->max_redirects = (unsigned int)uint_setting; - - svinst->max_cpu_time_secs = - (svinst->env_location == SIEVE_ENV_LOCATION_MS ? - 0 : SIEVE_DEFAULT_MAX_CPU_TIME_SECS); - if (sieve_setting_get_duration_value(svinst, "sieve_max_cpu_time", - &period)) { - if (period > (UINT_MAX / 1000)) - svinst->max_cpu_time_secs = (UINT_MAX / 1000); - else - svinst->max_cpu_time_secs = (unsigned int)period; - } - svinst->resource_usage_timeout_secs = - SIEVE_DEFAULT_RESOURCE_USAGE_TIMEOUT_SECS; - if (sieve_setting_get_duration_value( - svinst, "sieve_resource_usage_timeout", &period)) { - if (period > UINT_MAX) - svinst->resource_usage_timeout_secs = UINT_MAX; - else { - svinst->resource_usage_timeout_secs = - (unsigned int)period; - } - } - - (void)sieve_address_source_parse_from_setting( - svinst, svinst->pool, "sieve_redirect_envelope_from", - &svinst->redirect_from); - - svinst->redirect_duplicate_period = DEFAULT_REDIRECT_DUPLICATE_PERIOD; - if (sieve_setting_get_duration_value( - svinst, "sieve_redirect_duplicate_period", &period)) { - if (period > UINT_MAX) - svinst->redirect_duplicate_period = UINT_MAX; - else { - svinst->redirect_duplicate_period = - (unsigned int)period; - } - } - - str_setting = sieve_setting_get(svinst, "sieve_user_email"); - if (str_setting != NULL && *str_setting != '\0') { - struct smtp_address *address; - if (smtp_address_parse_path( - svinst->pool, str_setting, - SMTP_ADDRESS_PARSE_FLAG_BRACKETS_OPTIONAL, - &address, &error) < 0) { - e_warning(svinst->event, - "Invalid address value for setting " - "'sieve_user_email': %s", error); - } else { - svinst->user_email = address; - } - } -} diff --git a/src/lib-sieve/sieve-settings.old.h b/src/lib-sieve/sieve-settings.old.h index a5457ec93f8bb1bc162e15bd2edd39e7c17e2ec2..4038299ef1d1f5ecd22a8efb8e30720354bddc0d 100644 --- a/src/lib-sieve/sieve-settings.old.h +++ b/src/lib-sieve/sieve-settings.old.h @@ -31,12 +31,6 @@ bool sieve_setting_get_duration_value(struct sieve_instance *svinst, const char *setting, sieve_number_t *value_r); -/* - * Main Sieve engine settings - */ - -void sieve_settings_load(struct sieve_instance *svinst); - /* * Home directory */ diff --git a/src/lib-sieve/sieve-storage.c b/src/lib-sieve/sieve-storage.c index 462313ae6c3b62b27ad3c214505434c5234ee3a5..20d6e027f0711795b5e74d1f8737d110a999c2a4 100644 --- a/src/lib-sieve/sieve-storage.c +++ b/src/lib-sieve/sieve-storage.c @@ -492,7 +492,7 @@ int sieve_storage_create_personal(struct sieve_instance *svinst, enum sieve_error *error_code_r) { struct sieve_storage *storage = NULL; - const char *set_enabled, *set_default, *set_default_name; + const char *set_default, *set_default_name; enum sieve_error error_code; int ret; @@ -503,8 +503,7 @@ int sieve_storage_create_personal(struct sieve_instance *svinst, error_code_r = &error_code; /* Check whether Sieve is disabled for this user */ - if ((set_enabled = sieve_setting_get(svinst, "sieve_enabled")) != NULL && - strcasecmp(set_enabled, "no") == 0) { + if (!svinst->set->enabled) { e_debug(svinst->event, "Sieve is disabled for this user"); *error_code_r = SIEVE_ERROR_NOT_POSSIBLE; diff --git a/src/lib-sieve/sieve.c b/src/lib-sieve/sieve.c index ca90a3ac3d0c8ca93d25dd6a3d5947736a3d4883..f3625c1b7733b5ab82cd4a83fe313f5f472253f6 100644 --- a/src/lib-sieve/sieve.c +++ b/src/lib-sieve/sieve.c @@ -10,6 +10,7 @@ #include "eacces-error.h" #include "home-expand.h" #include "hostpid.h" +#include "settings.h" #include "message-address.h" #include "mail-user.h" @@ -57,6 +58,8 @@ int sieve_init(const struct sieve_environment *env, { struct event *event; struct sieve_instance *svinst; + const char *error; + struct sieve_settings *set; const char *domain; pool_t pool; @@ -67,6 +70,13 @@ int sieve_init(const struct sieve_environment *env, event_set_forced_debug(event, debug); event_set_append_log_prefix(event, "sieve: "); event_add_str(event, "user", env->username); + event_set_ptr(event, SETTINGS_EVENT_FILTER_NAME, SIEVE_SETTINGS_FILTER); + if (settings_get(event, &sieve_setting_parser_info, 0, + &set, &error) < 0) { + e_error(event, "%s", error); + event_unref(&event); + return -1; + } /* Create Sieve engine instance */ pool = pool_alloconly_create("sieve", 8192); @@ -83,6 +93,7 @@ int sieve_init(const struct sieve_environment *env, svinst->env_location = env->location; svinst->delivery_phase = env->delivery_phase; svinst->event = event; + svinst->set = set; /* Determine domain */ if (env->domainname != NULL && *(env->domainname) != '\0') @@ -114,10 +125,6 @@ int sieve_init(const struct sieve_environment *env, e_debug(event, "%s version %s initializing", PIGEONHOLE_NAME, PIGEONHOLE_VERSION_FULL); - /* Read configuration */ - - sieve_settings_load(svinst); - /* Initialize extensions */ if (sieve_extensions_init(svinst) < 0) { sieve_deinit(&svinst); @@ -150,11 +157,28 @@ void sieve_deinit(struct sieve_instance **_svinst) sieve_extensions_deinit(svinst); sieve_errors_deinit(svinst); + settings_free(svinst->set); event_unref(&svinst->event); pool_unref(&(svinst)->pool); } +int sieve_settings_reload(struct sieve_instance *svinst) +{ + struct sieve_settings *set; + const char *error; + + if (settings_get(svinst->event, &sieve_setting_parser_info, 0, + &set, &error) < 0) { + e_error(svinst->event, "%s", error); + return -1; + } + + settings_free(svinst->set); + svinst->set = set; + return 0; +} + void sieve_set_extensions(struct sieve_instance *svinst, const char *extensions) { sieve_extensions_set_string(svinst, extensions, FALSE, FALSE); @@ -974,17 +998,17 @@ int sieve_multiscript_finish(struct sieve_multiscript **_mscript, unsigned int sieve_max_redirects(struct sieve_instance *svinst) { - return svinst->max_redirects; + return svinst->set->max_redirects; } unsigned int sieve_max_actions(struct sieve_instance *svinst) { - return svinst->max_actions; + return svinst->set->max_actions; } size_t sieve_max_script_size(struct sieve_instance *svinst) { - return svinst->max_script_size; + return svinst->set->max_script_size; } /* @@ -995,10 +1019,10 @@ const char * sieve_user_get_log_path(struct sieve_instance *svinst, struct sieve_script *user_script) { - const char *log_path = NULL; + const char *log_path = (*svinst->set->user_log == '\0' ? + NULL : svinst->set->user_log); /* Determine user log file path */ - log_path = sieve_setting_get(svinst, "sieve_user_log"); if (log_path == NULL) { const char *path; @@ -1095,11 +1119,10 @@ int sieve_trace_log_create_dir(struct sieve_instance *svinst, const char *dir, int sieve_trace_log_open(struct sieve_instance *svinst, struct sieve_trace_log **trace_log_r) { - const char *trace_dir = - sieve_setting_get(svinst, "sieve_trace_dir"); + const char *trace_dir = svinst->set->trace_dir; *trace_log_r = NULL; - if (trace_dir == NULL) + if (*trace_dir == '\0') return -1; if (svinst->home_dir != NULL) { @@ -1165,14 +1188,11 @@ void sieve_trace_log_free(struct sieve_trace_log **_trace_log) int sieve_trace_config_get(struct sieve_instance *svinst, struct sieve_trace_config *tr_config) { - const char *tr_level = - sieve_setting_get(svinst, "sieve_trace_level"); - bool tr_debug, tr_addresses; + const char *tr_level = svinst->set->trace_level; i_zero(tr_config); - if (tr_level == NULL || *tr_level == '\0' || - strcasecmp(tr_level, "none") == 0) + if (*tr_level == '\0' || strcasecmp(tr_level, "none") == 0) return -1; if (strcasecmp(tr_level, "actions") == 0) @@ -1188,16 +1208,9 @@ int sieve_trace_config_get(struct sieve_instance *svinst, return -1; } - tr_debug = FALSE; - (void)sieve_setting_get_bool_value(svinst, "sieve_trace_debug", - &tr_debug); - tr_addresses = FALSE; - (void)sieve_setting_get_bool_value(svinst, "sieve_trace_addresses", - &tr_addresses); - - if (tr_debug) + if (svinst->set->trace_debug) tr_config->flags |= SIEVE_TRFLG_DEBUG; - if (tr_addresses) + if (svinst->set->trace_addresses) tr_config->flags |= SIEVE_TRFLG_ADDRESSES; return 0; } @@ -1236,8 +1249,8 @@ const struct smtp_address *sieve_get_user_email(struct sieve_instance *svinst) if (svinst->user_email_implicit != NULL) return svinst->user_email_implicit; - if (svinst->user_email != NULL) - return svinst->user_email; + if (svinst->set->parsed.user_email != NULL) + return svinst->set->parsed.user_email; if (smtp_address_parse_mailbox(svinst->pool, username, 0, &address, NULL) >= 0) { @@ -1314,10 +1327,11 @@ bool sieve_resource_usage_is_excessive( struct sieve_instance *svinst, const struct sieve_resource_usage *rusage) { - i_assert(svinst->max_cpu_time_secs <= (UINT_MAX / 1000)); - if (svinst->max_cpu_time_secs == 0) + i_assert(svinst->set->max_cpu_time <= (UINT_MAX / 1000)); + if (svinst->set->max_cpu_time == 0) return FALSE; - return (rusage->cpu_time_msecs > (svinst->max_cpu_time_secs * 1000)); + return (rusage->cpu_time_msecs > + (svinst->set->max_cpu_time * 1000)); } const char * diff --git a/src/lib-sieve/sieve.h b/src/lib-sieve/sieve.h index cd4ff7b6de80f1816c5406153dce085271a19e57..29bd320a2e7da822544bc62a88651f5b135fcd26 100644 --- a/src/lib-sieve/sieve.h +++ b/src/lib-sieve/sieve.h @@ -21,6 +21,9 @@ int sieve_init(const struct sieve_environment *env, /* Free all memory allocated by the sieve engine. */ void sieve_deinit(struct sieve_instance **_svinst); +/* Reload main engine settings */ +int sieve_settings_reload(struct sieve_instance *svinst); + /* Get capability string for a particular extension. */ const char * sieve_get_capabilities(struct sieve_instance *svinst, const char *name); diff --git a/src/plugins/imap-filter-sieve/imap-filter-sieve.c b/src/plugins/imap-filter-sieve/imap-filter-sieve.c index cc3cb51ab11936c2fe4d85d3966b7c483d58de95..150f860615c76c715b2400b2b2c13d213f8063d9 100644 --- a/src/plugins/imap-filter-sieve/imap-filter-sieve.c +++ b/src/plugins/imap-filter-sieve/imap-filter-sieve.c @@ -1041,8 +1041,8 @@ imap_sieve_filter_get_msgdata(struct imap_filter_sieve_context *sctx, "Failed to parse Delivered-To header"); } if (rcpt_to == NULL) { - if (svinst->user_email != NULL) - rcpt_to = svinst->user_email; + if (svinst->set->parsed.user_email != NULL) + rcpt_to = svinst->set->parsed.user_email; else if (smtp_address_parse_username(sctx->pool, user->username, &user_addr, &error) < 0) { e_warning(sieve_get_event(svinst), diff --git a/src/testsuite/cmd-test-config.c b/src/testsuite/cmd-test-config.c index a6eabdf3108355aa9a0bc8b94fc6ba4e30485302..565256d94ee812ddb7de3e2739458f7fa6e0ca99 100644 --- a/src/testsuite/cmd-test-config.c +++ b/src/testsuite/cmd-test-config.c @@ -477,7 +477,11 @@ cmd_test_config_reload_operation_execute(const struct sieve_runtime_env *renv, "reload configuration for sieve engine"); } - sieve_settings_load(eenv->svinst); + if (sieve_settings_reload(eenv->svinst) < 0) { + return testsuite_test_fail_cstr( + renv, "test_config_reload: " + "failed to reload sieve engine settings"); + } } else { if (sieve_runtime_trace_active(renv, SIEVE_TRLVL_COMMANDS)) { sieve_runtime_trace( diff --git a/src/testsuite/testsuite-settings.c b/src/testsuite/testsuite-settings.c index 51d7d3eeb7b9cf32c09861f8d3d87667c7cb1852..a1b6b5c6ca85982d1861176af32c27bfe31fed38 100644 --- a/src/testsuite/testsuite-settings.c +++ b/src/testsuite/testsuite-settings.c @@ -5,9 +5,12 @@ #include "hash.h" #include "imem.h" #include "strfuncs.h" +#include "settings.h" #include "mail-user.h" #include "sieve-common.h" +#include "sieve-settings.h" +#include "sieve-tool.h" #include "testsuite-common.h" #include "testsuite-mailstore.h" @@ -51,12 +54,30 @@ void testsuite_settings_deinit(void) } static const char * -testsuite_setting_get(struct sieve_instance *svinst ATTR_UNUSED, - void *context ATTR_UNUSED, const char *identifier) +testsuite_setting_get(struct sieve_instance *svinst, void *context ATTR_UNUSED, + const char *identifier) { + const struct sieve_settings *svset = svinst->set; struct testsuite_setting *setting; struct mail_user *user; + if (strcmp(identifier, "sieve_max_script_size") == 0) + return t_strdup_printf("%zu", svset->max_script_size); + else if (strcmp(identifier, "sieve_max_actions") == 0) + return t_strdup_printf("%u", svset->max_actions); + else if (strcmp(identifier, "sieve_max_redirects") == 0) + return t_strdup_printf("%u", svset->max_redirects); + else if (strcmp(identifier, "sieve_max_cpu_time") == 0) + return t_strdup_printf("%u", svset->max_cpu_time); + else if (strcmp(identifier, "sieve_resource_usage_timeout") == 0) + return t_strdup_printf("%u", svset->resource_usage_timeout); + else if (strcmp(identifier, "sieve_redirect_envelope_from") == 0) + return svset->redirect_envelope_from; + else if (strcmp(identifier, "sieve_redirect_duplicate_period") == 0) + return t_strdup_printf("%u", svset->redirect_duplicate_period); + else if (strcmp(identifier, "sieve_user_email") == 0) + return svset->user_email; + setting = hash_table_lookup(settings, identifier); if (setting != NULL) return setting->value; @@ -69,6 +90,18 @@ testsuite_setting_get(struct sieve_instance *svinst ATTR_UNUSED, void testsuite_setting_set(const char *identifier, const char *value) { + struct sieve_instance *svinst = testsuite_sieve_instance; + + if (svinst != NULL) { + struct settings_root *set_root; + + set_root = settings_root_find(svinst->event); + settings_root_override_remove(set_root, identifier, + SETTINGS_OVERRIDE_TYPE_CODE); + settings_root_override(set_root, identifier, value, + SETTINGS_OVERRIDE_TYPE_CODE); + } + struct testsuite_setting *setting = hash_table_lookup(settings, identifier); @@ -86,6 +119,16 @@ void testsuite_setting_set(const char *identifier, const char *value) void testsuite_setting_unset(const char *identifier) { + struct sieve_instance *svinst = testsuite_sieve_instance; + + if (svinst != NULL) { + struct settings_root *set_root; + + set_root = settings_root_find(svinst->event); + settings_root_override_remove(set_root, identifier, + SETTINGS_OVERRIDE_TYPE_CODE); + } + struct testsuite_setting *setting = hash_table_lookup(settings, identifier); diff --git a/tests/execute/errors-cpu-limit.svtest b/tests/execute/errors-cpu-limit.svtest index 4a045bc46e3494b5f7efa0e83525be9f013399aa..a87375dc48c51149490830b91c5544e3441dcb25 100644 --- a/tests/execute/errors-cpu-limit.svtest +++ b/tests/execute/errors-cpu-limit.svtest @@ -1,6 +1,6 @@ require "vnd.dovecot.testsuite"; -test_config_set "sieve_max_cpu_time" "2"; +test_config_set "sieve_max_cpu_time" "2s"; test_config_reload; test_set "message" text: