Peer,

> If reinjection of mail fails, Amavis will send a DSN back to the sender to
> notify him about this failure.
>
> But if D_REJECT is active this leads to *2* DSN back to the user: One DSN
> from the sending MTA (because Amavis blocks that mail to the feeding
> MTA), second DSN from Amavis himself.

A bug. Either a reject or a bounce should happen, not both.

As Thomas said, it was not envisaged to have a back-end MTA reject
mail at this late stage, so the situation was not thoroughly tested.

> In my understanding Amavis should not send his own DSN in case of D_REJECT
> if the mail has been already rejected against the feeding local MTA (and
> in case of Postfix' smtpd_proxy_filter also against the external sending
> MTA).

Note there is no dedicated configuration variable to configure what should
happen when a back-end MTA does not want to accept a message. Luckily there
is a %final_destiny_by_ccat, which allows to assign a 'destiny' to
a CC_MTA case:

%final_destiny_by_ccat = (
    CC_VIRUS,       sub { c('final_virus_destiny') },
    CC_BANNED,      sub { c('final_banned_destiny') },
    CC_SPAM,        sub { c('final_spam_destiny') },
    CC_BADH,        sub { c('final_bad_header_destiny') },
    CC_MTA.',2',    D_REJECT,  # in response to 5xx from MTA
    CC_OVERSIZED,   D_BOUNCE,
    CC_CATCHALL,    D_PASS,
  );

This should have sufficed, had it not been for a bug which
forgets to set $r->recip_destiny in case of a MTA reject.

The following patch fixes it (applicable to 2.6.4). It is more
extensive than it need be, because it also makes possible to
obtain a reject text from a %smtp_reason_by_ccat, which was
introduced in 2.6.4. Also, as the D_PASS does not make any sense
in case of a MTA failure (we can't forward anyway, even though
we want to), the patch silently turns a D_PASS into a D_REJECT
for the CC_MTA case, so adjusting %final_destiny_by_ccat is
not really necessary, it's just nice to be explicit.

--- amavisd.orig        2009-06-25 14:39:01.000000000 +0200
+++ amavisd     2009-07-10 19:55:58.000000000 +0200
@@ -1493,4 +1493,5 @@
     CC_SPAM,        sub { c('final_spam_destiny') },
     CC_BADH,        sub { c('final_bad_header_destiny') },
+    CC_MTA.',2',    D_REJECT,
     CC_OVERSIZED,   D_BOUNCE,
     CC_CATCHALL,    D_PASS,
@@ -11317,4 +11318,30 @@
         $msginfo->blocking_ccat($blocking_ccat)
                                           if !defined($msginfo->blocking_ccat);
+        my($final_destiny) =
+          $r->setting_by_contents_category(cr('final_destiny_by_ccat'));
+        if ($final_destiny == D_PASS) {
+          $final_destiny = D_REJECT;  # impossible to pass, change to reject
+        }
+        local($1,$2);
+        $r->recip_destiny($final_destiny);
+        if ($final_destiny == D_DISCARD && $smtp_resp =~ /^5/) {
+          $smtp_resp =~ s{^5(\d\d) 5(\.\d\.\d)}{250 2$2};  # 5xx -> 250
+        }
+        my($smtp_reason) =  # get the custom smtp response reason text
+          $r->setting_by_contents_category(cr('smtp_reason_by_ccat'));
+        $smtp_reason = ''  if !defined $smtp_reason;
+        if ($smtp_reason ne '') {
+          my(%mybuiltins) = %builtins;  # make a local copy
+          $smtp_reason = expand(\$smtp_reason, \%mybuiltins);
+          $smtp_reason = !ref($smtp_reason) ? '' : $$smtp_reason;
+          chomp($smtp_reason); $smtp_reason = sanitize_str($smtp_reason,1);
+          $smtp_reason = substr($smtp_reason,0,100) . "..."
+            if length($smtp_reason) > 100+3;
+        }
+        $smtp_resp =~ /^(\d\d\d(?: \d\.\d\.\d)?)\s*(.*)\z/;
+        my($dis) = $final_destiny == D_DISCARD ? ' Discarded' : '';
+        $r->recip_smtp_response("$1$dis $smtp_reason, $2");
+        $r->recip_done(1); # fake a delivery (confirm delivery to a bit bucket)
+        # note that 5xx status rejects may later be converted to bounces
       }
       $msginfo->header_edits($hdr_edits); # restore original edits just in case
@@ -17775,10 +17802,10 @@
 sub enhance_smtp_response($$$$$) {
   my($smtp_resp,$am_id,$mta_id,$dflt_enhcode,$cmd_name) = @_;
-  local($1,$2,$3); my($resp_shortmsg,$resp_msg);
+  local($1,$2,$3); my($resp_msg);
   my($resp_code,$resp_enhcode) = ('451', '4.5.0');
   if (!defined($smtp_resp) || $smtp_resp eq '') {
-    $resp_shortmsg = 'No resp. to '.$cmd_name;
+    $smtp_resp = sprintf('No resp. to %s', $cmd_name);
   } elsif ($smtp_resp !~ /^[245]\d{2}/) {
-    $resp_shortmsg = 'Bad resp. to '.$cmd_name;
+    $smtp_resp = sprintf('Bad resp. to %s: %s', $cmd_name,$smtp_resp);
   } elsif ($smtp_resp =~ /^ (\d{3}) [ \t]+ ([245] \. \d{1,3} \. \d{1,3})?
                           \s* (.*) \z/xs) {
@@ -17787,9 +17814,7 @@
     if ($resp_enhcode eq '' && $resp_code =~ /^[245]/)
       { $resp_enhcode = $dflt_enhcode; $resp_enhcode =~ s/^\d*/$c/ }
-    $resp_shortmsg = $c eq '2' ? 'Ok' : $c eq '4' ? 'TempFailed' : 'Failed';
   }
-  sprintf("%s %s %s, id=%s, from MTA(%s): %s",
-          $resp_code, $resp_enhcode, $resp_shortmsg,
-          $am_id, $mta_id, $smtp_resp);
+  sprintf("%s %s from MTA(%s): %s",
+          $resp_code, $resp_enhcode, $mta_id, $smtp_resp);
 }
 

The range of choices is now fully supported through
the $final_destiny_by_ccat{(CC_MTA)} setting, i.e.
D_REJECT, D_BOUNCE and D_DISCARD. Usually one would chose
a D_REJECT or D_BOUNCE.

Note that even when a D_REJECT is chosen as a final_destiny_by_ccat
for the CC_MTA case, it can still happen that amavisd responds with
a 2xx smtp status and sends its own bounce. This can happen with
multi-recipient mail, where some recipients are accepted and some
rejected by MTA. As SMTP protocol does not allow for per-recipient
responses, we have no other choice but to accept a message and
send a bounce to the rejected recipients, while delivering to the
accepted recipients. So, late header checks are alright, but late
per-recipient restrictions are to be avoided.

  Mark

------------------------------------------------------------------------------
Enter the BlackBerry Developer Challenge  
This is your chance to win up to $100,000 in prizes! For a limited time, 
vendors submitting new applications to BlackBerry App World(TM) will have
the opportunity to enter the BlackBerry Developer Challenge. See full prize  
details at: http://p.sf.net/sfu/Challenge
_______________________________________________
AMaViS-user mailing list
AMaViS-user@lists.sourceforge.net 
https://lists.sourceforge.net/lists/listinfo/amavis-user 
 AMaViS-FAQ:http://www.amavis.org/amavis-faq.php3 
 AMaViS-HowTos:http://www.amavis.org/howto/ 

Reply via email to