diff --git a/INSTALL b/INSTALL index 2fe76b91a1d7bd5f182468b53d3b248d864f348c..39bd9822df51b248e954da29e08a7a583dac633f 100644 --- a/INSTALL +++ b/INSTALL @@ -229,14 +229,15 @@ plugin section of the config file (default values are shown if applicable): appears to originate from the original sender. The following values are supported for this setting: - "sender" - The sender address is used (default) - "recipient" - The final recipient address is used - "orig_recipient" - The original recipient is used + "sender" - The sender address is used (default). + "recipient" - The final recipient address is used. + "orig_recipient" - The original recipient is used. + "postmaster" - The postmaster_address configured for the LDA. "<user@domain>" - Redirected messages are always sent from user@domain. The angle brackets are mandatory. The null "<>" address is also supported. - When the envelope sender of the processed message is the null address "<>", + When the envelope sender of the processed message is the null address "<>", the envelope sender of the redirected message is also always "<>", irrespective of what is configured for this setting. diff --git a/src/lib-sieve/cmd-redirect.c b/src/lib-sieve/cmd-redirect.c index 50cc289171f96ac56521ad1c4d129b0c70d96be1..deb81acdd3ab5c37c734995562371cdf1dea7c6d 100644 --- a/src/lib-sieve/cmd-redirect.c +++ b/src/lib-sieve/cmd-redirect.c @@ -317,8 +317,8 @@ static int act_redirect_send const struct sieve_script_env *senv = aenv->scriptenv; const char *sender = sieve_message_get_sender(msgctx); const char *recipient = sieve_message_get_final_recipient(msgctx); - enum sieve_redirect_envelope_from env_from = - aenv->svinst->redirect_from; + struct sieve_mail_sender *env_from = + &aenv->svinst->redirect_from; struct istream *input; struct ostream *output; const char *error; @@ -350,20 +350,22 @@ static int act_redirect_send when then returns a delivery status notification that also ends up being redirected to the same invalid address. */ - if ( sender != NULL && - env_from != SIEVE_REDIRECT_ENVELOPE_FROM_SENDER ) { - switch ( env_from ) { - case SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT: + if ( sender != NULL ) { + switch ( env_from->source ) { + case SIEVE_MAIL_SENDER_SOURCE_RECIPIENT: sender = sieve_message_get_final_recipient(msgctx); break; - case SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT: + case SIEVE_MAIL_SENDER_SOURCE_ORIG_RECIPIENT: sender = sieve_message_get_orig_recipient(msgctx); break; - case SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT: - sender = aenv->svinst->redirect_from_explicit; + case SIEVE_MAIL_SENDER_SOURCE_POSTMASTER: + sender = senv->postmaster_address; + break; + case SIEVE_MAIL_SENDER_SOURCE_EXPLICIT: + sender = env_from->address; break; default: - i_unreached(); + break; } } diff --git a/src/lib-sieve/sieve-common.h b/src/lib-sieve/sieve-common.h index fe75e45ed4e3394a7bb3d99d337286ac58d84e4d..6e39bc7b2433a88569525268408494e9c6d884fa 100644 --- a/src/lib-sieve/sieve-common.h +++ b/src/lib-sieve/sieve-common.h @@ -21,11 +21,18 @@ typedef uint32_t sieve_number_t; #define SIEVE_MAX_NUMBER ((sieve_number_t) -1) -enum sieve_redirect_envelope_from { - SIEVE_REDIRECT_ENVELOPE_FROM_SENDER, - SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT, - SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT, - SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT +enum sieve_mail_sender_source { + SIEVE_MAIL_SENDER_SOURCE_DEFAULT = 0, + SIEVE_MAIL_SENDER_SOURCE_SENDER, + SIEVE_MAIL_SENDER_SOURCE_RECIPIENT, + SIEVE_MAIL_SENDER_SOURCE_ORIG_RECIPIENT, + SIEVE_MAIL_SENDER_SOURCE_POSTMASTER, + SIEVE_MAIL_SENDER_SOURCE_EXPLICIT +}; + +struct sieve_mail_sender { + enum sieve_mail_sender_source source; + const char *address; }; /* @@ -206,8 +213,7 @@ struct sieve_instance { size_t max_script_size; unsigned int max_actions; unsigned int max_redirects; - enum sieve_redirect_envelope_from redirect_from; - const char *redirect_from_explicit; + struct sieve_mail_sender redirect_from; }; #endif /* __SIEVE_COMMON_H */ diff --git a/src/lib-sieve/sieve-settings.c b/src/lib-sieve/sieve-settings.c index 0997a2e72de79d7df3a3389b34a8ba7f29081481..e5168d7cbb7c1a887003c1e176edae63746fd355 100644 --- a/src/lib-sieve/sieve-settings.c +++ b/src/lib-sieve/sieve-settings.c @@ -217,6 +217,48 @@ bool sieve_setting_get_duration_value return TRUE; } +bool sieve_setting_get_mail_sender_value +(struct sieve_instance *svinst, pool_t pool, const char *setting, + struct sieve_mail_sender *sender) +{ + const char *str_value; + size_t set_len; + + str_value = sieve_setting_get(svinst, setting); + if ( str_value == NULL ) + return FALSE; + + str_value = t_str_trim(str_value); + str_value = t_str_lcase(str_value); + set_len = strlen(str_value); + if ( set_len > 0 ) { + if ( strcmp(str_value, "default") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_DEFAULT; + } else if ( strcmp(str_value, "sender") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_SENDER; + } else if ( strcmp(str_value, "recipient") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_RECIPIENT; + } else if ( strcmp(str_value, "orig_recipient") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_ORIG_RECIPIENT; + } else if ( strcmp(str_value, "postmaster") == 0 ) { + sender->source = SIEVE_MAIL_SENDER_SOURCE_POSTMASTER; + } else if ( str_value[0] == '<' && str_value[set_len-1] == '>') { + sender->source = SIEVE_MAIL_SENDER_SOURCE_EXPLICIT; + + str_value = t_str_trim(t_strndup(str_value+1, set_len-2)); + sender->address = NULL; + if ( *str_value != '\0' ) + sender->address = p_strdup(pool, str_value); + } else { + sieve_sys_warning(svinst, + "Invalid value for setting '%s': '%s'", setting, + str_value); + return FALSE; + } + } + return TRUE; +} + /* * Main Sieve engine settings */ @@ -226,7 +268,6 @@ void sieve_settings_load { unsigned long long int uint_setting; size_t size_setting; - const char *str_setting; svinst->max_script_size = SIEVE_DEFAULT_MAX_SCRIPT_SIZE; if ( sieve_setting_get_size_value @@ -246,36 +287,11 @@ void sieve_settings_load svinst->max_redirects = (unsigned int) uint_setting; } - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_SENDER; - svinst->redirect_from_explicit = NULL; - if ( (str_setting=sieve_setting_get - (svinst, "sieve_redirect_envelope_from")) != NULL ) { - size_t set_len; - - str_setting = t_str_trim(str_setting); - str_setting = t_str_lcase(str_setting); - set_len = strlen(str_setting); - if ( set_len > 0 ) { - if ( strcmp(str_setting, "sender") == 0 ) { - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_SENDER; - } else if ( strcmp(str_setting, "recipient") == 0 ) { - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_RECIPIENT; - } else if ( strcmp(str_setting, "orig_recipient") == 0 ) { - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_ORIG_RECIPIENT; - } else if ( str_setting[0] == '<' && str_setting[set_len-1] == '>') { - svinst->redirect_from = SIEVE_REDIRECT_ENVELOPE_FROM_EXPLICIT; - - str_setting = t_str_trim(t_strndup(str_setting+1, set_len-2)); - if ( *str_setting != '\0' ) { - svinst->redirect_from_explicit = - p_strdup(svinst->pool, str_setting); - } - } else { - sieve_sys_warning(svinst, - "Invalid value `%s' for sieve_redirect_envelope_from setting", - str_setting); - } - } + if (!sieve_setting_get_mail_sender_value + (svinst, svinst->pool, "sieve_redirect_envelope_from", + &svinst->redirect_from)) { + svinst->redirect_from.source = + SIEVE_MAIL_SENDER_SOURCE_DEFAULT; } } diff --git a/src/lib-sieve/sieve-settings.h b/src/lib-sieve/sieve-settings.h index af1b96f932e1ba73b424c62d48aae8c2565f113c..739a98650170ba2f8b0837b1dafc71c7f8f771a7 100644 --- a/src/lib-sieve/sieve-settings.h +++ b/src/lib-sieve/sieve-settings.h @@ -37,6 +37,10 @@ bool sieve_setting_get_duration_value (struct sieve_instance *svinst, const char *setting, sieve_number_t *value_r); +bool sieve_setting_get_mail_sender_value + (struct sieve_instance *svinst, pool_t pool, const char *setting, + struct sieve_mail_sender *sender); + /* * Main Sieve engine settings */