diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/src/EDITME | 4 | ||||
-rw-r--r-- | src/src/config.h.defaults | 1 | ||||
-rw-r--r-- | src/src/deliver.c | 40 | ||||
-rw-r--r-- | src/src/exim.c | 3 | ||||
-rw-r--r-- | src/src/expand.c | 10 | ||||
-rw-r--r-- | src/src/globals.c | 11 | ||||
-rw-r--r-- | src/src/globals.h | 12 | ||||
-rw-r--r-- | src/src/structs.h | 3 | ||||
-rw-r--r-- | src/src/transport.c | 4 | ||||
-rw-r--r-- | src/src/transports/smtp.c | 76 | ||||
-rw-r--r-- | src/src/transports/smtp.h | 3 |
11 files changed, 166 insertions, 1 deletions
diff --git a/src/src/EDITME b/src/src/EDITME index e29c1eb25..1db70f715 100644 --- a/src/src/EDITME +++ b/src/src/EDITME @@ -469,6 +469,10 @@ EXIM_MONITOR=eximon.bin # Uncomment the following line to add Per-Recipient-Data-Response support. # EXPERIMENTAL_PRDR=yes +# Uncomment the following line to support Transport post-delivery actions, +# eg. for logging to a database. +# EXPERIMENTAL_TPDA=yes + ############################################################################### # THESE ARE THINGS YOU MIGHT WANT TO SPECIFY # diff --git a/src/src/config.h.defaults b/src/src/config.h.defaults index 1594f6858..bf7ac63fb 100644 --- a/src/src/config.h.defaults +++ b/src/src/config.h.defaults @@ -170,6 +170,7 @@ it's a default value. */ #define EXPERIMENTAL_PRDR #define EXPERIMENTAL_SPF #define EXPERIMENTAL_SRS +#define EXPERIMENTAL_TPDA /* For developers */ #define WANT_DEEPER_PRINTF_CHECKS diff --git a/src/src/deliver.c b/src/src/deliver.c index 23e63d553..bc6a69fbf 100644 --- a/src/src/deliver.c +++ b/src/src/deliver.c @@ -695,6 +695,15 @@ the log line, and reset the store afterwards. Remote deliveries should always have a pointer to the host item that succeeded; local deliveries can have a pointer to a single host item in their host list, for use by the transport. */ +#ifdef EXPERIMENTAL_TPDA + tpda_delivery_ip = NULL; /* presume no successful remote delivery */ + tpda_delivery_port = 0; + tpda_delivery_fqdn = NULL; + tpda_delivery_local_part = NULL; + tpda_delivery_domain = NULL; + tpda_delivery_confirmation = NULL; +#endif + s = reset_point = store_get(size); log_address = string_log_address(addr, (log_write_selector & L_all_parents) != 0, TRUE); @@ -741,7 +750,12 @@ if ((log_extra_selector & LX_delivery_size) != 0) if (addr->transport->info->local) { if (addr->host_list != NULL) + { s = string_append(s, &size, &ptr, 2, US" H=", addr->host_list->name); + #ifdef EXPERIMENTAL_TPDA + tpda_delivery_fqdn = addr->host_list->name; + #endif + } if (addr->shadow_message != NULL) s = string_cat(s, &size, &ptr, addr->shadow_message, Ustrlen(addr->shadow_message)); @@ -760,6 +774,15 @@ else addr->host_used->port)); if (continue_sequence > 1) s = string_cat(s, &size, &ptr, US"*", 1); + + #ifdef EXPERIMENTAL_TPDA + tpda_delivery_ip = addr->host_used->address; + tpda_delivery_port = addr->host_used->port; + tpda_delivery_fqdn = addr->host_used->name; + tpda_delivery_local_part = addr->local_part; + tpda_delivery_domain = addr->domain; + tpda_delivery_confirmation = addr->message; + #endif } #ifdef SUPPORT_TLS @@ -827,6 +850,23 @@ store we used to build the line after writing it. */ s[ptr] = 0; log_write(0, flags, "%s", s); + +#ifdef EXPERIMENTAL_TPDA +if (addr->transport->tpda_delivery_action) + { + DEBUG(D_deliver) + debug_printf(" TPDA(Delivery): tpda_deliver_action=|%s| tpda_delivery_IP=%s\n", + addr->transport->tpda_delivery_action, tpda_delivery_ip); + + router_name = addr->router->name; + transport_name = addr->transport->name; + if (!expand_string(addr->transport->tpda_delivery_action) && *expand_string_message) + log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand tpda_deliver_action in %s: %s\n", + transport_name, expand_string_message); + router_name = NULL; + transport_name = NULL; + } +#endif store_reset(reset_point); return; } diff --git a/src/src/exim.c b/src/src/exim.c index 8ab0456d8..c5053ba7c 100644 --- a/src/src/exim.c +++ b/src/src/exim.c @@ -825,6 +825,9 @@ fprintf(f, "Support for:"); #ifdef EXPERIMENTAL_PRDR fprintf(f, " Experimental_PRDR"); #endif +#ifdef EXPERIMENTAL_TPDA + fprintf(f, " Experimental_TPDA"); +#endif fprintf(f, "\n"); fprintf(f, "Lookups (built-in):"); diff --git a/src/src/expand.c b/src/src/expand.c index edef45dba..a22ee2af4 100644 --- a/src/src/expand.c +++ b/src/src/expand.c @@ -677,6 +677,16 @@ static var_entry var_table[] = { { "tod_logfile", vtype_todlf, NULL }, { "tod_zone", vtype_todzone, NULL }, { "tod_zulu", vtype_todzulu, NULL }, +#ifdef EXPERIMENTAL_TPDA + { "tpda_defer_errno", vtype_int, &tpda_defer_errno }, + { "tpda_defer_errstr", vtype_stringptr, &tpda_defer_errstr }, + { "tpda_delivery_confirmation", vtype_stringptr, &tpda_delivery_confirmation }, + { "tpda_delivery_domain", vtype_stringptr, &tpda_delivery_domain }, + { "tpda_delivery_fqdn", vtype_stringptr, &tpda_delivery_fqdn }, + { "tpda_delivery_ip", vtype_stringptr, &tpda_delivery_ip }, + { "tpda_delivery_local_part",vtype_stringptr,&tpda_delivery_local_part }, + { "tpda_delivery_port", vtype_int, &tpda_delivery_port }, +#endif { "transport_name", vtype_stringptr, &transport_name }, { "value", vtype_stringptr, &lookup_value }, { "version_number", vtype_stringptr, &version_string }, diff --git a/src/src/globals.c b/src/src/globals.c index 05bb0ae86..d4589cd18 100644 --- a/src/src/globals.c +++ b/src/src/globals.c @@ -1280,6 +1280,17 @@ int thismessage_size_limit = 0; int timeout_frozen_after = 0; BOOL timestamps_utc = FALSE; +#ifdef EXPERIMENTAL_TPDA +int tpda_defer_errno = 0; +uschar *tpda_defer_errstr = NULL; +uschar *tpda_delivery_ip = NULL; +int tpda_delivery_port = 0; +uschar *tpda_delivery_fqdn = NULL; +uschar *tpda_delivery_local_part= NULL; +uschar *tpda_delivery_domain = NULL; +uschar *tpda_delivery_confirmation = NULL; +#endif + transport_instance *transports = NULL; transport_instance transport_defaults = { diff --git a/src/src/globals.h b/src/src/globals.h index 2cc16881b..104b5fa7a 100644 --- a/src/src/globals.h +++ b/src/src/globals.h @@ -834,6 +834,18 @@ extern int test_harness_load_avg; /* For use when testing */ extern int thismessage_size_limit; /* Limit for this message */ extern int timeout_frozen_after; /* Max time to keep frozen messages */ extern BOOL timestamps_utc; /* Use UTC for all times */ + +#ifdef EXPERIMENTAL_TPDA +extern int tpda_defer_errno; /* error number set when a remote delivery is deferred with a host error */ +extern uschar *tpda_defer_errstr; /* error string set when a remote delivery is deferred with a host error */ +extern uschar *tpda_delivery_ip; /* IP of host, which has accepted delivery */ +extern int tpda_delivery_port; /* port of host, which has accepted delivery */ +extern uschar *tpda_delivery_fqdn; /* FQDN of host, which has accepted delivery */ +extern uschar *tpda_delivery_local_part;/* local part of address being delivered */ +extern uschar *tpda_delivery_domain; /* domain part of address being delivered */ +extern uschar *tpda_delivery_confirmation; /* SMTP confirmation message */ +#endif + extern uschar *transport_name; /* Name of transport last started */ extern int transport_count; /* Count of bytes transported */ extern int transport_newlines; /* Accurate count of number of newline chars transported */ diff --git a/src/src/structs.h b/src/src/structs.h index 53aa2106b..baf9a0f85 100644 --- a/src/src/structs.h +++ b/src/src/structs.h @@ -184,6 +184,9 @@ typedef struct transport_instance { BOOL log_fail_output; BOOL log_defer_output; BOOL retry_use_local_part; /* Defaults true for local, false for remote */ +#ifdef EXPERIMENTAL_TPDA + uschar *tpda_delivery_action; /* String to expand on success */ +#endif } transport_instance; diff --git a/src/src/transport.c b/src/src/transport.c index 7dd1afb85..d2540be62 100644 --- a/src/src/transport.c +++ b/src/src/transport.c @@ -94,6 +94,10 @@ optionlist optionlist_transports[] = { (void *)offsetof(transport_instance, shadow_condition) }, { "shadow_transport", opt_stringptr|opt_public, (void *)offsetof(transport_instance, shadow) }, +#ifdef EXPERIMENTAL_TPDA + { "tpda_delivery_action",opt_stringptr | opt_public, + (void *)offsetof(transport_instance, tpda_delivery_action) }, +#endif { "transport_filter", opt_stringptr|opt_public, (void *)offsetof(transport_instance, filter_command) }, { "transport_filter_timeout", opt_time|opt_public, diff --git a/src/src/transports/smtp.c b/src/src/transports/smtp.c index b18720cc0..9918f3116 100644 --- a/src/src/transports/smtp.c +++ b/src/src/transports/smtp.c @@ -156,6 +156,10 @@ optionlist smtp_transport_options[] = { { "tls_verify_certificates", opt_stringptr, (void *)offsetof(smtp_transport_options_block, tls_verify_certificates) } #endif +#ifdef EXPERIMENTAL_TPDA + ,{ "tpda_host_defer_action", opt_stringptr, + (void *)offsetof(smtp_transport_options_block, tpda_host_defer_action) }, +#endif }; /* Size of the options list. An extern variable has to be used so that its @@ -233,6 +237,9 @@ smtp_transport_options_block smtp_transport_option_defaults = { NULL, /* dkim_sign_headers */ NULL /* dkim_strict */ #endif +#ifdef EXPERIMENTAL_TPDA + ,NULL /* tpda_host_defer_action */ +#endif }; @@ -577,6 +584,59 @@ else +#ifdef EXPERIMENTAL_TPDA +/************************************************* +* Post-defer action * +*************************************************/ + +/* This expands an arbitrary per-transport string. + It might, for example, be used to write to the database log. + +Arguments: + ob transport options block + addr the address item containing error information + host the current host + +Returns: nothing +*/ + +static void +tpda_deferred(smtp_transport_options_block *ob, address_item *addr, host_item *host) +{ +uschar *action = ob->tpda_host_defer_action; +if (!action) + return; + +tpda_delivery_ip = string_copy(host->address); +tpda_delivery_port = (host->port == PORT_NONE)? 25 : host->port; +tpda_delivery_fqdn = string_copy(host->name); +tpda_delivery_local_part = string_copy(addr->local_part); +tpda_delivery_domain = string_copy(addr->domain); +tpda_defer_errno = addr->basic_errno; + +tpda_defer_errstr = addr->message + ? addr->basic_errno > 0 + ? string_sprintf("%s: %s", addr->message, strerror(addr->basic_errno)) + : string_copy(addr->message) + : addr->basic_errno > 0 + ? string_copy(strerror(addr->basic_errno)) + : NULL; + +DEBUG(D_transport) + debug_printf(" TPDA(host defer): tpda_host_defer_action=|%s| tpda_delivery_IP=%s\n", + action, tpda_delivery_ip); + +router_name = addr->router->name; +transport_name = addr->transport->name; +if (!expand_string(action) && *expand_string_message) + log_write(0, LOG_MAIN|LOG_PANIC, "failed to expand tpda_defer_action in %s: %s\n", + transport_name, expand_string_message); +router_name = transport_name = NULL; +} +#endif + + + /************************************************* * Synchronize SMTP responses * *************************************************/ @@ -1912,7 +1972,12 @@ if (!ok) ok = TRUE; else /* Set up confirmation if needed - applies only to SMTP */ - if ((log_extra_selector & LX_smtp_confirmation) != 0 && !lmtp) + if ( + #ifndef EXPERIMENTAL_TPDA + (log_extra_selector & LX_smtp_confirmation) != 0 && + #endif + !lmtp + ) { uschar *s = string_printing(buffer); conf = (s == buffer)? (uschar *)string_copy(s) : s; @@ -3051,6 +3116,11 @@ for (cutoff_retry = 0; expired && first_addr->basic_errno != ERRNO_TLSFAILURE) write_logs(first_addr, host); + #ifdef EXPERIMENTAL_TPDA + if (rc == DEFER) + tpda_deferred(ob, first_addr, host); + #endif + /* If STARTTLS was accepted, but there was a failure in setting up the TLS session (usually a certificate screwup), and the host is not in hosts_require_tls, and tls_tempfail_tryclear is true, try again, with @@ -3073,6 +3143,10 @@ for (cutoff_retry = 0; expired && expanded_hosts != NULL, &message_defer, TRUE); if (rc == DEFER && first_addr->basic_errno != ERRNO_AUTHFAIL) write_logs(first_addr, host); + #ifdef EXPERIMENTAL_TPDA + if (rc == DEFER) + tpda_deferred(ob, first_addr, host); + #endif } #endif } diff --git a/src/src/transports/smtp.h b/src/src/transports/smtp.h index 8e85294bc..0d8801647 100644 --- a/src/src/transports/smtp.h +++ b/src/src/transports/smtp.h @@ -73,6 +73,9 @@ typedef struct { uschar *dkim_sign_headers; uschar *dkim_strict; #endif + #ifdef EXPERIMENTAL_TPDA + uschar *tpda_host_defer_action; + #endif } smtp_transport_options_block; /* Data for reading the private options. */ |