summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/src/deliver.c61
-rw-r--r--src/src/globals.c1
-rw-r--r--src/src/structs.h1
-rw-r--r--src/src/transports/smtp.c4
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) },