2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 13:18:12 +00:00

postfix-3.2-20161101

This commit is contained in:
Wietse Venema 2016-11-01 00:00:00 -05:00 committed by Viktor Dukhovni
parent fac73c7bea
commit 28b5cc972d
17 changed files with 680 additions and 440 deletions

View File

@ -22537,3 +22537,11 @@ Apologies for any names omitted.
and "PASS" disables header, body, and Milter inspection for and "PASS" disables header, body, and Milter inspection for
the remainder of the message content. Contributed by Hobbit. the remainder of the message content. Contributed by Hobbit.
Files: cleanup/cleanup_message.c, global/header_body_checks.c. Files: cleanup/cleanup_message.c, global/header_body_checks.c.
20161024
Feature: smtpd_milter_maps, per-client Milter configuration
that overrides smtpd_milters, and that has the same syntax.
Files: mantools/postlink, proto/MILTER_README.html,
proto/postconf.proto, global/mail_params.h, smtpd/smtpd.c,
smtpd/smtpd.h, smtpd/smtpd_sasl_proto.c, smtpd/smtpd_state.c.

View File

@ -1,8 +1,8 @@
PPoossttffiixx bbeeffoorree--qquueeuuee MMiilltteerr ssuuppppoorrtt Postfix before-queue Milter support
------------------------------------------------------------------------------- -------------------------------------------------------------------------------
IInnttrroodduuccttiioonn Introduction
Postfix implements support for the Sendmail version 8 Milter (mail filter) Postfix implements support for the Sendmail version 8 Milter (mail filter)
protocol. This protocol is used by applications that run outside the MTA to protocol. This protocol is used by applications that run outside the MTA to
@ -30,7 +30,7 @@ This document provides information on the following topics:
* Workarounds * Workarounds
* Limitations * Limitations
HHooww MMiilltteerr aapppplliiccaattiioonnss pplluugg iinnttoo PPoossttffiixx How Milter applications plug into Postfix
The Postfix Milter implementation uses two different lists of mail filters: one The Postfix Milter implementation uses two different lists of mail filters: one
list of filters for SMTP mail only, and one list of filters for non-SMTP mail. list of filters for SMTP mail only, and one list of filters for non-SMTP mail.
@ -80,7 +80,7 @@ Postfix architecture).
Local -> sendmail(1) Local -> sendmail(1)
BBuuiillddiinngg MMiilltteerr aapppplliiccaattiioonnss Building Milter applications
Milter applications have been written in C, JAVA and Perl, but this document Milter applications have been written in C, JAVA and Perl, but this document
deals with C applications only. For these, you need an object library that deals with C applications only. For these, you need an object library that
@ -94,25 +94,25 @@ some Linux systems).
Once libmilter is installed, applications such as OpenDKIM and OpenDMARC build Once libmilter is installed, applications such as OpenDKIM and OpenDMARC build
out of the box without requiring any tinkering: out of the box without requiring any tinkering:
$ ggzzccaatt ooppeennddkkiimm--xx..yy..zz..ttaarr..ggzz || ttaarr xxff -- $ gzcat opendkim-x.y.z.tar.gz | tar xf -
$ ccdd ooppeennddkkiimm--xx..yy..zz $ cd opendkim-x.y.z
$ ..//ccoonnffiigguurree ......ooppttiioonnss...... $ ./configure ...options...
$ mmaakkee $ make
[...lots of output omitted...] [...lots of output omitted...]
$ mmaakkee iinnssttaallll $ make install
RRuunnnniinngg MMiilltteerr aapppplliiccaattiioonnss Running Milter applications
To run a Milter application, see the documentation of the filter for options. A To run a Milter application, see the documentation of the filter for options. A
typical command looks like this: typical command looks like this:
# //ssoommee//wwhheerree//ooppeennddkkiimm --ll --uu uusseerriidd --pp iinneett::ppoorrttnnuummbbeerr@@llooccaallhhoosstt ......ootthheerr # /some/where/opendkim -l -u userid -p inet:portnumber@localhost ...other
ooppttiioonnss...... options...
Please specify a userid value that isn't used for other applications (not Please specify a userid value that isn't used for other applications (not
"postfix", not "www", etc.). "postfix", not "www", etc.).
CCoonnffiigguurriinngg PPoossttffiixx Configuring Postfix
Like Sendmail, Postfix has a lot of configuration options that control how it Like Sendmail, Postfix has a lot of configuration options that control how it
talks to Milter applications. Besides global options that apply to all Milter talks to Milter applications. Besides global options that apply to all Milter
@ -127,10 +127,11 @@ Information in this section:
* Milter protocol version * Milter protocol version
* Milter protocol timeouts * Milter protocol timeouts
* Different settings for different Milter applications * Different settings for different Milter applications
* Different settings for different SMTP clients
* Sendmail macro emulation * Sendmail macro emulation
* What macros will Postfix send to Milters? * What macros will Postfix send to Milters?
SSMMTTPP--OOnnllyy MMiilltteerr aapppplliiccaattiioonnss SMTP-Only Milter applications
The SMTP-only Milter applications handle mail that arrives via the Postfix The SMTP-only Milter applications handle mail that arrives via the Postfix
smtpd(8) server. They are typically used to filter unwanted mail, and to sign smtpd(8) server. They are typically used to filter unwanted mail, and to sign
@ -158,20 +159,23 @@ from other Milter applications.
The general syntax for listening sockets is as follows: The general syntax for listening sockets is as follows:
uunniixx::pathname unix:pathname
Connect to the local UNIX-domain server that is bound to the specified Connect to the local UNIX-domain server that is bound to the specified
pathname. If the smtpd(8) or cleanup(8) process runs chrooted, an pathname. If the smtpd(8) or cleanup(8) process runs chrooted, an
absolute pathname is interpreted relative to the Postfix queue absolute pathname is interpreted relative to the Postfix queue
directory. directory.
iinneett::host::port inet:host:port
Connect to the specified TCP port on the specified local or remote Connect to the specified TCP port on the specified local or remote
host. The host and port can be specified in numeric or symbolic form. host. The host and port can be specified in numeric or symbolic form.
NOTE: Postfix syntax differs from Milter syntax which has the form NOTE: Postfix syntax differs from Milter syntax which has the form
iinneett::port@@host. inet:port@host.
NNoonn--SSMMTTPP MMiilltteerr aapppplliiccaattiioonnss For advanced configuration see "Different settings for different SMTP clients"
and "Different settings for different Milter applications".
Non-SMTP Milter applications
The non-SMTP Milter applications handle mail that arrives via the Postfix The non-SMTP Milter applications handle mail that arrives via the Postfix
sendmail(1) command-line or via the Postfix qmqpd(8) server. They are typically sendmail(1) command-line or via the Postfix qmqpd(8) server. They are typically
@ -222,7 +226,7 @@ must not REJECT or TEMPFAIL simulated RCPT TO commands. When a
non_smtpd_milters application REJECTs or TEMPFAILs a recipient, Postfix will non_smtpd_milters application REJECTs or TEMPFAILs a recipient, Postfix will
report a configuration error, and mail will stay in the queue. report a configuration error, and mail will stay in the queue.
SSiiggnniinngg iinntteerrnnaallllyy--ggeenneerraatteedd bboouunnccee mmeessssaaggeess Signing internally-generated bounce messages
Postfix normally does not apply content filters to mail that is generated Postfix normally does not apply content filters to mail that is generated
internally such as bounces or Postmaster notifications. Filtering internally- internally such as bounces or Postmaster notifications. Filtering internally-
@ -239,7 +243,7 @@ non_smtpd_milters, header_checks or body_checks (lines 3-5 below).
4 header_checks = don't reject internally-generated bounces 4 header_checks = don't reject internally-generated bounces
5 body_checks = don't reject internally-generated bounces 5 body_checks = don't reject internally-generated bounces
MMiilltteerr eerrrroorr hhaannddlliinngg Milter error handling
The milter_default_action parameter specifies how Postfix handles Milter The milter_default_action parameter specifies how Postfix handles Milter
application errors. The default action is to respond with a temporary error application errors. The default action is to respond with a temporary error
@ -256,16 +260,16 @@ the message in the "hold" queue, and is available with Postfix 2.6 or later.
See "Different settings for different Milter applications" for advanced See "Different settings for different Milter applications" for advanced
configuration options. configuration options.
MMiilltteerr pprroottooccooll vveerrssiioonn Milter protocol version
As Postfix is not built with the Sendmail libmilter library, you may need to As Postfix is not built with the Sendmail libmilter library, you may need to
configure the Milter protocol version that Postfix should use. The default configure the Milter protocol version that Postfix should use. The default
version is 6 (before Postfix 2.6 the default version is 2). version is 6 (before Postfix 2.6 the default version is 2).
/etc/postfix/main.cf: /etc/postfix/main.cf:
# Postfix >= 2.6 # Postfix 2.6
milter_protocol = 6 milter_protocol = 6
# 2.3 <= Postfix <= 2.5 # 2.3 ≤ Postfix ≤ 2.5
milter_protocol = 2 milter_protocol = 2
If the Postfix milter_protocol setting specifies a too low version, the If the Postfix milter_protocol setting specifies a too low version, the
@ -294,21 +298,21 @@ libmilter library does not expect.
See "Different settings for different Milter applications" for advanced See "Different settings for different Milter applications" for advanced
configuration options. configuration options.
MMiilltteerr pprroottooccooll ttiimmeeoouuttss Milter protocol timeouts
Postfix uses different time limits at different Milter protocol stages. The Postfix uses different time limits at different Milter protocol stages. The
table shows the timeout settings and the corresponding protocol stages (EOH = table shows the timeout settings and the corresponding protocol stages (EOH =
end of headers; EOM = end of message). end of headers; EOM = end of message).
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _________________________________________________________________
|PPoossttffiixx ppaarraammeetteerr |TTiimmee lliimmiitt|MMiilltteerr pprroottooccooll ssttaaggee | |Postfix parameter |Time limit|Milter protocol stage |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |______________________|__________|_______________________________|
|milter_connect_timeout|30s |CONNECT | |milter_connect_timeout|30s |CONNECT |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |______________________|__________|_______________________________|
|milter_command_timeout|30s |HELO, MAIL, RCPT, DATA, UNKNOWN| |milter_command_timeout|30s |HELO, MAIL, RCPT, DATA, UNKNOWN|
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |______________________|__________|_______________________________|
|milter_content_timeout|300s |HEADER, EOH, BODY, EOM | |milter_content_timeout|300s |HEADER, EOH, BODY, EOM |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |______________________|__________|_______________________________|
Beware: 30s may be too short for Milter applications that do lots of DNS Beware: 30s may be too short for Milter applications that do lots of DNS
lookups. However, if you increase the above timeouts too much, remote SMTP lookups. However, if you increase the above timeouts too much, remote SMTP
@ -318,7 +322,7 @@ inherent problem with before-queue filtering.
See "Different settings for different Milter applications" for advanced See "Different settings for different Milter applications" for advanced
configuration options. configuration options.
DDiiffffeerreenntt sseettttiinnggss ffoorr ddiiffffeerreenntt MMiilltteerr aapppplliiccaattiioonnss Different settings for different Milter applications
The previous sections list a number of Postfix main.cf parameters that control The previous sections list a number of Postfix main.cf parameters that control
time limits and other settings for all Postfix Milter clients. This is time limits and other settings for all Postfix Milter clients. This is
@ -345,11 +349,31 @@ Instead of a server endpoint, we now have a list enclosed in {}.
content_timeout, default_action, and protocol. content_timeout, default_action, and protocol.
Inside the list, syntax is similar to what we already know from main.cf: items Inside the list, syntax is similar to what we already know from main.cf: items
separated by space or comma. There is one difference: yyoouu mmuusstt eenncclloossee aa separated by space or comma. There is one difference: you must enclose a
sseettttiinngg iinn ppaarreenntthheesseess,, aass iinn ""{{ nnaammee == vvaalluuee }}"",, iiff yyoouu wwaanntt ttoo hhaavvee ssppaaccee oorr setting in parentheses, as in "{ name = value }", if you want to have space or
ccoommmmaa wwiitthhiinn aa vvaalluuee oorr aarroouunndd ""=="". comma within a value or around "=".
SSeennddmmaaiill mmaaccrroo eemmuullaattiioonn Different settings for different SMTP clients
The smtpd_milter_maps feature supports different Milter settings for different
client IP addresses. Lookup results override the the global smtpd_milters
setting, and have the same syntax. For example, to disable Milter settings for
local address ranges:
/etc/postfix/main.cf:
smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map
smtpd_milters = inet:host:port, { inet:host:port, ... }, ...
/etc/postfix/smtpd_milter_map:
# Disable Milters for local clients.
127.0.0.0/8 DISABLE
192.168.0.0/16 DISABLE
::/64 DISABLE
2001:db8::/32 DISABLE
This feature is available with Postfix 3.2 and later.
Sendmail macro emulation
Postfix emulates a limited number of Sendmail macros, as shown in the table. Postfix emulates a limited number of Sendmail macros, as shown in the table.
Some macro values depend on whether a recipient is rejected (rejected Some macro values depend on whether a recipient is rejected (rejected
@ -358,92 +382,70 @@ macros are available at different Milter protocol stages (EOH = end-of-header,
EOM = end-of-message); their availability is not always the same as in EOM = end-of-message); their availability is not always the same as in
Sendmail. See the workarounds section below for solutions. Sendmail. See the workarounds section below for solutions.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _________________________________________________________________________________________________________________________________________
|SSeennddmmaaiill mmaaccrroo |MMiilltteerr pprroottooccooll ssttaaggee |DDeessccrriippttiioonn | |Sendmail macro |Milter protocol stage |Description |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|i |DATA, EOH, EOM |Queue ID, also Postfix | |i |DATA, EOH, EOM |Queue ID, also Postfix queue file name |
| | |queue file name | |____________________|_______________________________________________|____________________________________________________________________|
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|j |Always |Value of myhostname | |j |Always |Value of myhostname |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|_ |Always |The validated client name | |_ |Always |The validated client name and address |
| | |and address | |____________________|_______________________________________________|____________________________________________________________________|
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{auth_authen} |MAIL, DATA, EOH, EOM |SASL login name | |{auth_authen} |MAIL, DATA, EOH, EOM |SASL login name |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|{auth_author} |MAIL, DATA, EOH, EOM |SASL sender | |{auth_author} |MAIL, DATA, EOH, EOM |SASL sender |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|{auth_type} |MAIL, DATA, EOH, EOM |SASL login method | |{auth_type} |MAIL, DATA, EOH, EOM |SASL login method |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|{client_addr} |Always |Remote client IP address | |{client_addr} |Always |Remote client IP address |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
| | |Connection concurrency for| |{client_connections}|CONNECT |Connection concurrency for this client (zero if the client is |
| | |this client (zero if the | | | |excluded from all smtpd_client_* limits). |
|{client_connections}|CONNECT |client is excluded from | |____________________|_______________________________________________|____________________________________________________________________|
| | |all smtpd_client_* |
| | |limits). |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
| | |Remote client hostname | | | |Remote client hostname |
| | |When address -> name | |{client_name} |Always |When address → name lookup or name → address verification fails:|
|{client_name} |Always |lookup or name -> address |
| | |verification fails: |
| | |"unknown" | | | |"unknown" |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|{client_port} |Always (Postfix >=2.5) |Remote client TCP port | |{client_port} |Always (Postfix ≥2.5) |Remote client TCP port |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
| | |Client name from address -| |{client_ptr} |CONNECT, HELO, MAIL, DATA |Client name from address → name lookup |
|{client_ptr} |CONNECT, HELO, MAIL, DATA|> name lookup | | | |When address → name lookup fails: "unknown" |
| | |When address -> name | |____________________|_______________________________________________|____________________________________________________________________|
| | |lookup fails: "unknown" | |{cert_issuer} |HELO, MAIL, DATA, EOH, EOM |TLS client certificate issuer |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|{cert_issuer} |HELO, MAIL, DATA, EOH, |TLS client certificate | |{cert_subject} |HELO, MAIL, DATA, EOH, EOM |TLS client certificate subject |
| |EOM |issuer | |____________________|_______________________________________________|____________________________________________________________________|
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |{cipher_bits} |HELO, MAIL, DATA, EOH, EOM |TLS session key size |
|{cert_subject} |HELO, MAIL, DATA, EOH, |TLS client certificate | |____________________|_______________________________________________|____________________________________________________________________|
| |EOM |subject | |{cipher} |HELO, MAIL, DATA, EOH, EOM |TLS cipher |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|{cipher_bits} |HELO, MAIL, DATA, EOH, |TLS session key size | |{daemon_addr} |Always (Postfix ≥3.2) |Local server IP address |
| |EOM | | |____________________|_______________________________________________|____________________________________________________________________|
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |{daemon_name} |Always |value of milter_macro_daemon_name |
|{cipher} |HELO, MAIL, DATA, EOH, |TLS cipher | |____________________|_______________________________________________|____________________________________________________________________|
| |EOM | | |{daemon_port} |Always (Postfix ≥3.2) |Local server TCP port |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|{daemon_addr} |Always (Postfix >=3.2) |Local server IP address |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{daemon_name} |Always |value of |
| | |milter_macro_daemon_name |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{daemon_port} |Always (Postfix >=3.2) |Local server TCP port |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{mail_addr} |MAIL |Sender address | |{mail_addr} |MAIL |Sender address |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
|{mail_host} |MAIL (Postfix >= 2.6, |Sender next-hop | |{mail_host} |MAIL (Postfix ≥ 2.6, only with smtpd_milters)|Sender next-hop destination |
| |only with smtpd_milters) |destination | |____________________|_______________________________________________|____________________________________________________________________|
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |{mail_mailer} |MAIL (Postfix ≥ 2.6, only with smtpd_milters)|Sender mail delivery transport |
|{mail_mailer} |MAIL (Postfix >= 2.6, |Sender mail delivery | |____________________|_______________________________________________|____________________________________________________________________|
| |only with smtpd_milters) |transport | |{rcpt_addr} |RCPT |Recipient address |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | | | |With rejected recipient: descriptive text |
| | |Recipient address | |____________________|_______________________________________________|____________________________________________________________________|
|{rcpt_addr} |RCPT |With rejected recipient: | |{rcpt_host} |RCPT (Postfix ≥ 2.6, only with smtpd_milters)|Recipient next-hop destination |
| | |descriptive text | | | |With rejected recipient: enhanced status code |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
| | |Recipient next-hop | |{rcpt_mailer} |RCPT (Postfix ≥ 2.6, only with smtpd_milters)|Recipient mail delivery transport |
|{rcpt_host} |RCPT (Postfix >= 2.6, |destination | | | |With rejected recipient: "error" |
| |only with smtpd_milters) |With rejected recipient: | |____________________|_______________________________________________|____________________________________________________________________|
| | |enhanced status code | |{tls_version} |HELO, MAIL, DATA, EOH, EOM |TLS protocol version |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
| | |Recipient mail delivery |
|{rcpt_mailer} |RCPT (Postfix >= 2.6, |transport |
| |only with smtpd_milters) |With rejected recipient: |
| | |"error" |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{tls_version} |HELO, MAIL, DATA, EOH, |TLS protocol version |
| |EOM | |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|v |Always |value of milter_macro_v | |v |Always |value of milter_macro_v |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |____________________|_______________________________________________|____________________________________________________________________|
WWhhaatt mmaaccrrooss wwiillll PPoossttffiixx sseenndd ttoo MMiilltteerrss?? What macros will Postfix send to Milters?
Postfix sends specific sets of macros at different Milter protocol stages. The Postfix sends specific sets of macros at different Milter protocol stages. The
sets are configured with the parameters as shown in the table below (EOH = end sets are configured with the parameters as shown in the table below (EOH = end
@ -454,26 +456,26 @@ As of Sendmail 8.14.0, Milter applications can specify what macros they want to
receive at different Milter protocol stages. An application-specified list receive at different Milter protocol stages. An application-specified list
takes precedence over a Postfix-specified list. takes precedence over a Postfix-specified list.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ___________________________________________________________________
|PPoossttffiixx ppaarraammeetteerr |MMiilltteerr pprroottooccooll|MMiilltteerr pprroottooccooll ssttaaggee| |Postfix parameter |Milter protocol|Milter protocol stage|
| |vveerrssiioonn | | | |version | |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
|milter_connect_macros |2 or higher |CONNECT | |milter_connect_macros |2 or higher |CONNECT |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
|milter_helo_macros |2 or higher |HELO/EHLO | |milter_helo_macros |2 or higher |HELO/EHLO |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
|milter_mail_macros |2 or higher |MAIL FROM | |milter_mail_macros |2 or higher |MAIL FROM |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
|milter_rcpt_macros |2 or higher |RCPT TO | |milter_rcpt_macros |2 or higher |RCPT TO |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
|milter_data_macros |4 or higher |DATA | |milter_data_macros |4 or higher |DATA |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
|milter_end_of_header_macros |6 or higher |EOH | |milter_end_of_header_macros |6 or higher |EOH |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
|milter_end_of_data_macros |2 or higher |EOM | |milter_end_of_data_macros |2 or higher |EOM |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
|milter_unknown_command_macros|3 or higher |unknown command | |milter_unknown_command_macros|3 or higher |unknown command |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_____________________________|_______________|_____________________|
By default, Postfix will send only macros whose values have been updated with By default, Postfix will send only macros whose values have been updated with
information from main.cf or master.cf, from an SMTP session (for example; SASL information from main.cf or master.cf, from an SMTP session (for example; SASL
@ -485,7 +487,7 @@ specify macro default values with the milter_macro_defaults parameter. Specify
zero or more name=value pairs separated by comma or whitespace; you may even zero or more name=value pairs separated by comma or whitespace; you may even
specify macro names that Postfix does know about! specify macro names that Postfix does know about!
WWoorrkkaarroouunnddss Workarounds
* To avoid breaking DKIM etc. signatures with an SMTP-based content filter, * To avoid breaking DKIM etc. signatures with an SMTP-based content filter,
update the before-filter SMTP client in master.cf, and add a line with "- update the before-filter SMTP client in master.cf, and add a line with "-
@ -504,7 +506,7 @@ WWoorrkkaarroouunnddss
* Some Milter applications use the "{if_addr}" macro to recognize local mail; * Some Milter applications use the "{if_addr}" macro to recognize local mail;
this macro does not exist in Postfix. Workaround: use the "{daemon_addr}" this macro does not exist in Postfix. Workaround: use the "{daemon_addr}"
(Postfix >= 3.2) or "{client_addr}" macro instead. (Postfix 3.2) or "{client_addr}" macro instead.
* Some Milter applications log a warning that looks like this: * Some Milter applications log a warning that looks like this:
@ -533,19 +535,19 @@ WWoorrkkaarroouunnddss
o Edit the filter source file (typically named xxx-filter/xxx-filter.c or o Edit the filter source file (typically named xxx-filter/xxx-filter.c or
similar). similar).
o Look up the mlfi_eom() function and add code near the top shown as bboolldd o Look up the mlfi_eom() function and add code near the top shown as bold
text below: text below:
dfc = cc->cctx_msg; dfc = cc->cctx_msg;
assert(dfc != NULL); assert(dfc != NULL);
//** DDeetteerrmmiinnee tthhee jjoobb IIDD ffoorr llooggggiinngg.. **// /* Determine the job ID for logging. */
iiff ((ddffcc-->>mmccttxx__jjoobbiidd ==== 00 |||| ssttrrccmmpp((ddffcc-->>mmccttxx__jjoobbiidd,, JJOOBBIIDDUUNNKKNNOOWWNN)) ==== 00)) if (dfc->mctx_jobid == 0 || strcmp(dfc->mctx_jobid, JOBIDUNKNOWN) == 0)
{{ {
cchhaarr **jjoobbiidd == ssmmffii__ggeettssyymmvvaall((ccttxx,, ""ii""));; char *jobid = smfi_getsymval(ctx, "i");
iiff ((jjoobbiidd !!== 00)) if (jobid != 0)
ddffcc-->>mmccttxx__jjoobbiidd == jjoobbiidd;; dfc->mctx_jobid = jobid;
}} }
NOTES: NOTES:
@ -557,7 +559,7 @@ WWoorrkkaarroouunnddss
o This change fixes only the ugly message header, but not the WARNING o This change fixes only the ugly message header, but not the WARNING
message. Fortunately, many Milters log that message only once. message. Fortunately, many Milters log that message only once.
LLiimmiittaattiioonnss Limitations
This section lists limitations of the Postfix Milter implementation. Some This section lists limitations of the Postfix Milter implementation. Some
limitations will be removed as the implementation is extended over time. Of limitations will be removed as the implementation is extended over time. Of
@ -567,22 +569,22 @@ the CONTENT_INSPECTION_README document for a discussion.
* The Milter protocol has evolved over time. Therefore, different Postfix * The Milter protocol has evolved over time. Therefore, different Postfix
versions implement different feature sets. versions implement different feature sets.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ ________________________________________________________________________
|PPoossttffiixx|SSuuppppoorrtteedd MMiilltteerr rreeqquueessttss | |Postfix|Supported Milter requests |
|_ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_______|________________________________________________________________|
| 2.6 |All Milter requests of Sendmail 8.14.0 (see notes below). | | 2.6 |All Milter requests of Sendmail 8.14.0 (see notes below). |
|_ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_______|________________________________________________________________|
| |All Milter requests of Sendmail 8.14.0, except: | | |All Milter requests of Sendmail 8.14.0, except: |
| |SMFIP_RCPT_REJ (report rejected recipients to the mail filter), | | |SMFIP_RCPT_REJ (report rejected recipients to the mail filter), |
| 2.5 |SMFIR_CHGFROM (replace sender, with optional ESMTP parameters), | | 2.5 |SMFIR_CHGFROM (replace sender, with optional ESMTP parameters), |
| |SMFIR_ADDRCPT_PAR (add recipient, with optional ESMTP | | |SMFIR_ADDRCPT_PAR (add recipient, with optional ESMTP |
| |parameters). | | |parameters). |
|_ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_______|________________________________________________________________|
| 2.4 |All Milter requests of Sendmail 8.13.0. | | 2.4 |All Milter requests of Sendmail 8.13.0. |
|_ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_______|________________________________________________________________|
| 2.3 |All Milter requests of Sendmail 8.13.0, except: | | 2.3 |All Milter requests of Sendmail 8.13.0, except: |
| |SMFIR_REPLBODY (replace message body). | | |SMFIR_REPLBODY (replace message body). |
|_ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ | |_______|________________________________________________________________|
* For Milter applications that are written in C, you need to use the Sendmail * For Milter applications that are written in C, you need to use the Sendmail
libmilter library. libmilter library.

View File

@ -16,6 +16,13 @@ specifies the release date of a stable release or snapshot release.
If you upgrade from Postfix 3.0 or earlier, read RELEASE_NOTES-3.1 If you upgrade from Postfix 3.0 or earlier, read RELEASE_NOTES-3.1
before proceeding. before proceeding.
Major changes with snapshot 20161031
====================================
The smtpd_milter_maps feature supports per-client Milter configuration.
This overrides the global smtpd_milters setting and has the same syntax. A
lookup result of "DISABLE" turns off Milter support.
Incompatible changes with snapshot 20160925 Incompatible changes with snapshot 20160925
=========================================== ===========================================

View File

@ -259,6 +259,9 @@ support per-Milter timeouts, per-Milter error handling, etc. </p>
<li><a href="#per-milter">Different settings for different Milter <li><a href="#per-milter">Different settings for different Milter
applications </a> applications </a>
<li><a href="#per-client">Different settings for different SMTP
clients </a>
<li><a href="#macros">Sendmail macro emulation</a> <li><a href="#macros">Sendmail macro emulation</a>
<li><a href="#send-macros">What macros will Postfix send to Milters?</a> <li><a href="#send-macros">What macros will Postfix send to Milters?</a>
@ -320,6 +323,11 @@ form <b>inet:</b><i>port</i><b>@</b><i>host</i>. </p> </dd>
</blockquote> </blockquote>
<p> For advanced configuration see "<a href="#per-client">Different
settings for different SMTP clients</a>" and "<a
href="#per-milter">Different settings for different Milter
applications</a>". </p>
<h3> <a name="non-smtp-milters">Non-SMTP Milter applications </a> </h3> <h3> <a name="non-smtp-milters">Non-SMTP Milter applications </a> </h3>
<p> The non-SMTP Milter applications handle mail that arrives via <p> The non-SMTP Milter applications handle mail that arrives via
@ -564,6 +572,29 @@ and protocol. </p>
}", if you want to have space or comma within a value or around }", if you want to have space or comma within a value or around
"="</b>. </p> "="</b>. </p>
<h3><a name="per-client">Different settings for different SMTP
clients </a></h3>
<p> The <a href="postconf.5.html#smtpd_milter_maps">smtpd_milter_maps</a> feature supports different Milter settings
for different client IP addresses. Lookup results override the the
global <a href="postconf.5.html#smtpd_milters">smtpd_milters</a> setting, and have the same syntax. For example,
to disable Milter settings for local address ranges: </p>
<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
<a href="postconf.5.html#smtpd_milter_maps">smtpd_milter_maps</a> = <a href="cidr_table.5.html">cidr</a>:/etc/postfix/smtpd_milter_map
<a href="postconf.5.html#smtpd_milters">smtpd_milters</a> = inet:host:port, { inet:host:port, ... }, ...
/etc/postfix/smtpd_milter_map:
# Disable Milters for local clients.
127.0.0.0/8 DISABLE
192.168.0.0/16 DISABLE
::/64 DISABLE
2001:db8::/32 DISABLE
</pre>
<p> This feature is available with Postfix 3.2 and later. </p>
<h3><a name="macros">Sendmail macro emulation</a></h3> <h3><a name="macros">Sendmail macro emulation</a></h3>
<p> Postfix emulates a limited number of Sendmail macros, as shown <p> Postfix emulates a limited number of Sendmail macros, as shown

View File

@ -14637,6 +14637,39 @@ from the list. </p>
<p> This feature is available in Postfix 2.10 and later. </p> <p> This feature is available in Postfix 2.10 and later. </p>
</DD>
<DT><b><a name="smtpd_milter_maps">smtpd_milter_maps</a>
(default: empty)</b></DT><DD>
<p> Lookup tables with Milter settings per remote SMTP client IP
address. The lookup result overrides the <a href="postconf.5.html#smtpd_milters">smtpd_milters</a> setting,
and has the same syntax. </p>
<p> Note: lookup tables cannot return empty responses. Specify a
lookup result of DISABLE (case does not matter) to indicate that
Milter support should be disabled. </p>
<p> Example to disable Milters for local clients: </p>
<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
<a href="postconf.5.html#smtpd_milter_maps">smtpd_milter_maps</a> = <a href="cidr_table.5.html">cidr</a>:/etc/postfix/smtpd_milter_map
<a href="postconf.5.html#smtpd_milters">smtpd_milters</a> = inet:host:port, { inet:host:port, ... }, ...
</pre>
<pre>
/etc/postfix/smtpd_milter_map:
# Disable Milters for local clients.
127.0.0.0/8 DISABLE
192.168.0.0/16 DISABLE
::/64 DISABLE
2001:db8::/32 DISABLE
</pre>
<p> This feature is available in Postfix 3.2 and later. </p>
</DD> </DD>
<DT><b><a name="smtpd_milters">smtpd_milters</a> <DT><b><a name="smtpd_milters">smtpd_milters</a>

View File

@ -297,6 +297,12 @@ SMTPD(8) SMTPD(8)
for arbitrary macros that Postfix may send to Milter applica- for arbitrary macros that Postfix may send to Milter applica-
tions. tions.
Available in Postfix version 3.2 and later:
<b><a href="postconf.5.html#smtpd_milter_maps">smtpd_milter_maps</a> (empty)</b>
Lookup tables with Milter settings per remote SMTP client IP
address.
<b>GENERAL CONTENT INSPECTION CONTROLS</b> <b>GENERAL CONTENT INSPECTION CONTROLS</b>
The following parameters are applicable for both built-in and external The following parameters are applicable for both built-in and external
content filters. content filters.

View File

@ -9827,6 +9827,41 @@ Examples:
.ft R .ft R
.PP .PP
This feature is available in Postfix 2.10 and later. This feature is available in Postfix 2.10 and later.
.SH smtpd_milter_maps (default: empty)
Lookup tables with Milter settings per remote SMTP client IP
address. The lookup result overrides the smtpd_milters setting,
and has the same syntax.
.PP
Note: lookup tables cannot return empty responses. Specify a
lookup result of DISABLE (case does not matter) to indicate that
Milter support should be disabled.
.PP
Example to disable Milters for local clients:
.PP
.nf
.na
.ft C
/etc/postfix/main.cf:
smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map
smtpd_milters = inet:host:port, { inet:host:port, ... }, ...
.fi
.ad
.ft R
.PP
.nf
.na
.ft C
/etc/postfix/smtpd_milter_map:
# Disable Milters for local clients.
127.0.0.0/8 DISABLE
192.168.0.0/16 DISABLE
::/64 DISABLE
2001:db8::/32 DISABLE
.fi
.ad
.ft R
.PP
This feature is available in Postfix 3.2 and later.
.SH smtpd_milters (default: empty) .SH smtpd_milters (default: empty)
A list of Milter (mail filter) applications for new mail that A list of Milter (mail filter) applications for new mail that
arrives via the Postfix \fBsmtpd\fR(8) server. Specify space or comma as arrives via the Postfix \fBsmtpd\fR(8) server. Specify space or comma as

View File

@ -284,6 +284,11 @@ Available in Postfix version 3.1 and later:
Optional list of \fIname=value\fR pairs that specify default Optional list of \fIname=value\fR pairs that specify default
values for arbitrary macros that Postfix may send to Milter values for arbitrary macros that Postfix may send to Milter
applications. applications.
.PP
Available in Postfix version 3.2 and later:
.IP "\fBsmtpd_milter_maps (empty)\fR"
Lookup tables with Milter settings per remote SMTP client IP
address.
.SH "GENERAL CONTENT INSPECTION CONTROLS" .SH "GENERAL CONTENT INSPECTION CONTROLS"
.na .na
.nf .nf

View File

@ -550,6 +550,7 @@ while (<>) {
s;\bsmtpd_history_flush_threshold\b;<a href="postconf.5.html#smtpd_history_flush_threshold">$&</a>;g; s;\bsmtpd_history_flush_threshold\b;<a href="postconf.5.html#smtpd_history_flush_threshold">$&</a>;g;
s;\bsmtpd_junk_command_limit\b;<a href="postconf.5.html#smtpd_junk_command_limit">$&</a>;g; s;\bsmtpd_junk_command_limit\b;<a href="postconf.5.html#smtpd_junk_command_limit">$&</a>;g;
s;\bsmtpd_milters\b;<a href="postconf.5.html#smtpd_milters">$&</a>;g; s;\bsmtpd_milters\b;<a href="postconf.5.html#smtpd_milters">$&</a>;g;
s;\bsmtpd_milter_maps\b;<a href="postconf.5.html#smtpd_milter_maps">$&</a>;g;
s;\bsmtpd_noop_commands\b;<a href="postconf.5.html#smtpd_noop_commands">$&</a>;g; s;\bsmtpd_noop_commands\b;<a href="postconf.5.html#smtpd_noop_commands">$&</a>;g;
s;\bsmtpd_null_access_lookup_key\b;<a href="postconf.5.html#smtpd_null_access_lookup_key">$&</a>;g; s;\bsmtpd_null_access_lookup_key\b;<a href="postconf.5.html#smtpd_null_access_lookup_key">$&</a>;g;
s;\bsmtpd_recipient_overshoot_limit\b;<a href="postconf.5.html#smtpd_recipient_overshoot_limit">$&</a>;g; s;\bsmtpd_recipient_overshoot_limit\b;<a href="postconf.5.html#smtpd_recipient_overshoot_limit">$&</a>;g;

View File

@ -259,6 +259,9 @@ support per-Milter timeouts, per-Milter error handling, etc. </p>
<li><a href="#per-milter">Different settings for different Milter <li><a href="#per-milter">Different settings for different Milter
applications </a> applications </a>
<li><a href="#per-client">Different settings for different SMTP
clients </a>
<li><a href="#macros">Sendmail macro emulation</a> <li><a href="#macros">Sendmail macro emulation</a>
<li><a href="#send-macros">What macros will Postfix send to Milters?</a> <li><a href="#send-macros">What macros will Postfix send to Milters?</a>
@ -320,6 +323,11 @@ form <b>inet:</b><i>port</i><b>@</b><i>host</i>. </p> </dd>
</blockquote> </blockquote>
<p> For advanced configuration see "<a href="#per-client">Different
settings for different SMTP clients</a>" and "<a
href="#per-milter">Different settings for different Milter
applications</a>". </p>
<h3> <a name="non-smtp-milters">Non-SMTP Milter applications </a> </h3> <h3> <a name="non-smtp-milters">Non-SMTP Milter applications </a> </h3>
<p> The non-SMTP Milter applications handle mail that arrives via <p> The non-SMTP Milter applications handle mail that arrives via
@ -564,6 +572,29 @@ main.cf: items separated by space or comma. There is one difference:
}", if you want to have space or comma within a value or around }", if you want to have space or comma within a value or around
"="</b>. </p> "="</b>. </p>
<h3><a name="per-client">Different settings for different SMTP
clients </a></h3>
<p> The smtpd_milter_maps feature supports different Milter settings
for different client IP addresses. Lookup results override the the
global smtpd_milters setting, and have the same syntax. For example,
to disable Milter settings for local address ranges: </p>
<pre>
/etc/postfix/main.cf:
smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map
smtpd_milters = inet:host:port, { inet:host:port, ... }, ...
/etc/postfix/smtpd_milter_map:
# Disable Milters for local clients.
127.0.0.0/8 DISABLE
192.168.0.0/16 DISABLE
::/64 DISABLE
2001:db8::/32 DISABLE
</pre>
<p> This feature is available with Postfix 3.2 and later. </p>
<h3><a name="macros">Sendmail macro emulation</a></h3> <h3><a name="macros">Sendmail macro emulation</a></h3>
<p> Postfix emulates a limited number of Sendmail macros, as shown <p> Postfix emulates a limited number of Sendmail macros, as shown

View File

@ -16675,3 +16675,32 @@ the verify(8) daemon automatically refreshes an active address
before it expires. </p> before it expires. </p>
<p> This feature is available in Postfix 3.1 and later. </p> <p> This feature is available in Postfix 3.1 and later. </p>
%PARAM smtpd_milter_maps
<p> Lookup tables with Milter settings per remote SMTP client IP
address. The lookup result overrides the smtpd_milters setting,
and has the same syntax. </p>
<p> Note: lookup tables cannot return empty responses. Specify a
lookup result of DISABLE (case does not matter) to indicate that
Milter support should be disabled. </p>
<p> Example to disable Milters for local clients: </p>
<pre>
/etc/postfix/main.cf:
smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map
smtpd_milters = inet:host:port, { inet:host:port, ... }, ...
</pre>
<pre>
/etc/postfix/smtpd_milter_map:
# Disable Milters for local clients.
127.0.0.0/8 DISABLE
192.168.0.0/16 DISABLE
::/64 DISABLE
2001:db8::/32 DISABLE
</pre>
<p> This feature is available in Postfix 3.2 and later. </p>

View File

@ -3250,6 +3250,11 @@ extern bool var_tls_dane_taa_dgst;
#define DEF_SMTPD_MILTERS "" #define DEF_SMTPD_MILTERS ""
extern char *var_smtpd_milters; extern char *var_smtpd_milters;
#define VAR_SMTPD_MILTER_MAPS "smtpd_milter_maps"
#define DEF_SMTPD_MILTER_MAPS ""
extern char *var_smtpd_milter_maps;
#define SMTPD_MILTERS_DISABLE "DISABLE"
#define VAR_CLEANUP_MILTERS "non_smtpd_milters" #define VAR_CLEANUP_MILTERS "non_smtpd_milters"
#define DEF_CLEANUP_MILTERS "" #define DEF_CLEANUP_MILTERS ""
extern char *var_cleanup_milters; extern char *var_cleanup_milters;

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20161008" #define MAIL_RELEASE_DATE "20161101"
#define MAIL_VERSION_NUMBER "3.2" #define MAIL_VERSION_NUMBER "3.2"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@ -258,6 +258,11 @@
/* Optional list of \fIname=value\fR pairs that specify default /* Optional list of \fIname=value\fR pairs that specify default
/* values for arbitrary macros that Postfix may send to Milter /* values for arbitrary macros that Postfix may send to Milter
/* applications. /* applications.
/* .PP
/* Available in Postfix version 3.2 and later:
/* .IP "\fBsmtpd_milter_maps (empty)\fR"
/* Lookup tables with Milter settings per remote SMTP client IP
/* address.
/* GENERAL CONTENT INSPECTION CONTROLS /* GENERAL CONTENT INSPECTION CONTROLS
/* .ad /* .ad
/* .fi /* .fi
@ -1355,6 +1360,7 @@ bool var_smtpd_peername_lookup;
int var_plaintext_code; int var_plaintext_code;
bool var_smtpd_delay_open; bool var_smtpd_delay_open;
char *var_smtpd_milters; char *var_smtpd_milters;
char *var_smtpd_milter_maps;
int var_milt_conn_time; int var_milt_conn_time;
int var_milt_cmd_time; int var_milt_cmd_time;
int var_milt_msg_time; int var_milt_msg_time;
@ -1402,6 +1408,13 @@ int var_smtpd_uproxy_tmout;
*/ */
static MAPS *ehlo_discard_maps; static MAPS *ehlo_discard_maps;
/*
* Per-client Milter support.
*/
static MAPS *smtpd_milter_maps;
static void setup_milters(SMTPD_STATE *);
static void teardown_milters(SMTPD_STATE *);
/* /*
* VERP command name. * VERP command name.
*/ */
@ -1459,11 +1472,6 @@ static void tls_reset(SMTPD_STATE *);
#define REASON_LOST_CONNECTION "lost connection" #define REASON_LOST_CONNECTION "lost connection"
#define REASON_ERROR_LIMIT "too many errors" #define REASON_ERROR_LIMIT "too many errors"
/*
* Mail filter initialization status.
*/
MILTERS *smtpd_milters;
#ifdef USE_TLS #ifdef USE_TLS
/* /*
@ -1640,10 +1648,9 @@ static int helo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
#define PUSH_STRING(old, curr, new) { char *old = (curr); (curr) = (new); #define PUSH_STRING(old, curr, new) { char *old = (curr); (curr) = (new);
#define POP_STRING(old, curr) (curr) = old; } #define POP_STRING(old, curr) (curr) = old; }
if (smtpd_milters != 0 if (state->milters != 0
&& SMTPD_STAND_ALONE(state) == 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0 && (state->saved_flags & MILTER_SKIP_FLAGS) == 0
&& (err = milter_helo_event(smtpd_milters, argv[1].strval, 0)) != 0) { && (err = milter_helo_event(state->milters, argv[1].strval, 0)) != 0) {
/* Log reject etc. with correct HELO information. */ /* Log reject etc. with correct HELO information. */
PUSH_STRING(saved_helo, state->helo_name, argv[1].strval); PUSH_STRING(saved_helo, state->helo_name, argv[1].strval);
err = check_milter_reply(state, err); err = check_milter_reply(state, err);
@ -1726,10 +1733,9 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
* other commands such as AUTH, STARTTLS, and VRFY. * other commands such as AUTH, STARTTLS, and VRFY.
*/ */
err = 0; err = 0;
if (smtpd_milters != 0 if (state->milters != 0
&& SMTPD_STAND_ALONE(state) == 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0 && (state->saved_flags & MILTER_SKIP_FLAGS) == 0
&& (err = milter_helo_event(smtpd_milters, argv[1].strval, 1)) != 0) { && (err = milter_helo_event(state->milters, argv[1].strval, 1)) != 0) {
/* Log reject etc. with correct HELO information. */ /* Log reject etc. with correct HELO information. */
PUSH_STRING(saved_helo, state->helo_name, argv[1].strval); PUSH_STRING(saved_helo, state->helo_name, argv[1].strval);
err = check_milter_reply(state, err); err = check_milter_reply(state, err);
@ -1904,8 +1910,8 @@ static void helo_reset(SMTPD_STATE *state)
if (state->helo_name) { if (state->helo_name) {
myfree(state->helo_name); myfree(state->helo_name);
state->helo_name = 0; state->helo_name = 0;
if (SMTPD_STAND_ALONE(state) == 0 && smtpd_milters != 0) if (state->milters != 0)
milter_abort(smtpd_milters); milter_abort(state->milters);
} }
if (state->ehlo_argv) { if (state->ehlo_argv) {
argv_free(state->ehlo_argv); argv_free(state->ehlo_argv);
@ -2036,10 +2042,10 @@ static int mail_open_stream(SMTPD_STATE *state)
state->cleanup = state->dest->stream; state->cleanup = state->dest->stream;
state->queue_id = mystrdup(state->dest->id); state->queue_id = mystrdup(state->dest->id);
if (SMTPD_STAND_ALONE(state) == 0) { if (SMTPD_STAND_ALONE(state) == 0) {
if (smtpd_milters != 0 if (state->milters != 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0) && (state->saved_flags & MILTER_SKIP_FLAGS) == 0)
/* Send place-holder smtpd_milters list. */ /* Send place-holder smtpd_milters list. */
(void) milter_dummy(smtpd_milters, state->cleanup); (void) milter_dummy(state->milters, state->cleanup);
rec_fprintf(state->cleanup, REC_TYPE_TIME, REC_TYPE_TIME_FORMAT, rec_fprintf(state->cleanup, REC_TYPE_TIME, REC_TYPE_TIME_FORMAT,
REC_TYPE_TIME_ARG(state->arrival_time)); REC_TYPE_TIME_ARG(state->arrival_time));
if (*var_filter_xport) if (*var_filter_xport)
@ -2533,11 +2539,10 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "%s", err); smtpd_chat_reply(state, "%s", err);
return (-1); return (-1);
} }
if (smtpd_milters != 0 if (state->milters != 0
&& SMTPD_STAND_ALONE(state) == 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0) { && (state->saved_flags & MILTER_SKIP_FLAGS) == 0) {
PUSH_STRING(saved_sender, state->sender, STR(state->addr_buf)); PUSH_STRING(saved_sender, state->sender, STR(state->addr_buf));
err = milter_mail_event(smtpd_milters, err = milter_mail_event(state->milters,
milter_argv(state, argc - 2, argv + 2)); milter_argv(state, argc - 2, argv + 2));
if (err != 0) { if (err != 0) {
/* Log reject etc. with correct sender information. */ /* Log reject etc. with correct sender information. */
@ -2653,8 +2658,8 @@ static void mail_reset(SMTPD_STATE *state)
state->queue_id = 0; state->queue_id = 0;
} }
if (state->sender) { if (state->sender) {
if (SMTPD_STAND_ALONE(state) == 0 && smtpd_milters != 0) if (state->milters != 0)
milter_abort(smtpd_milters); milter_abort(state->milters);
myfree(state->sender); myfree(state->sender);
state->sender = 0; state->sender = 0;
} }
@ -2868,11 +2873,11 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
} else { } else {
err = smtpd_check_rcpt(state, STR(state->addr_buf)); err = smtpd_check_rcpt(state, STR(state->addr_buf));
} }
if (smtpd_milters != 0 if (state->milters != 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0) { && (state->saved_flags & MILTER_SKIP_FLAGS) == 0) {
PUSH_STRING(saved_rcpt, state->recipient, STR(state->addr_buf)); PUSH_STRING(saved_rcpt, state->recipient, STR(state->addr_buf));
state->milter_reject_text = err; state->milter_reject_text = err;
milter_err = milter_rcpt_event(smtpd_milters, milter_err = milter_rcpt_event(state->milters,
err == 0 ? MILTER_FLAG_NONE : err == 0 ? MILTER_FLAG_NONE :
MILTER_FLAG_WANT_RCPT_REJ, MILTER_FLAG_WANT_RCPT_REJ,
milter_argv(state, argc - 2, argv + 2)); milter_argv(state, argc - 2, argv + 2));
@ -3143,10 +3148,9 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
smtpd_chat_reply(state, "%s", err); smtpd_chat_reply(state, "%s", err);
return (-1); return (-1);
} }
if (smtpd_milters != 0 if (state->milters != 0
&& SMTPD_STAND_ALONE(state) == 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0 && (state->saved_flags & MILTER_SKIP_FLAGS) == 0
&& (err = milter_data_event(smtpd_milters)) != 0 && (err = milter_data_event(state->milters)) != 0
&& (err = check_milter_reply(state, err)) != 0) { && (err = check_milter_reply(state, err)) != 0) {
smtpd_chat_reply(state, "%s", err); smtpd_chat_reply(state, "%s", err);
return (-1); return (-1);
@ -3186,10 +3190,10 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
*/ */
if (state->cleanup) { if (state->cleanup) {
if (SMTPD_STAND_ALONE(state) == 0) { if (SMTPD_STAND_ALONE(state) == 0) {
if (smtpd_milters != 0 if (state->milters != 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0) && (state->saved_flags & MILTER_SKIP_FLAGS) == 0)
/* Send actual smtpd_milters list. */ /* Send actual smtpd_milters list. */
(void) milter_send(smtpd_milters, state->cleanup); (void) milter_send(state->milters, state->cleanup);
if (state->saved_flags) if (state->saved_flags)
rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d", rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d",
state->saved_flags); state->saved_flags);
@ -3437,7 +3441,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
* XXX See exception below in code that overrides state->access_denied for * XXX See exception below in code that overrides state->access_denied for
* compliance with RFC 2821 Sec 3.1. * compliance with RFC 2821 Sec 3.1.
*/ */
if (smtpd_milters != 0 && (state->err & CLEANUP_STAT_WRITE) != 0) if (state->milters != 0 && (state->err & CLEANUP_STAT_WRITE) != 0)
state->access_denied = mystrdup("421 4.3.0 Mail system error"); state->access_denied = mystrdup("421 4.3.0 Mail system error");
/* /*
@ -3658,7 +3662,7 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
state->addr); state->addr);
return (-1); return (-1);
} }
if (smtpd_milters != 0 && (err = milter_other_event(smtpd_milters)) != 0 if (state->milters != 0 && (err = milter_other_event(state->milters)) != 0
&& (err[0] == '5' || err[0] == '4')) { && (err[0] == '5' || err[0] == '4')) {
state->error_mask |= MAIL_ERROR_POLICY; state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "%s", err); smtpd_chat_reply(state, "%s", err);
@ -3713,7 +3717,7 @@ static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "503 Error: send HELO/EHLO first"); smtpd_chat_reply(state, "503 Error: send HELO/EHLO first");
return (-1); return (-1);
} }
if (smtpd_milters != 0 && (err = milter_other_event(smtpd_milters)) != 0 if (state->milters != 0 && (err = milter_other_event(state->milters)) != 0
&& (err[0] == '5' || err[0] == '4')) { && (err[0] == '5' || err[0] == '4')) {
state->error_mask |= MAIL_ERROR_POLICY; state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "%s", err); smtpd_chat_reply(state, "%s", err);
@ -4154,8 +4158,11 @@ static int xclient_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
chat_reset(state, 0); chat_reset(state, 0);
mail_reset(state); mail_reset(state);
rcpt_reset(state); rcpt_reset(state);
if (smtpd_milters) if (state->milters)
milter_disc_event(smtpd_milters); milter_disc_event(state->milters);
/* Following duplicates the top-level connect/disconnect handler. */
teardown_milters(state);
setup_milters(state);
vstream_longjmp(state->client, SMTP_ERR_NONE); vstream_longjmp(state->client, SMTP_ERR_NONE);
return (0); return (0);
} }
@ -4634,7 +4641,7 @@ static int starttls_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
smtpd_chat_reply(state, "501 5.5.4 Syntax: STARTTLS"); smtpd_chat_reply(state, "501 5.5.4 Syntax: STARTTLS");
return (-1); return (-1);
} }
if (smtpd_milters != 0 && (err = milter_other_event(smtpd_milters)) != 0) { if (state->milters != 0 && (err = milter_other_event(state->milters)) != 0) {
if (err[0] == '5') { if (err[0] == '5') {
state->error_mask |= MAIL_ERROR_POLICY; state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "%s", err); smtpd_chat_reply(state, "%s", err);
@ -5035,10 +5042,10 @@ static void smtpd_proto(SMTPD_STATE *state)
*/ */
else { else {
err = 0; err = 0;
if (smtpd_milters != 0 && SMTPD_STAND_ALONE(state) == 0) { if (state->milters != 0) {
milter_macro_callback(smtpd_milters, smtpd_milter_eval, milter_macro_callback(state->milters, smtpd_milter_eval,
(void *) state); (void *) state);
if ((err = milter_conn_event(smtpd_milters, state->name, if ((err = milter_conn_event(state->milters, state->name,
state->addr, state->addr,
strcmp(state->port, CLIENT_PORT_UNKNOWN) ? strcmp(state->port, CLIENT_PORT_UNKNOWN) ?
state->port : "0", state->port : "0",
@ -5163,9 +5170,8 @@ static void smtpd_proto(SMTPD_STATE *state)
} }
/* state->access_denied == 0 || cmdp->action == quit_cmd */ /* state->access_denied == 0 || cmdp->action == quit_cmd */
if (cmdp->name == 0) { if (cmdp->name == 0) {
if (smtpd_milters != 0 if (state->milters != 0
&& SMTPD_STAND_ALONE(state) == 0 && (err = milter_unknown_event(state->milters,
&& (err = milter_unknown_event(smtpd_milters,
argv[0].strval)) != 0 argv[0].strval)) != 0
&& (err = check_milter_reply(state, err)) != 0) { && (err = check_milter_reply(state, err)) != 0) {
smtpd_chat_reply(state, "%s", err); smtpd_chat_reply(state, "%s", err);
@ -5270,8 +5276,8 @@ static void smtpd_proto(SMTPD_STATE *state)
chat_reset(state, 0); chat_reset(state, 0);
mail_reset(state); mail_reset(state);
rcpt_reset(state); rcpt_reset(state);
if (smtpd_milters) if (state->milters)
milter_disc_event(smtpd_milters); milter_disc_event(state->milters);
} }
/* smtpd_format_cmd_stats - format per-command statistics */ /* smtpd_format_cmd_stats - format per-command statistics */
@ -5313,6 +5319,59 @@ static char *smtpd_format_cmd_stats(VSTRING *buf)
return (lowercase(STR(buf))); return (lowercase(STR(buf)));
} }
/* setup_milters - set up Milters after a connection is established */
static void setup_milters(SMTPD_STATE *state)
{
const char *milter_string;
/*
* Postcondition: either state->milters is set, or the
* INPUT_TRANSP_MILTER flag is passed down-stream.
*/
if (SMTPD_STAND_ALONE(state) == 0
&& (smtpd_input_transp_mask & INPUT_TRANSP_MILTER) == 0
&& ((smtpd_milter_maps
&& (milter_string =
maps_find(smtpd_milter_maps, state->addr, 0)) != 0)
|| *(milter_string = var_smtpd_milters) != 0)
&& strcasecmp(milter_string, SMTPD_MILTERS_DISABLE) != 0) {
state->milters = milter_create(milter_string,
var_milt_conn_time,
var_milt_cmd_time,
var_milt_msg_time,
var_milt_protocol,
var_milt_def_action,
var_milt_conn_macros,
var_milt_helo_macros,
var_milt_mail_macros,
var_milt_rcpt_macros,
var_milt_data_macros,
var_milt_eoh_macros,
var_milt_eod_macros,
var_milt_unk_macros,
var_milt_macro_deflts);
}
/*
* Safety: disable non_smtpd_milters when not sending our own mail filter
* list. Otherwise the next stage could handle this message as a local
* submission.
*/
if (state->milters == 0)
smtpd_input_transp_mask |= INPUT_TRANSP_MILTER;
}
/* teardown_milters - release resources */
static void teardown_milters(SMTPD_STATE *state)
{
if (state->milters) {
milter_free(state->milters);
state->milters = 0;
}
}
/* smtpd_service - service one client */ /* smtpd_service - service one client */
@ -5374,6 +5433,11 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv)
*/ */
debug_peer_check(state.name, state.addr); debug_peer_check(state.name, state.addr);
/*
* Set up Milters, or disable Milters down-stream.
*/
setup_milters(&state); /* duplicates xclient_cmd */
/* /*
* Provide the SMTP service. * Provide the SMTP service.
*/ */
@ -5386,6 +5450,7 @@ static void smtpd_service(VSTREAM *stream, char *service, char **argv)
*/ */
msg_info("disconnect from %s%s", state.namaddr, msg_info("disconnect from %s%s", state.namaddr,
smtpd_format_cmd_stats(state.buffer)); smtpd_format_cmd_stats(state.buffer));
teardown_milters(&state); /* duplicates xclient_cmd */
smtpd_state_reset(&state); smtpd_state_reset(&state);
debug_peer_restore(); debug_peer_restore();
} }
@ -5598,6 +5663,14 @@ static void pre_jail_init(char *unused_name, char **unused_argv)
var_smtpd_ehlo_dis_maps, var_smtpd_ehlo_dis_maps,
DICT_FLAG_LOCK); DICT_FLAG_LOCK);
/*
* Per-client Milter support.
*/
if (*var_smtpd_milter_maps)
smtpd_milter_maps = maps_create(VAR_SMTPD_MILTER_MAPS,
var_smtpd_milter_maps,
DICT_FLAG_LOCK);
/* /*
* DNS reply filter. * DNS reply filter.
*/ */
@ -5627,35 +5700,6 @@ static void post_jail_init(char *unused_name, char **unused_argv)
smtpd_proxy_opts = smtpd_proxy_opts =
smtpd_proxy_parse_opts(VAR_SMTPD_PROXY_OPTS, var_smtpd_proxy_opts); smtpd_proxy_parse_opts(VAR_SMTPD_PROXY_OPTS, var_smtpd_proxy_opts);
/*
* Sendmail mail filters.
*
* XXX Should not do this when running in stand-alone mode. But that test
* looks at VSTREAM_IN which is not available at this point.
*
* XXX Disable non_smtpd_milters when not sending our own mail filter list.
*/
if ((smtpd_input_transp_mask & INPUT_TRANSP_MILTER) == 0) {
if (*var_smtpd_milters)
smtpd_milters = milter_create(var_smtpd_milters,
var_milt_conn_time,
var_milt_cmd_time,
var_milt_msg_time,
var_milt_protocol,
var_milt_def_action,
var_milt_conn_macros,
var_milt_helo_macros,
var_milt_mail_macros,
var_milt_rcpt_macros,
var_milt_data_macros,
var_milt_eoh_macros,
var_milt_eod_macros,
var_milt_unk_macros,
var_milt_macro_deflts);
else
smtpd_input_transp_mask |= INPUT_TRANSP_MILTER;
}
/* /*
* Sanity checks. The queue_minfree value should be at least as large as * Sanity checks. The queue_minfree value should be at least as large as
* (process_limit * message_size_limit) but that is unpractical, so we * (process_limit * message_size_limit) but that is unpractical, so we
@ -5865,6 +5909,7 @@ int main(int argc, char **argv)
VAR_MILT_DAEMON_NAME, DEF_MILT_DAEMON_NAME, &var_milt_daemon_name, 1, 0, VAR_MILT_DAEMON_NAME, DEF_MILT_DAEMON_NAME, &var_milt_daemon_name, 1, 0,
VAR_MILT_V, DEF_MILT_V, &var_milt_v, 1, 0, VAR_MILT_V, DEF_MILT_V, &var_milt_v, 1, 0,
VAR_MILT_MACRO_DEFLTS, DEF_MILT_MACRO_DEFLTS, &var_milt_macro_deflts, 0, 0, VAR_MILT_MACRO_DEFLTS, DEF_MILT_MACRO_DEFLTS, &var_milt_macro_deflts, 0, 0,
VAR_SMTPD_MILTER_MAPS, DEF_SMTPD_MILTER_MAPS, &var_smtpd_milter_maps, 0, 0,
VAR_STRESS, DEF_STRESS, &var_stress, 0, 0, VAR_STRESS, DEF_STRESS, &var_stress, 0, 0,
VAR_UNV_FROM_WHY, DEF_UNV_FROM_WHY, &var_unv_from_why, 0, 0, VAR_UNV_FROM_WHY, DEF_UNV_FROM_WHY, &var_unv_from_why, 0, 0,
VAR_UNV_RCPT_WHY, DEF_UNV_RCPT_WHY, &var_unv_rcpt_why, 0, 0, VAR_UNV_RCPT_WHY, DEF_UNV_RCPT_WHY, &var_unv_rcpt_why, 0, 0,

View File

@ -182,6 +182,7 @@ typedef struct {
const char **milter_argv; /* SMTP command vector */ const char **milter_argv; /* SMTP command vector */
ssize_t milter_argc; /* SMTP command vector */ ssize_t milter_argc; /* SMTP command vector */
const char *milter_reject_text; /* input to call-back from Milter */ const char *milter_reject_text; /* input to call-back from Milter */
MILTERS *milters; /* Milter initialization status.*/
/* /*
* EHLO temporary space. * EHLO temporary space.

View File

@ -163,7 +163,7 @@ int smtpd_sasl_auth_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "503 5.5.1 Error: MAIL transaction in progress"); smtpd_chat_reply(state, "503 5.5.1 Error: MAIL transaction in progress");
return (-1); return (-1);
} }
if (smtpd_milters != 0 && (err = milter_other_event(smtpd_milters)) != 0) { if (state->milters != 0 && (err = milter_other_event(state->milters)) != 0) {
if (err[0] == '5') { if (err[0] == '5') {
state->error_mask |= MAIL_ERROR_POLICY; state->error_mask |= MAIL_ERROR_POLICY;
smtpd_chat_reply(state, "%s", err); smtpd_chat_reply(state, "%s", err);

View File

@ -159,6 +159,7 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream,
state->milter_argv = 0; state->milter_argv = 0;
state->milter_argc = 0; state->milter_argc = 0;
state->milters = 0;
/* /*
* Initialize peer information. * Initialize peer information.