On Mon, Jan 27, 2014 at 02:51:20PM -0800, Quanah Gibson-Mount wrote:

> >The fallback relay setting is a fixed per-transport setting.  So
> >the fallback relay would not be per-user.  Only the first LMTP
> >server to try (per-user transport table).  Each transport carries
> >a fixed fallback relay in master.cf.
> >
> >So you'd have one transport per "cluster" of mailstores, and an
> >associated fallback that uses the cluster round-robin address.  The
> >user's transport entry would direct the first delivery attempt to
> >"somelmtp:primary-store:port" if it is best to not simply round-robin
> >the deliveries and sending each user's mail to the primary destination
> >for that user is substantially better.
> 
> Ok, makes sense.  That would work well.  Thanks!
The patch below may not even compile, but probably works, give it a try.
As you can see, it is mostly a matter of adding a bit of documentation
and disabling conditionals that make existing code apply only to SMTP.

If it works well for you, and Wietse is not opposed to an
"lmtp_fallback_relay" feature, something like this could be part
of Postfix 2.12.

diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto
index bba32ac..18e6288 100644
--- a/postfix/proto/postconf.proto
+++ b/postfix/proto/postconf.proto
@@ -1492,6 +1492,25 @@ as the right-hand side for backup or primary MX domain 
entries.
 for destinations that it is MX host for.
 </p>
 
+%PARAM lmtp_fallback_relay
+
+<p> Optional list of relay hosts for LMTP destinations that can't be
+found or that are unreachable.  In main.cf elements are separated by
+whitespace or commas.  </p>
+
+<p> By default, mail is returned to the sender when a destination is not
+found, and delivery is deferred when a destination is unreachable.  </p>
+
+<p> The fallback relays must be TCP LMTP destinations, specified without
+a leading "inet:" prefix.  Specify a host or host:port.  Since MX
+lookups do not apply with LMTP, there is no need to use the "[host]" or
+"[host]:port" forms.  If you specify multiple LMTP destinations, Postfix
+will try them in the specified order.  </p>
+
+<p>
+This feature is available in Postfix 2.12 and later.
+</p>
+
 %PARAM fast_flush_domains $relay_domains
 
 <p>
diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h
index 12fd0e1..963d438 100644
--- a/postfix/src/global/mail_params.h
+++ b/postfix/src/global/mail_params.h
@@ -198,7 +198,8 @@ extern char *var_null_relay_maps_key;
 
 #define VAR_SMTP_FALLBACK      "smtp_fallback_relay"
 #define DEF_SMTP_FALLBACK      "$fallback_relay"
-#define VAR_LMTP_FALLBACK      "smtp_fallback_relay"
+#define VAR_LMTP_FALLBACK      "lmtp_fallback_relay"
+#define DEF_LMTP_FALLBACK      ""
 #define DEF_FALLBACK_RELAY     ""
 extern char *var_fallback_relay;
 
diff --git a/postfix/src/smtp/lmtp_params.c b/postfix/src/smtp/lmtp_params.c
index 68a2739..5af852f 100644
--- a/postfix/src/smtp/lmtp_params.c
+++ b/postfix/src/smtp/lmtp_params.c
@@ -1,5 +1,6 @@
     static const CONFIG_STR_TABLE lmtp_str_table[] = {
        VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
+       VAR_LMTP_FALLBACK, DEF_LMTP_FALLBACK, &var_fallback_relay, 0, 0,
        VAR_BESTMX_TRANSP, DEF_BESTMX_TRANSP, &var_bestmx_transp, 0, 0,
        VAR_ERROR_RCPT, DEF_ERROR_RCPT, &var_error_rcpt, 1, 0,
        VAR_LMTP_SASL_PASSWD, DEF_LMTP_SASL_PASSWD, &var_smtp_sasl_passwd, 0, 0,
diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c
index ff278c1..0b84adc 100644
--- a/postfix/src/smtp/smtp_connect.c
+++ b/postfix/src/smtp/smtp_connect.c
@@ -778,9 +778,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char 
*nexthop,
     if (sites->argc == 0)
        msg_panic("null destination: \"%s\"", nexthop);
     non_fallback_sites = sites->argc;
-    /* When we are lmtp(8) var_fallback_relay is null */
-    if (smtp_mode)
-       argv_split_append(sites, var_fallback_relay, ", \t\r\n");
+    argv_split_append(sites, var_fallback_relay, ", \t\r\n");
 
     /*
      * Don't give up after a hard host lookup error until we have tried the
@@ -1055,7 +1053,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const 
char *nexthop,
         * Pay attention to what could be configuration problems, and pretend
         * that these are recoverable rather than bouncing the mail.
         */
-       else if (!SMTP_HAS_SOFT_DSN(why) && smtp_mode) {
+       else if (!SMTP_HAS_SOFT_DSN(why)) {
 
            /*
             * The fall-back destination did not resolve as expected, or it
@@ -1071,7 +1069,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const 
char *nexthop,
             * The next-hop relayhost did not resolve as expected, or it is
             * refusing to talk to us, or mail for it loops back to us.
             */
-           else if (strcmp(sites->argv[0], var_relayhost) == 0) {
+           else if (smtp_mode && strcmp(sites->argv[0], var_relayhost) == 0) {
                msg_warn("%s configuration problem", VAR_RELAYHOST);
                vstring_strcpy(why->status, "4.3.5");
                /* XXX Keep the diagnostic code and MTA. */
@@ -1081,7 +1079,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const 
char *nexthop,
             * Mail for the next-hop destination loops back to myself. Pass
             * the mail to the best_mx_transport or bounce it.
             */
-           else if (SMTP_HAS_LOOP_DSN(why) && *var_bestmx_transp) {
+           else if (smtp_mode && SMTP_HAS_LOOP_DSN(why) && *var_bestmx_transp) 
{
                dsb_reset(why);                 /* XXX */
                state->status = deliver_pass_all(MAIL_CLASS_PRIVATE,
                                                 var_bestmx_transp,

-- 
        Viktor.

Reply via email to