--- amavisd~ Sat Nov 16 05:33:44 2002 +++ amavisd Sun Nov 17 22:33:19 2002 @@ -963,35 +963,36 @@ my($msginfo) = @_; my($smtp_resp,$exit_code,$dsn_needed); + my($sender) = $msginfo->sender; my($per_recip_data) = $msginfo->per_recip_data; my($any_not_done) = scalar(grep {!$_->recip_done} @$per_recip_data); if ($forward_method ne '' && $any_not_done) { die "Explicit forwarding, but not all recips done" } if (!@$per_recip_data) { # no recipients, nothing to do $smtp_resp = "250 2.5.0 Ok"; $exit_code = EX_OK; - do_log(5, "one_response_for_all: no recipients, '$smtp_resp'"); + do_log(5, "one_response_for_all <$sender>: no recipients, '$smtp_resp'"); } if (!defined $smtp_resp) { - for my $r (@$per_recip_data) { # any 4xx code ? + for my $r (@$per_recip_data) { # any 4xx code ? if ($r->recip_smtp_response =~ /^4/) # pick the first 4xx code { $smtp_resp = $r->recip_smtp_response; last } } if (!defined $smtp_resp) { - for my $r (@$per_recip_data) { # any invalid code ? - if ($r->recip_smtp_response !~ /^[245]/) { # pick the first - $smtp_resp = "451 4.5.0 Bad SMTP response code??? <" . - $r->recip_smtp_response . ">"; - last; + for my $r (@$per_recip_data) { # any invalid code ? + if ($r->recip_done && $r->recip_smtp_response !~ /^[245]/) { + $smtp_resp = '451 4.5.0 Bad SMTP response code??? "' . + $r->recip_smtp_response . '"'; + last; # pick the first } } } if (defined $smtp_resp) { $exit_code = EX_TEMPFAIL; - do_log(5, "one_response_for_all: 4xx found, '$smtp_resp'"); + do_log(5, "one_response_for_all <$sender>: 4xx found, '$smtp_resp'"); } } # NOTE: a 2xx SMTP response code is set both by internal DISCARD, - # and a genuine successful delivery. To distinguish between the two + # and by a genuine successful delivery. To distinguish between the two # we need to check $r->recip_destiny as well. # if (!defined $smtp_resp) { @@ -1004,8 +1005,8 @@ } if ($notall) { $smtp_resp = undef } if (defined $smtp_resp) { - $exit_code = $forward_method ne '' ? 99 : EX_OK; - do_log(5, "one_response_for_all: all DISCARD, '$smtp_resp'"); + $exit_code = $forward_method eq '' ? 99 : EX_OK; + do_log(5, "one_response_for_all <$sender>: all DISCARD, '$smtp_resp'"); } } if (!defined $smtp_resp) { @@ -1027,7 +1028,7 @@ if ($notall) { $smtp_resp = undef } if (defined $smtp_resp) { $exit_code = EX_UNAVAILABLE; - do_log(5, "one_response_for_all: some REJECTs, '$smtp_resp'"); + do_log(5, "one_response_for_all <$sender>: some REJECTs, '$smtp_resp'"); } } if (!defined $smtp_resp) { @@ -1054,7 +1055,7 @@ $smtp_resp .= " $drop_cnt DROP" . ($drop_cnt==1?'':'S') if $drop_cnt; $exit_code = EX_OK; $dsn_needed = $rej_cnt ? 1 : 0; - do_log(5, "one_response_for_all: " . + do_log(5, "one_response_for_all <$sender>: " . ($rej_cnt+$drop_cnt > 0 ? 'mixed' : 'success') . ", '$smtp_resp'"); } @@ -2793,6 +2794,7 @@ last; } } + $best_try_originator; } # Given a dotted-quad IP address try reverse DNS resolve, and then @@ -3832,7 +3834,7 @@ BEGIN { import Amavis::Util qw(do_log sanitize_str); import Amavis::Timing qw(section_time); - import Amavis::Conf qw(:notifyconf $myhostname); + import Amavis::Conf qw(:notifyconf $myhostname $forward_method); import Amavis::Lookup qw(lookup); import Amavis::Expand qw(expand); import Amavis::rfc2821_2822_Tools; @@ -3878,9 +3880,10 @@ $builtins_ref, $template_ref) = @_; my($dsn_time) = time; # time of dsn creation - now my($notification); - if ($msginfo->sender_contact eq '') { - # must not respond to null return path + if ($msginfo->sender eq '') { # must not respond to null return path do_log(4, "Not sending DSN to empty return path"); + } elsif ($msginfo->sender_contact eq '') { + do_log(4, "Not sending DSN to believed-to-be-faked return path"); } elsif ($msginfo->mime_entity->head->get("precedence") =~ /bulk|list|junk/i ) { # don't send notifications in response to mail from mailing lists @@ -3898,8 +3901,13 @@ my($remote_mta) = $r->recip_remote_mta; my($smtp_resp) = $r->recip_smtp_response; if (! $r->recip_done) { - do_log(0, "TROUBLE: recipient not done: <" . - $r->recip_addr . "> " . $smtp_resp); + if ($forward_method eq '') { # e.g. milter + # as far as we are concerned all is ok, delivery by MTA-in + $smtp_resp = "250 2.5.0 Ok, continue delivery"; + } else { + do_log(0, "TROUBLE: recipient not done: <" . + $r->recip_addr . "> " . $smtp_resp); + } } my($smtp_resp_code, $smtp_resp_enhcode, $smtp_resp_msg); if ($smtp_resp =~ /^ (\d{3}) \s+ ([245] \. \d{1,3} \. \d{1,3})? @@ -4795,6 +4803,7 @@ # abort if quarantining not successful die "Can not quarantine: '$n_smtp_resp'"; } + do_log(5, "DO_QUARANTINE done"); } # If virus found - quarantine it and send notifications @@ -4826,6 +4835,7 @@ } do_quarantine($conn, $msginfo, $hdr_edits, \@q_addr) if @q_addr; + do_log(5, "DO_VIRUS - NOTIFICATIONS, sender: ".$msginfo->sender); $hdr_edits = Amavis::Out::EditHeader->new; # try to find a per-sender administrator @@ -4879,6 +4889,7 @@ # $notification->purge; } } + do_log(5, "DO_VIRUS - DONE"); } # @@ -4924,6 +4935,7 @@ join(',', map{"<$_>"} @{$msginfo->recips}), $s, $VIRUSFILE, join(',',@q_addr) )); } + my($hdr_edits) = Amavis::Out::EditHeader->new; # try to find a per-sender administrator @@ -4932,6 +4944,7 @@ do_log(4, "Skip spam_admin notification for <".$msginfo->sender. ">, no admin specified"); } else { # Notify admin + do_log(5, "DO_SPAM - NOTIFICATIONS, sender: ".$msginfo->sender); my($notification) = Amavis::In::Message->new; $notification->sender($mailfrom_notify_spamadmin); $notification->recips([$admin]); @@ -4950,6 +4963,7 @@ { do_log(0, "FAILED to notify spam admin: $n_smtp_resp") } # $notification->purge; } + do_log(5, "DO_SPAM DONE"); } # Calculate message digest; @@ -5430,17 +5444,24 @@ do_log(4, "tempdir being removed: $tempdir"); rmdir_recursively($tempdir); } - if ($forward_method eq '' && $exit_code != EX_TEMPFAIL) { # e.g. milter -# TODO: this must be based on exit_code: all or none must be done -# for my $r (@{$msginfo->per_recip_data}) { -# # a limited helper program can not do it, but should have been done -# my($addr,$newaddr) = ($r->recip_addr, $r->recip_addr_modified); -# if ($r->recip_done) { -# do_log(0, "TODO: recip addr <$addr> should be removed"); -# } elsif ($newaddr ne $addr) { -# do_log(0, "TODO: recip addr <$addr> should be replaced with <$newaddr>"); -# } -# } + if ($forward_method eq '' && $exit_code == EX_OK) { # e.g. milter + # when forwarding is left for MTA on the input side to do, + # warn if there is anything that should be done, but MTA is not + # capable of doing (or a helper program can not pass the request) + my($any_deletes); + for my $r (@{$msginfo->per_recip_data}) { + my($addr,$newaddr) = ($r->recip_addr, $r->recip_final_addr); + if ($r->recip_done) { + do_log(0, "WARN: recip addr <$addr> should be removed, but MTA can't do it"); + $any_deletes++; + } elsif ($newaddr ne $addr) { + do_log(0, "WARN: recip addr <$addr> should be replaced with <$newaddr>, but MTA can't do it"); + } + } + if ($any_deletes) { + do_log(0, "WARN: REJECT THE WHOLE MESSAGE, MTA-in can't do the recips deletion"); + $exit_code = EX_UNAVAILABLE; + } } } if ($mta_in_type eq 'qmail' && $exit_code == EX_TEMPFAIL) {