diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/src/deliver.c | 61 | ||||
-rw-r--r-- | src/src/globals.c | 1 | ||||
-rw-r--r-- | src/src/structs.h | 1 | ||||
-rw-r--r-- | src/src/transports/smtp.c | 4 |
4 files changed, 46 insertions, 21 deletions
diff --git a/src/src/deliver.c b/src/src/deliver.c index d33cf799a..5000f1cbc 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -3844,9 +3844,20 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) } /* Get the flag which specifies whether the transport can handle different - domains that nevertheless resolve to the same set of hosts. */ - - multi_domain = tp->multi_domain; + domains that nevertheless resolve to the same set of hosts. If it needs + expanding, get variables set: $address_data, $domain_data, $localpart_data, + $host, $host_address, $host_port. */ + if (tp->expand_multi_domain) + deliver_set_expansions(addr); + + if (exp_bool(addr, US"transport", tp->name, D_transport, + US"multi_domain", tp->multi_domain, tp->expand_multi_domain, + &multi_domain) != OK) + { + deliver_set_expansions(NULL); + remote_post_process(addr, LOG_MAIN|LOG_PANIC, addr->message, fallback); + continue; + } /* Get the maximum it can handle in one envelope, with zero meaning unlimited, which is forced for the MUA wrapper case. */ @@ -3915,26 +3926,35 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) entirely different domains. The host list pointers can be NULL in the case where the hosts are defined in the transport. There is also a configured maximum limit of addresses that can be handled at once (see comments above - for how it is computed). */ + for how it is computed). + If the transport does not handle multiple domains, enforce that also, + and if it might need a per-address check for this, re-evaluate it. + */ while ((next = *anchor) != NULL && address_count < address_count_max) { - if ((multi_domain || Ustrcmp(next->domain, addr->domain) == 0) - && - tp == next->transport - && - same_hosts(next->host_list, addr->host_list) - && - same_strings(next->p.errors_address, addr->p.errors_address) - && - same_headers(next->p.extra_headers, addr->p.extra_headers) - && - same_ugid(tp, next, addr) - && - (next->p.remove_headers == addr->p.remove_headers || - (next->p.remove_headers != NULL && - addr->p.remove_headers != NULL && - Ustrcmp(next->p.remove_headers, addr->p.remove_headers) == 0))) + BOOL md; + if ( (multi_domain || Ustrcmp(next->domain, addr->domain) == 0) + && tp == next->transport + && same_hosts(next->host_list, addr->host_list) + && same_strings(next->p.errors_address, addr->p.errors_address) + && same_headers(next->p.extra_headers, addr->p.extra_headers) + && same_ugid(tp, next, addr) + && ( next->p.remove_headers == addr->p.remove_headers + || ( next->p.remove_headers != NULL + && addr->p.remove_headers != NULL + && Ustrcmp(next->p.remove_headers, addr->p.remove_headers) == 0 + ) ) + && ( !multi_domain + || ( ( + !tp->expand_multi_domain || (deliver_set_expansions(next), 1), + exp_bool(addr, + US"transport", next->transport->name, D_transport, + US"multi_domain", next->transport->multi_domain, + next->transport->expand_multi_domain, &md) == OK + ) + && md + ) ) ) { *anchor = next->next; next->next = NULL; @@ -3944,6 +3964,7 @@ for (delivery_count = 0; addr_remote != NULL; delivery_count++) address_count++; } else anchor = &(next->next); + deliver_set_expansions(NULL); } /* If we are acting as an MUA wrapper, all addresses must go in a single diff --git a/src/src/globals.c b/src/src/globals.c index fb705d9d8..f7c67d76f 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1356,6 +1356,7 @@ transport_instance transport_defaults = { NULL, /* batch_id */ NULL, /* home_dir */ NULL, /* current_dir */ + NULL, /* expand-multi-domain */ TRUE, /* multi-domain */ FALSE, /* overrides_hosts */ 100, /* max_addresses */ diff --git a/src/src/structs.h b/src/src/structs.h index 259d9af71..2250bbbde 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -148,6 +148,7 @@ typedef struct transport_instance { uschar *home_dir; /* ) Used only for local transports */ uschar *current_dir; /* ) */ /**************************************/ + uschar *expand_multi_domain; /* ) */ BOOL multi_domain; /* ) */ BOOL overrides_hosts; /* ) Used only for remote transports */ int max_addresses; /* ) */ diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index 33d357f7a..69bbc4d0c 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -19,6 +19,8 @@ before the lower case letters). Some live in the transport_instance block so as to be publicly visible; these are flagged with opt_public. */ optionlist smtp_transport_options[] = { + { "*expand_multi_domain", opt_stringptr | opt_hidden | opt_public, + (void *)offsetof(transport_instance, expand_multi_domain) }, { "*expand_retry_include_ip_address", opt_stringptr | opt_hidden, (void *)(offsetof(smtp_transport_options_block, expand_retry_include_ip_address)) }, @@ -145,7 +147,7 @@ optionlist smtp_transport_options[] = { (void *)offsetof(smtp_transport_options_block, lmtp_ignore_quota) }, { "max_rcpt", opt_int | opt_public, (void *)offsetof(transport_instance, max_addresses) }, - { "multi_domain", opt_bool | opt_public, + { "multi_domain", opt_expand_bool | opt_public, (void *)offsetof(transport_instance, multi_domain) }, { "port", opt_stringptr, (void *)offsetof(smtp_transport_options_block, port) }, |