Cleanup: made parsing of '!' operators in regexp and pcre
tables consistent with cidr tables. Files: util/dict_regexp.c,
util/dict_pcre.c.
+
+20160605
+
+ Cleanup: integer wrap-around detection in the MySQL and
+ PostgreSQL clients. This is totally non-critical because
+ Postfix strings are size-limited by design. Files:
+ global/dict_mysqql.c, global/dict_pgsql.c.
+
+20160607
+
+ Documentation: dnsblog.
+
+20160609
+
+ Documentation: postsuper(1) manpage text for multiple -[dhH]
+ options. File: postsuper/postsuper.c.
+
+20160611
+
+ Cleanup: Postfix SMTP server local IP address and port
+ attributes in the policy delegation protocol (attribute
+ names: server_address, server_port), in the Milter protocol
+ (macro names: {daemon_addr}, {daemon_port}) and in the
+ XCLIENT protocol (attribute names: DESTADDR, DESTPORT).
+ Files: proto/MILTER_README.html, proto/SMTPD_POLICY_README.html,
+ cleanup/cleanup.h, cleanup/cleanup_milter.c, global/mail_proto.h,
+ milter/milter.h, smtpd/smtpd.c, smtpd/smtpd.h, smtpd/smtpd_check.c,
+ smtpd/smtpd_haproxy.c, smtpd/smtpd_milter.c, smtpd/smtpd_peer.c.
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
|{auth_type} |MAIL, DATA, EOH, EOM |SASL login method |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |{client_addr} |Always |Client IP address |
+ |{client_addr} |Always |Remote client IP address |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
| | |Connection concurrency for|
| | |this client (zero if the |
| | |all smtpd_client_* |
| | |limits). |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- | | |Client hostname |
+ | | |Remote client hostname |
| | |When address -> name |
|{client_name} |Always |lookup or name -> address |
| | |verification fails: |
| | |"unknown" |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |{client_port} |Always (Postfix >=2.5) |Client TCP port |
+ |{client_port} |Always (Postfix >=2.5) |Remote client TCP port |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
| | |Client name from address -|
|{client_ptr} |CONNECT, HELO, MAIL, DATA|> name lookup |
|{cipher} |HELO, MAIL, DATA, EOH, |TLS cipher |
| |EOM | |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |{daemon_addr} |Always (Postfix >=3.2) |Local server IP address |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
|{daemon_name} |Always |value of |
| | |milter_macro_daemon_name |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
+ |{daemon_port} |Always (Postfix >=3.2) |Local server TCP port |
+ |_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
|{mail_addr} |MAIL |Sender address |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
|{mail_host} |MAIL (Postfix >= 2.6, |Sender next-hop |
-o smtp_generic_maps=
* Some Milter applications use the "{if_addr}" macro to recognize local mail;
- this macro does not exist in Postfix. Workaround: use the "{client_addr}"
- macro instead.
+ this macro does not exist in Postfix. Workaround: use the "{daemon_addr}"
+ (Postfix >= 3.2) or "{client_addr}" macro instead.
* Some Milter applications log a warning that looks like this:
that keeps the zombies away, Postfix would be spending most of its resources
not receiving email.
-The main challenge for postscreen(8) is to make an is-it-a-zombie decision
-based on a single measurement. This is necessary because many zombies try to
-fly under the radar and avoid spamming the same site repeatedly. Once
-postscreen(8) decides that a client is not-a-zombie, it whitelists the client
-temporarily to avoid further delays for legitimate mail.
+The main challenge for postscreen(8) is to make an is-a-zombie decision based
+on a single measurement. This is necessary because many zombies try to fly
+under the radar and avoid spamming the same site repeatedly. Once postscreen(8)
+decides that a client is not-a-zombie, it whitelists the client temporarily to
+avoid further delays for legitimate mail.
Zombies have challenges too: they have only a limited amount of time to deliver
spam before their IP address becomes blacklisted. To speed up spam deliveries,
postscreen(8) uses a variety of measurements to recognize zombies. First,
postscreen(8) determines if the remote SMTP client IP address is blacklisted.
Second, postscreen(8) looks for protocol compromises that are made to speed up
-delivery. These are good indicators for making is-it-a-zombie decisions based
-on single measurements.
+delivery. These are good indicators for making is-a-zombie decisions based on
+single measurements.
postscreen(8) does not inspect message content. Message content can vary from
one delivery to the next, especially with clients that (also) send legitimate
-email. Content is not a good indicator for making is-it-a-zombie decisions
-based on single measurements, and that is the problem that postscreen(8) is
-focused on.
+email. Content is not a good indicator for making is-a-zombie decisions based
+on single measurements, and that is the problem that postscreen(8) is focused
+on.
G\bGe\ben\bne\ber\bra\bal\bl o\bop\bpe\ber\bra\bat\bti\bio\bon\bn
* A non-persistent memcache: temporary whitelist can be shared between
postscreen(8) daemons on the same host or different hosts. Disable cache
cleanup (postscreen_cache_cleanup_interval = 0) in all postscreen(8)
- daemons because memcache: does not implement this (but see example 4 below
+ daemons because memcache: has no first-next API (but see example 4 below
for memcache: with persistent backup). This requires Postfix 2.9 or later.
# Example 1: non-persistent memcache: whitelist.
client_port=1234
P\bPo\bos\bst\btf\bfi\bix\bx v\bve\ber\brs\bsi\bio\bon\bn 3\b3.\b.1\b1 a\ban\bnd\bd l\bla\bat\bte\ber\br:\b:
policy_context=submission
+ P\bPo\bos\bst\btf\bfi\bix\bx v\bve\ber\brs\bsi\bio\bon\bn 3\b3.\b.2\b2 a\ban\bnd\bd l\bla\bat\bte\ber\br:\b:
+ server_address=10.3.2.1
+ server_port=54321
[empty line]
Notes:
the "DATA" and "END-OF-MESSAGE" stages. It specifies the number of
recipients that Postfix accepted for the current message.
- * The client address is an IPv4 dotted quad in the form 1.2.3.4 or it is an
- IPv6 address in the form 1:2:3::4:5:6.
+ * The remote client or local server IP address is an IPv4 dotted quad in the
+ form 1.2.3.4 or it is an IPv6 address in the form 1:2:3::4:5:6.
+
+ * The remote client or local server port is a decimal number in the range 0-
+ 65535.
* For a discussion of the differences between reverse and verified
client_name information, see the reject_unknown_client_hostname discussion
* Attribute values are xtext encoded as per RFC 1891.
- * The NAME attribute specifies an SMTP client hostname (not an SMTP client
- address), [UNAVAILABLE] when client hostname lookup failed due to a
+ * The NAME attribute specifies a remote SMTP client hostname (not an SMTP
+ client address), [UNAVAILABLE] when client hostname lookup failed due to a
permanent error, or [TEMPUNAVAIL] when the lookup error condition was
transient.
- * The ADDR attribute specifies an SMTP client numerical IPv4 network address,
- an IPv6 address prefixed with IPV6:, or [UNAVAILABLE] when the address
- information is unavailable. Address information is not enclosed with [].
+ * The ADDR attribute specifies a remote SMTP client numerical IPv4 network
+ address, an IPv6 address prefixed with IPV6:, or [UNAVAILABLE] when the
+ address information is unavailable. Address information is not enclosed
+ with [].
- * The PORT attribute specifies the SMTP client TCP port number as a decimal
- number, or [UNAVAILABLE] when the information is unavailable.
+ * The PORT attribute specifies a remote SMTP client TCP port number as a
+ decimal number, or [UNAVAILABLE] when the information is unavailable.
* The PROTO attribute specifies either SMTP or ESMTP.
+ * The DESTADDR attribute specifies a local SMTP server numerical IPv4 network
+ address, an IPv6 address prefixed with IPV6:, or [UNAVAILABLE] when the
+ address information is unavailable. Address information is not enclosed
+ with [].
+
+ * The DESTPORT attribute specifies a local SMTP server TCP port number as a
+ decimal number, or [UNAVAILABLE] when the information is unavailable.
+
* The HELO attribute specifies an SMTP HELO parameter value, or the value
[UNAVAILABLE] when the information is unavailable.
Disable -DSNAPSHOT and -DNONPROD in makedefs.
+ Propagate SMTPD_PEER_CODE_XXX from smtpd(8) to cleanup(8),
+ so that {client_resolve} and {_} produce consistent results.
+
Modeline support in config files to enable/disable trailing
#comment, and to give hints about how to handle an LHS or
RHS.
+ The cleanup daemon searches canonical_maps and virtual_alias_maps
+ with quoted address forms. The address local part should
+ be in unquoted form before it is split into name and
+ extension. Note, however, that although quoting is done
+ over the entire localpart, unquoting is not simply a matter
+ of removing the outer quotes. The fix will require careful
+ consideration of the responsibilities of mail_addr_map(),
+ mail_addr_find(), and mail_addr_crunch(), and making sure
+ that the callers can handle quoted results. For example,
+ sender_bcc_maps and recipient_bcc_maps invoke mail_addr_find()
+ with unquoted forms and expects an unquoted result, and so on.
+
Maintainability: replace lengthy libmilter-API argument lists
with named parameters, as with the libtls API.
<tr> <td> {auth_type} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
login method </td> </tr>
-<tr> <td> {client_addr} </td> <td> Always </td> <td> Client IP
-address </td> </tr>
+<tr> <td> {client_addr} </td> <td> Always </td> <td> Remote client
+IP address </td> </tr>
<tr> <td> {client_connections} </td> <td> CONNECT </td> <td>
Connection concurrency for this client (zero if the client is
excluded from all smtpd_client_* limits). </td> </tr>
-<tr> <td> {client_name} </td> <td> Always </td> <td> Client hostname
-<br> When address → name lookup or name → address
+<tr> <td> {client_name} </td> <td> Always </td> <td> Remote client
+hostname <br> When address → name lookup or name → address
verification fails: "unknown" </td> </tr>
<tr> <td> {client_port} </td> <td> Always (Postfix ≥2.5) </td>
-<td> Client TCP port </td> </tr>
+<td> Remote client TCP port </td> </tr>
<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
<td> Client name from address → name lookup <br> When address
<tr> <td> {cipher} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td> TLS
cipher </td> </tr>
+<tr> <td> {daemon_addr} </td> <td> Always (Postfix ≥3.2) </td>
+<td> Local server IP address </td> </tr>
+
<tr> <td> {daemon_name} </td> <td> Always </td> <td> value of
<a href="postconf.5.html#milter_macro_daemon_name">milter_macro_daemon_name</a> </td> </tr>
+<tr> <td> {daemon_port} </td> <td> Always (Postfix ≥3.2) </td>
+<td> Local server TCP port </td> </tr>
+
<tr> <td> {mail_addr} </td> <td> MAIL </td> <td> Sender address
</td> </tr>
<li> <p> Some Milter applications use the "<tt>{if_addr}</tt>" macro
to recognize local mail; this macro does not exist in Postfix.
-Workaround: use the "<tt>{client_addr}</tt>" macro instead. </p>
+Workaround: use the "<tt>{daemon_addr}</tt>" (Postfix &ge 3.2) or
+"<tt>{client_addr}</tt>" macro instead. </p>
<li> <p> Some Milter applications log a warning that looks like
this: </p>
tool like <a href="postscreen.8.html">postscreen(8)</a> that keeps the zombies away, Postfix would be
spending most of its resources not receiving email. </p>
-<p> The main challenge for <a href="postscreen.8.html">postscreen(8)</a> is to make an is-it-a-zombie
+<p> The main challenge for <a href="postscreen.8.html">postscreen(8)</a> is to make an is-a-zombie
decision based on a single measurement. This is necessary because
many zombies try to fly under the radar and avoid spamming the same
site repeatedly. Once <a href="postscreen.8.html">postscreen(8)</a> decides that a client is
zombies. First, <a href="postscreen.8.html">postscreen(8)</a> determines if the remote SMTP client
IP address is blacklisted. Second, <a href="postscreen.8.html">postscreen(8)</a> looks for protocol
compromises that are made to speed up delivery. These are good
-indicators for making is-it-a-zombie decisions based on single
+indicators for making is-a-zombie decisions based on single
measurements. </p>
<p> <a href="postscreen.8.html">postscreen(8)</a> does not inspect message content. Message content
can vary from one delivery to the next, especially with clients
that (also) send legitimate email. Content is not a good indicator
-for making is-it-a-zombie decisions based on single measurements,
+for making is-a-zombie decisions based on single measurements,
and that is the problem that <a href="postscreen.8.html">postscreen(8)</a> is focused on. </p>
<h2> <a name="general"> General operation </a> </h2>
<li> <p> A non-persistent <a href="memcache_table.5.html">memcache</a>: temporary whitelist can be shared
between <a href="postscreen.8.html">postscreen(8)</a> daemons on the same host or different
hosts. Disable cache cleanup (<a href="postconf.5.html#postscreen_cache_cleanup_interval">postscreen_cache_cleanup_interval</a>
- = 0) in all <a href="postscreen.8.html">postscreen(8)</a> daemons because <a href="memcache_table.5.html">memcache</a>: does not
- implement this (but see example 4 below for <a href="memcache_table.5.html">memcache</a>: with
+ = 0) in all <a href="postscreen.8.html">postscreen(8)</a> daemons because <a href="memcache_table.5.html">memcache</a>: has no
+ first-next API (but see example 4 below for <a href="memcache_table.5.html">memcache</a>: with
persistent backup). This requires Postfix 2.9 or later. </p>
<pre>
client_port=1234
<b>Postfix version 3.1 and later:</b>
policy_context=submission
+<b>Postfix version 3.2 and later:</b>
+server_address=10.3.2.1
+server_port=54321
[empty line]
</pre>
</blockquote>
specifies the number of recipients that Postfix accepted for
the current message. </p>
- <li> <p> The client address is an IPv4 dotted quad in the form
- 1.2.3.4 or it is an IPv6 address in the form 1:2:3::4:5:6.
- </p>
+ <li> <p> The remote client or local server IP address is an
+ IPv4 dotted quad in the form 1.2.3.4 or it is an IPv6 address
+ in the form 1:2:3::4:5:6. </p>
+
+ <li> <p> The remote client or local server port is a decimal
+ number in the range 0-65535. </p>
<li> <p> For a discussion of the differences between reverse
and verified client_name information, see the
<li> <p> Attribute values are xtext encoded as per <a href="http://tools.ietf.org/html/rfc1891">RFC 1891</a>.
</p>
- <li> <p> The NAME attribute specifies an SMTP client hostname
- (not an SMTP client address), [UNAVAILABLE] when client hostname
- lookup failed due to a permanent error, or [TEMPUNAVAIL] when
- the lookup error condition was transient. </p>
+ <li> <p> The NAME attribute specifies a remote SMTP client
+ hostname (not an SMTP client address), [UNAVAILABLE] when client
+ hostname lookup failed due to a permanent error, or [TEMPUNAVAIL]
+ when the lookup error condition was transient. </p>
- <li> <p> The ADDR attribute specifies an SMTP client numerical
- IPv4 network address, an IPv6 address prefixed with IPV6:, or
- [UNAVAILABLE] when the address information is unavailable.
- Address information is not enclosed with []. </p>
+ <li> <p> The ADDR attribute specifies a remote SMTP client
+ numerical IPv4 network address, an IPv6 address prefixed with
+ IPV6:, or [UNAVAILABLE] when the address information is
+ unavailable. Address information is not enclosed with []. </p>
- <li> <p> The PORT attribute specifies the SMTP client TCP port
- number as a decimal number, or [UNAVAILABLE] when the information
- is unavailable. </p>
+ <li> <p> The PORT attribute specifies a remote SMTP client TCP
+ port number as a decimal number, or [UNAVAILABLE] when the
+ information is unavailable. </p>
<li> <p> The PROTO attribute specifies either SMTP or ESMTP.
</p>
+ <li> <p> The DESTADDR attribute specifies a local SMTP server
+ numerical IPv4 network address, an IPv6 address prefixed with
+ IPV6:, or [UNAVAILABLE] when the address information is
+ unavailable. Address information is not enclosed with []. </p>
+
+ <li> <p> The DESTPORT attribute specifies a local SMTP server
+ TCP port number as a decimal number, or [UNAVAILABLE] when the
+ information is unavailable. </p>
+
<li> <p> The HELO attribute specifies an SMTP HELO parameter
value, or the value [UNAVAILABLE] when the information is
unavailable. </p>
match and replies with the query arguments plus an address list with
the resulting IP addresses, separated by whitespace, and the reply TTL.
Otherwise it replies with the query arguments plus an empty address
- list and the reply TTL (-1 if unavailable). Finally, The <a href="dnsblog.8.html"><b>dnsblog</b>(8)</a>
- server closes the connection.
+ list and the reply TTL; the reply TTL is -1 if no reply is received, or
+ a negative reply without SOA record. Finally, The <a href="dnsblog.8.html"><b>dnsblog</b>(8)</a> server
+ closes the connection.
<b>DIAGNOSTICS</b>
Problems and transactions are logged to <b>syslogd</b>(8).
run for only a limited amount of time. Use the command "<b>postfix reload</b>"
to speed up a change.
- The text below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
+ The text below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
more details including examples.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
figuration files.
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to handle a
+ How much time a Postfix daemon process may take to handle a
request before it is terminated by a built-in watchdog timer.
<b><a href="postconf.5.html#postscreen_dnsbl_sites">postscreen_dnsbl_sites</a> (empty)</b>
factors.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
- The time limit for sending or receiving information over an
+ The time limit for sending or receiving information over an
internal communication channel.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ The mail system name that is prepended to the process name in
+ syslog records, so that "smtpd" becomes, for example, "post-
fix/smtpd".
<b>SEE ALSO</b>
Delete one message with the named queue ID from the named mail
queue(s) (default: <b>hold</b>, <b>incoming</b>, <b>active</b> and <b>deferred</b>).
- If a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the program reads queue IDs
- from standard input. For example, to delete all mail with
- exactly one recipient <b>user@example.com</b>:
+ To delete multiple files, specify the <b>-d</b> option multiple times,
+ or specify a <i>queue</i><b>_</b><i>id</i> of <b>-</b> to read queue IDs from standard
+ input. For example, to delete all mail with exactly one recipi-
+ ent <b>user@example.com</b>:
mailq | tail +2 | grep -v '^ *(' | awk 'BEGIN { RS = "" }
# $7=sender, $8=recipient1, $9=recipient2
print $1 }
' | tr -d '*!' | postsuper -d -
- Specify "<b>-d ALL</b>" to remove all messages; for example, specify
- "<b>-d ALL deferred</b>" to delete all mail in the <b>deferred</b> queue. As
- a safety measure, the word <b>ALL</b> must be specified in upper case.
+ Specify "<b>-d ALL</b>" to remove all messages; for example, specify
+ "<b>-d ALL deferred</b>" to delete all mail in the <b>deferred</b> queue. As
+ a safety measure, the word <b>ALL</b> must be specified in upper case.
- Warning: Postfix queue IDs are reused (always with Postfix <=
- 2.8; and with Postfix >= 2.9 when <a href="postconf.5.html#enable_long_queue_ids">enable_long_queue_ids</a>=no).
- There is a very small possibility that postsuper deletes the
- wrong message file when it is executed while the Postfix mail
+ Warning: Postfix queue IDs are reused (always with Postfix <=
+ 2.8; and with Postfix >= 2.9 when <a href="postconf.5.html#enable_long_queue_ids">enable_long_queue_ids</a>=no).
+ There is a very small possibility that postsuper deletes the
+ wrong message file when it is executed while the Postfix mail
system is delivering mail.
The scenario is as follows:
- 1) The Postfix queue manager deletes the message that <a href="postsuper.1.html"><b>post-</b></a>
- <a href="postsuper.1.html"><b>super</b>(1)</a> is asked to delete, because Postfix is finished
- with the message (it is delivered, or it is returned to
+ 1) The Postfix queue manager deletes the message that <a href="postsuper.1.html"><b>post-</b></a>
+ <a href="postsuper.1.html"><b>super</b>(1)</a> is asked to delete, because Postfix is finished
+ with the message (it is delivered, or it is returned to
the sender).
- 2) New mail arrives, and the new message is given the same
- queue ID as the message that <a href="postsuper.1.html"><b>postsuper</b>(1)</a> is supposed to
- delete. The probability for reusing a deleted queue ID
- is about 1 in 2**15 (the number of different microsecond
- values that the system clock can distinguish within a
+ 2) New mail arrives, and the new message is given the same
+ queue ID as the message that <a href="postsuper.1.html"><b>postsuper</b>(1)</a> is supposed to
+ delete. The probability for reusing a deleted queue ID
+ is about 1 in 2**15 (the number of different microsecond
+ values that the system clock can distinguish within a
second).
- 3) <a href="postsuper.1.html"><b>postsuper</b>(1)</a> deletes the new message, instead of the old
+ 3) <a href="postsuper.1.html"><b>postsuper</b>(1)</a> deletes the new message, instead of the old
message that it should have deleted.
<b>-h</b> <i>queue</i><b>_</b><i>id</i>
- Put mail "on hold" so that no attempt is made to deliver it.
- Move one message with the named queue ID from the named mail
- queue(s) (default: <b>incoming</b>, <b>active</b> and <b>deferred</b>) to the <b>hold</b>
+ Put mail "on hold" so that no attempt is made to deliver it.
+ Move one message with the named queue ID from the named mail
+ queue(s) (default: <b>incoming</b>, <b>active</b> and <b>deferred</b>) to the <b>hold</b>
queue.
- If a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the program reads queue IDs
- from standard input.
+ To hold multiple files, specify the <b>-h</b> option multiple times, or
+ specify a <i>queue</i><b>_</b><i>id</i> of <b>-</b> to read queue IDs from standard input.
- Specify "<b>-h ALL</b>" to hold all messages; for example, specify "<b>-h</b>
- <b>ALL deferred</b>" to hold all mail in the <b>deferred</b> queue. As a
+ Specify "<b>-h ALL</b>" to hold all messages; for example, specify "<b>-h</b>
+ <b>ALL deferred</b>" to hold all mail in the <b>deferred</b> queue. As a
safety measure, the word <b>ALL</b> must be specified in upper case.
- Note: while mail is "on hold" it will not expire when its time
- in the queue exceeds the <b><a href="postconf.5.html#maximal_queue_lifetime">maximal_queue_lifetime</a></b> or
- <b><a href="postconf.5.html#bounce_queue_lifetime">bounce_queue_lifetime</a></b> setting. It becomes subject to expiration
+ Note: while mail is "on hold" it will not expire when its time
+ in the queue exceeds the <b><a href="postconf.5.html#maximal_queue_lifetime">maximal_queue_lifetime</a></b> or
+ <b><a href="postconf.5.html#bounce_queue_lifetime">bounce_queue_lifetime</a></b> setting. It becomes subject to expiration
after it is released from "hold".
This feature is available in Postfix 2.0 and later.
<b>-H</b> <i>queue</i><b>_</b><i>id</i>
- Release mail that was put "on hold". Move one message with the
- named queue ID from the named mail queue(s) (default: <b>hold</b>) to
+ Release mail that was put "on hold". Move one message with the
+ named queue ID from the named mail queue(s) (default: <b>hold</b>) to
the <b>deferred</b> queue.
- If a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the program reads queue IDs
- from standard input.
+ To release multiple files, specify the <b>-H</b> option multiple times,
+ or specify a <i>queue</i><b>_</b><i>id</i> of <b>-</b> to read queue IDs from standard
+ input.
Note: specify "<b>postsuper -r</b>" to release mail that was kept on
hold for a significant fraction of <b>$<a href="postconf.5.html#maximal_queue_lifetime">maximal_queue_lifetime</a></b> or
<b>-r</b> <i>queue</i><b>_</b><i>id</i>
Requeue the message with the named queue ID from the named mail
- queue(s) (default: <b>hold</b>, <b>incoming</b>, <b>active</b> and <b>deferred</b>). To
- requeue multiple messages, specify multiple <b>-r</b> command-line
- options.
+ queue(s) (default: <b>hold</b>, <b>incoming</b>, <b>active</b> and <b>deferred</b>).
- Alternatively, if a <i>queue</i><b>_</b><i>id</i> of <b>-</b> is specified, the program
- reads queue IDs from standard input.
+ To requeue multiple files, specify the <b>-r</b> option multiple times,
+ or specify a <i>queue</i><b>_</b><i>id</i> of <b>-</b> to read queue IDs from standard
+ input.
- Specify "<b>-r ALL</b>" to requeue all messages. As a safety measure,
+ Specify "<b>-r ALL</b>" to requeue all messages. As a safety measure,
the word <b>ALL</b> must be specified in upper case.
A requeued message is moved to the <b>maildrop</b> queue, from where it
is copied by the <a href="pickup.8.html"><b>pickup</b>(8)</a> and <a href="cleanup.8.html"><b>cleanup</b>(8)</a> daemons to a new queue
- file. In many respects its handling differs from that of a new
+ file. In many respects its handling differs from that of a new
local submission.
- <b>o</b> The message is not subjected to the <a href="postconf.5.html#smtpd_milters">smtpd_milters</a> or
+ <b>o</b> The message is not subjected to the <a href="postconf.5.html#smtpd_milters">smtpd_milters</a> or
<a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a> settings. When mail has passed through
- an external content filter, this would produce incorrect
- results with Milter applications that depend on original
+ an external content filter, this would produce incorrect
+ results with Milter applications that depend on original
SMTP connection state information.
- <b>o</b> The message is subjected again to mail address rewriting
+ <b>o</b> The message is subjected again to mail address rewriting
and substitution. This is useful when rewriting rules or
virtual mappings have changed.
- The address rewriting context (local or remote) is the
+ The address rewriting context (local or remote) is the
same as when the message was received.
- <b>o</b> The message is subjected to the same <a href="postconf.5.html#content_filter">content_filter</a> set-
- tings (if any) as used for new local mail submissions.
+ <b>o</b> The message is subjected to the same <a href="postconf.5.html#content_filter">content_filter</a> set-
+ tings (if any) as used for new local mail submissions.
This is useful when <a href="postconf.5.html#content_filter">content_filter</a> settings have changed.
- Warning: Postfix queue IDs are reused (always with Postfix <=
- 2.8; and with Postfix >= 2.9 when <a href="postconf.5.html#enable_long_queue_ids">enable_long_queue_ids</a>=no).
+ Warning: Postfix queue IDs are reused (always with Postfix <=
+ 2.8; and with Postfix >= 2.9 when <a href="postconf.5.html#enable_long_queue_ids">enable_long_queue_ids</a>=no).
There is a very small possibility that <a href="postsuper.1.html"><b>postsuper</b>(1)</a> requeues the
- wrong message file when it is executed while the Postfix mail
+ wrong message file when it is executed while the Postfix mail
system is running, but no harm should be done.
This feature is available in Postfix 1.1 and later.
- <b>-s</b> Structure check and structure repair. This should be done once
+ <b>-s</b> Structure check and structure repair. This should be done once
before Postfix startup.
- <b>o</b> Rename files whose name does not match the message file
+ <b>o</b> Rename files whose name does not match the message file
inode number. This operation is necessary after restoring
- a mail queue from a different machine or from backup,
+ a mail queue from a different machine or from backup,
when queue files were created with Postfix <= 2.8 or with
"<a href="postconf.5.html#enable_long_queue_ids">enable_long_queue_ids</a> = no".
- <b>o</b> Move queue files that are in the wrong place in the file
- system hierarchy and remove subdirectories that are no
- longer needed. File position rearrangements are neces-
+ <b>o</b> Move queue files that are in the wrong place in the file
+ system hierarchy and remove subdirectories that are no
+ longer needed. File position rearrangements are neces-
sary after a change in the <b><a href="postconf.5.html#hash_queue_names">hash_queue_names</a></b> and/or
<b><a href="postconf.5.html#hash_queue_depth">hash_queue_depth</a></b> configuration parameters.
- <b>o</b> Rename queue files created with "<a href="postconf.5.html#enable_long_queue_ids">enable_long_queue_ids</a> =
- yes" to short names, for migration to Postfix <= 2.8.
+ <b>o</b> Rename queue files created with "<a href="postconf.5.html#enable_long_queue_ids">enable_long_queue_ids</a> =
+ yes" to short names, for migration to Postfix <= 2.8.
The procedure is as follows:
# postfix stop
Run <a href="postsuper.1.html"><b>postsuper</b>(1)</a> repeatedly until it stops reporting file
name changes.
- <b>-S</b> A redundant version of <b>-s</b> that requires that long file names
+ <b>-S</b> A redundant version of <b>-s</b> that requires that long file names
also match the message file inode number. This option exists for
testing purposes, and is available with Postfix 2.9 and later.
- <b>-v</b> Enable verbose logging for debugging purposes. Multiple <b>-v</b>
+ <b>-v</b> Enable verbose logging for debugging purposes. Multiple <b>-v</b>
options make the software increasingly verbose.
<b>DIAGNOSTICS</b>
Problems are reported to the standard error stream and to <b>syslogd</b>(8).
<a href="postsuper.1.html"><b>postsuper</b>(1)</a> reports the number of messages deleted with <b>-d</b>, the number
- of messages requeued with <b>-r</b>, and the number of messages whose queue
- file name was fixed with <b>-s</b>. The report is written to the standard
+ of messages requeued with <b>-r</b>, and the number of messages whose queue
+ file name was fixed with <b>-s</b>. The report is written to the standard
error stream and to <b>syslogd</b>(8).
<b>ENVIRONMENT</b>
cannot be placed "on hold".
<b>CONFIGURATION PARAMETERS</b>
- The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
- gram. The text below provides only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
+ The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
+ gram. The text below provides only a parameter summary. See <a href="postconf.5.html"><b>post-</b></a>
<a href="postconf.5.html"><b>conf</b>(5)</a> for more details including examples.
<b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
- The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
+ The default location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
figuration files.
<b><a href="postconf.5.html#hash_queue_depth">hash_queue_depth</a> (1)</b>
- The number of subdirectory levels for queue directories listed
+ The number of subdirectory levels for queue directories listed
with the <a href="postconf.5.html#hash_queue_names">hash_queue_names</a> parameter.
<b><a href="postconf.5.html#hash_queue_names">hash_queue_names</a> (deferred, defer)</b>
- The names of queue directories that are split across multiple
+ The names of queue directories that are split across multiple
subdirectory levels.
<b><a href="postconf.5.html#queue_directory">queue_directory</a> (see 'postconf -d' output)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
- The mail system name that is prepended to the process name in
- syslog records, so that "smtpd" becomes, for example, "post-
+ The mail system name that is prepended to the process name in
+ syslog records, so that "smtpd" becomes, for example, "post-
fix/smtpd".
Available in Postfix version 2.9 and later:
mail queue(s) (default: \fBhold\fR, \fBincoming\fR, \fBactive\fR and
\fBdeferred\fR).
-If a \fIqueue_id\fR of \fB\-\fR is specified, the program reads
-queue IDs from standard input. For example, to delete all mail
+To delete multiple files, specify the \fB\-d\fR option multiple
+times, or specify a \fIqueue_id\fR of \fB\-\fR to read queue IDs
+from standard input. For example, to delete all mail
with exactly one recipient \fBuser@example.com\fR:
.sp
.nf
mail queue(s) (default: \fBincoming\fR, \fBactive\fR and
\fBdeferred\fR) to the \fBhold\fR queue.
-If a \fIqueue_id\fR of \fB\-\fR is specified, the program reads
-queue IDs from standard input.
+To hold multiple files, specify the \fB\-h\fR option multiple
+times, or specify a \fIqueue_id\fR of \fB\-\fR to read queue IDs
+from standard input.
.sp
Specify "\fB\-h ALL\fR" to hold all messages; for example, specify
"\fB\-h ALL deferred\fR" to hold all mail in the \fBdeferred\fR queue.
Move one message with the named queue ID from the named
mail queue(s) (default: \fBhold\fR) to the \fBdeferred\fR queue.
-If a \fIqueue_id\fR of \fB\-\fR is specified, the program reads
-queue IDs from standard input.
+To release multiple files, specify the \fB\-H\fR option multiple
+times, or specify a \fIqueue_id\fR of \fB\-\fR to read queue IDs
+from standard input.
.sp
Note: specify "\fBpostsuper \-r\fR" to release mail that was kept on
hold for a significant fraction of \fB$maximal_queue_lifetime\fR
Requeue the message with the named queue ID from the named
mail queue(s) (default: \fBhold\fR, \fBincoming\fR, \fBactive\fR and
\fBdeferred\fR).
-To requeue multiple messages, specify multiple \fB\-r\fR
-command\-line options.
-Alternatively, if a \fIqueue_id\fR of \fB\-\fR is specified,
-the program reads queue IDs from standard input.
+To requeue multiple files, specify the \fB\-r\fR option multiple
+times, or specify a \fIqueue_id\fR of \fB\-\fR to read queue IDs
+from standard input.
.sp
Specify "\fB\-r ALL\fR" to requeue all messages. As a safety
measure, the word \fBALL\fR must be specified in upper case.
query arguments plus an address list with the resulting IP
addresses, separated by whitespace, and the reply TTL.
Otherwise it replies with the query arguments plus an empty
-address list and the reply TTL (\-1 if unavailable). Finally,
-The \fBdnsblog\fR(8) server closes the connection.
+address list and the reply TTL; the reply TTL is \-1 if no
+reply is received, or a negative reply without SOA record.
+Finally, The \fBdnsblog\fR(8) server closes the connection.
.SH DIAGNOSTICS
.ad
.fi
.ad
.fi
The Secure Mailer license must be distributed with this software.
-.SH "HISTORY"
-.na
-.nf
+.SH HISTORY
+.ad
+.fi
.ad
.fi
This service was introduced with Postfix version 2.8.
<tr> <td> {auth_type} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
login method </td> </tr>
-<tr> <td> {client_addr} </td> <td> Always </td> <td> Client IP
-address </td> </tr>
+<tr> <td> {client_addr} </td> <td> Always </td> <td> Remote client
+IP address </td> </tr>
<tr> <td> {client_connections} </td> <td> CONNECT </td> <td>
Connection concurrency for this client (zero if the client is
excluded from all smtpd_client_* limits). </td> </tr>
-<tr> <td> {client_name} </td> <td> Always </td> <td> Client hostname
-<br> When address → name lookup or name → address
+<tr> <td> {client_name} </td> <td> Always </td> <td> Remote client
+hostname <br> When address → name lookup or name → address
verification fails: "unknown" </td> </tr>
<tr> <td> {client_port} </td> <td> Always (Postfix ≥2.5) </td>
-<td> Client TCP port </td> </tr>
+<td> Remote client TCP port </td> </tr>
<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
<td> Client name from address → name lookup <br> When address
<tr> <td> {cipher} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td> TLS
cipher </td> </tr>
+<tr> <td> {daemon_addr} </td> <td> Always (Postfix ≥3.2) </td>
+<td> Local server IP address </td> </tr>
+
<tr> <td> {daemon_name} </td> <td> Always </td> <td> value of
milter_macro_daemon_name </td> </tr>
+<tr> <td> {daemon_port} </td> <td> Always (Postfix ≥3.2) </td>
+<td> Local server TCP port </td> </tr>
+
<tr> <td> {mail_addr} </td> <td> MAIL </td> <td> Sender address
</td> </tr>
<li> <p> Some Milter applications use the "<tt>{if_addr}</tt>" macro
to recognize local mail; this macro does not exist in Postfix.
-Workaround: use the "<tt>{client_addr}</tt>" macro instead. </p>
+Workaround: use the "<tt>{daemon_addr}</tt>" (Postfix &ge 3.2) or
+"<tt>{client_addr}</tt>" macro instead. </p>
<li> <p> Some Milter applications log a warning that looks like
this: </p>
tool like postscreen(8) that keeps the zombies away, Postfix would be
spending most of its resources not receiving email. </p>
-<p> The main challenge for postscreen(8) is to make an is-it-a-zombie
+<p> The main challenge for postscreen(8) is to make an is-a-zombie
decision based on a single measurement. This is necessary because
many zombies try to fly under the radar and avoid spamming the same
site repeatedly. Once postscreen(8) decides that a client is
zombies. First, postscreen(8) determines if the remote SMTP client
IP address is blacklisted. Second, postscreen(8) looks for protocol
compromises that are made to speed up delivery. These are good
-indicators for making is-it-a-zombie decisions based on single
+indicators for making is-a-zombie decisions based on single
measurements. </p>
<p> postscreen(8) does not inspect message content. Message content
can vary from one delivery to the next, especially with clients
that (also) send legitimate email. Content is not a good indicator
-for making is-it-a-zombie decisions based on single measurements,
+for making is-a-zombie decisions based on single measurements,
and that is the problem that postscreen(8) is focused on. </p>
<h2> <a name="general"> General operation </a> </h2>
<li> <p> A non-persistent memcache: temporary whitelist can be shared
between postscreen(8) daemons on the same host or different
hosts. Disable cache cleanup (postscreen_cache_cleanup_interval
- = 0) in all postscreen(8) daemons because memcache: does not
- implement this (but see example 4 below for memcache: with
+ = 0) in all postscreen(8) daemons because memcache: has no
+ first-next API (but see example 4 below for memcache: with
persistent backup). This requires Postfix 2.9 or later. </p>
<pre>
client_port=1234
<b>Postfix version 3.1 and later:</b>
policy_context=submission
+<b>Postfix version 3.2 and later:</b>
+server_address=10.3.2.1
+server_port=54321
[empty line]
</pre>
</blockquote>
specifies the number of recipients that Postfix accepted for
the current message. </p>
- <li> <p> The client address is an IPv4 dotted quad in the form
- 1.2.3.4 or it is an IPv6 address in the form 1:2:3::4:5:6.
- </p>
+ <li> <p> The remote client or local server IP address is an
+ IPv4 dotted quad in the form 1.2.3.4 or it is an IPv6 address
+ in the form 1:2:3::4:5:6. </p>
+
+ <li> <p> The remote client or local server port is a decimal
+ number in the range 0-65535. </p>
<li> <p> For a discussion of the differences between reverse
and verified client_name information, see the
<li> <p> Attribute values are xtext encoded as per RFC 1891.
</p>
- <li> <p> The NAME attribute specifies an SMTP client hostname
- (not an SMTP client address), [UNAVAILABLE] when client hostname
- lookup failed due to a permanent error, or [TEMPUNAVAIL] when
- the lookup error condition was transient. </p>
+ <li> <p> The NAME attribute specifies a remote SMTP client
+ hostname (not an SMTP client address), [UNAVAILABLE] when client
+ hostname lookup failed due to a permanent error, or [TEMPUNAVAIL]
+ when the lookup error condition was transient. </p>
- <li> <p> The ADDR attribute specifies an SMTP client numerical
- IPv4 network address, an IPv6 address prefixed with IPV6:, or
- [UNAVAILABLE] when the address information is unavailable.
- Address information is not enclosed with []. </p>
+ <li> <p> The ADDR attribute specifies a remote SMTP client
+ numerical IPv4 network address, an IPv6 address prefixed with
+ IPV6:, or [UNAVAILABLE] when the address information is
+ unavailable. Address information is not enclosed with []. </p>
- <li> <p> The PORT attribute specifies the SMTP client TCP port
- number as a decimal number, or [UNAVAILABLE] when the information
- is unavailable. </p>
+ <li> <p> The PORT attribute specifies a remote SMTP client TCP
+ port number as a decimal number, or [UNAVAILABLE] when the
+ information is unavailable. </p>
<li> <p> The PROTO attribute specifies either SMTP or ESMTP.
</p>
+ <li> <p> The DESTADDR attribute specifies a local SMTP server
+ numerical IPv4 network address, an IPv6 address prefixed with
+ IPV6:, or [UNAVAILABLE] when the address information is
+ unavailable. Address information is not enclosed with []. </p>
+
+ <li> <p> The DESTPORT attribute specifies a local SMTP server
+ TCP port number as a decimal number, or [UNAVAILABLE] when the
+ information is unavailable. </p>
+
<li> <p> The HELO attribute specifies an SMTP HELO parameter
value, or the value [UNAVAILABLE] when the information is
unavailable. </p>
cleanup_milter.o: ../../include/header_body_checks.h
cleanup_milter.o: ../../include/header_opts.h
cleanup_milter.o: ../../include/htable.h
+cleanup_milter.o: ../../include/inet_proto.h
cleanup_milter.o: ../../include/iostuff.h
cleanup_milter.o: ../../include/is_header.h
cleanup_milter.o: ../../include/lex_822.h
const char *client_addr; /* real or ersatz client */
int client_af; /* real or ersatz client */
const char *client_port; /* real or ersatz client */
+ const char *server_addr; /* real or ersatz server */
+ const char *server_port; /* real or ersatz server */
VSTRING *milter_ext_from; /* externalized sender */
VSTRING *milter_ext_rcpt; /* externalized recipient */
VSTRING *milter_err_text; /* milter call-back reply */
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
#include <vstream.h>
#include <vstring.h>
#include <stringops.h>
+#include <inet_proto.h>
/* Global library. */
*/
#ifndef CLIENT_ATTR_UNKNOWN
#define CLIENT_ATTR_UNKNOWN "unknown"
+#define SERVER_ATTR_UNKNOWN "unknown"
#endif
if (strcmp(name, S8_MAC__) == 0) {
state->client_port : "0");
if (strcmp(name, S8_MAC_CLIENT_PTR) == 0)
return (state->reverse_name);
+ /* XXX S8_MAC_CLIENT_RES needs SMTPD_PEER_CODE_XXX from smtpd. */
+ if (strcmp(name, S8_MAC_DAEMON_ADDR) == 0)
+ return (state->server_addr);
+ if (strcmp(name, S8_MAC_DAEMON_PORT) == 0)
+ return (state->server_port
+ && strcmp(state->server_port, SERVER_ATTR_UNKNOWN) ?
+ state->server_port : "0");
/*
* MAIL FROM macros.
static void cleanup_milter_client_init(CLEANUP_STATE *state)
{
+ static INET_PROTO_INFO *proto_info;
const char *proto_attr;
/*
state->client_addr = nvtable_find(state->attr, MAIL_ATTR_ACT_CLIENT_ADDR);
state->client_port = nvtable_find(state->attr, MAIL_ATTR_ACT_CLIENT_PORT);
proto_attr = nvtable_find(state->attr, MAIL_ATTR_ACT_CLIENT_AF);
+ state->server_addr = nvtable_find(state->attr, MAIL_ATTR_ACT_SERVER_ADDR);
+ state->server_port = nvtable_find(state->attr, MAIL_ATTR_ACT_SERVER_PORT);
if (state->client_name == 0 || state->client_addr == 0 || proto_attr == 0
|| !alldig(proto_attr)) {
state->client_name = "localhost";
- state->client_addr = "127.0.0.1";
- state->client_af = AF_INET;
+#ifdef AF_INET6
+ if (proto_info == 0)
+ proto_info = inet_proto_info();
+ if (proto_info->sa_family_list[0] == PF_INET6) {
+ state->client_addr = "::1";
+ state->client_af = AF_INET6;
+ } else
+#endif
+ {
+ state->client_addr = "127.0.0.1";
+ state->client_af = AF_INET;
+ }
+ state->server_addr = state->client_addr;
} else
state->client_af = atoi(proto_attr);
if (state->reverse_name == 0)
state->reverse_name = state->client_name;
/* Compatibility with pre-2.5 queue files. */
- if (state->client_port == 0)
+ if (state->client_port == 0) {
state->client_port = NO_CLIENT_PORT;
+ state->server_port = state->client_port;
+ }
}
/* cleanup_milter_inspect - run message through mail filter */
state->client_addr = 0;
state->client_af = 0;
state->client_port = 0;
+ state->server_addr = 0;
+ state->server_port = 0;
state->milter_ext_from = 0;
state->milter_ext_rcpt = 0;
state->milter_err_text = 0;
/* query arguments plus an address list with the resulting IP
/* addresses, separated by whitespace, and the reply TTL.
/* Otherwise it replies with the query arguments plus an empty
-/* address list and the reply TTL (-1 if unavailable). Finally,
-/* The \fBdnsblog\fR(8) server closes the connection.
+/* address list and the reply TTL; the reply TTL is -1 if no
+/* reply is received, or a negative reply without SOA record.
+/* Finally, The \fBdnsblog\fR(8) server closes the connection.
/* DIAGNOSTICS
/* Problems and transactions are logged to \fBsyslogd\fR(8).
/* CONFIGURATION PARAMETERS
#include <syslog.h>
#include <time.h>
#include <mysql.h>
+#include <limits.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
{
DICT_MYSQL *dict_mysql = (DICT_MYSQL *) dict;
int len = strlen(name);
- int buflen = 2 * len + 1;
+ int buflen;
/*
* We won't get integer overflows in 2*len + 1, because Postfix input
* keys have reasonable size limits, better safe than sorry.
*/
- if (buflen < len)
+ if (len > (INT_MAX - 1) / 2)
msg_panic("dict_mysql_quote: integer overflow in 2*%d+1", len);
+ buflen = 2 * len + 1;
VSTRING_SPACE(result, buflen);
#if defined(MYSQL_VERSION_ID) && MYSQL_VERSION_ID >= 40000
HOST *active_host = dict_pgsql->active_host;
char *myname = "dict_pgsql_quote";
size_t len = strlen(name);
- size_t buflen = 2 * len + 1;
+ size_t buflen;
int err = 1;
if (active_host == 0)
* We won't get arithmetic overflows in 2*len + 1, because Postfix input
* keys have reasonable size limits, better safe than sorry.
*/
- if (buflen <= len)
- msg_panic("%s: arithmetic overflow in 2*%lu+1",
- myname, (unsigned long) len);
+ if (len > (SSIZE_T_MAX - VSTRING_LEN(result) - 1) / 2)
+ msg_panic("%s: arithmetic overflow in %lu+2*%lu+1",
+ myname, (unsigned long) VSTRING_LEN(result),
+ (unsigned long) len);
+ buflen = 2 * len + 1;
/*
* XXX Workaround: stop further processing when PQescapeStringConn()
extern char *var_milt_def_action;
#define VAR_MILT_CONN_MACROS "milter_connect_macros"
-#define DEF_MILT_CONN_MACROS "j {daemon_name} v"
+#define DEF_MILT_CONN_MACROS "j {daemon_name} {daemon_addr} v"
extern char *var_milt_conn_macros;
#define VAR_MILT_HELO_MACROS "milter_helo_macros"
#define XCLIENT_PROTO "PROTO" /* client protocol */
#define XCLIENT_HELO "HELO" /* client helo */
#define XCLIENT_LOGIN "LOGIN" /* SASL login name */
+#define XCLIENT_DESTADDR "DESTADDR" /* server address */
+#define XCLIENT_DESTPORT "DESTPORT" /* server port */
#define XCLIENT_UNAVAILABLE "[UNAVAILABLE]" /* permanently unavailable */
#define XCLIENT_TEMPORARY "[TEMPUNAVAIL]" /* temporarily unavailable */
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
#endif
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20160604"
+#define MAIL_RELEASE_DATE "20160611"
#define MAIL_VERSION_NUMBER "3.2"
#ifdef SNAPSHOT
/*
* Sendmail 8 macro names. We support forms with and without the {}.
*/
-#define S8_MAC__ "{_}" /* sender resolve */
+#define S8_MAC__ "{_}" /* sender host, see client_resolve */
#define S8_MAC_J "{j}" /* myhostname */
#define S8_MAC_V "{v}" /* mail_name + mail_version */
#define S8_MAC_CLIENT_PTR "{client_ptr}"
#define S8_MAC_CLIENT_RES "{client_resolve}"
+#define S8_MAC_DAEMON_ADDR "{daemon_addr}"
+#define S8_MAC_DAEMON_PORT "{daemon_port}"
+
#define S8_MAC_TLS_VERSION "{tls_version}"
#define S8_MAC_CIPHER "{cipher}"
#define S8_MAC_CIPHER_BITS "{cipher_bits}"
"{client_port}",
"{client_ptr}",
"{client_resolve}",
+ "{daemon_addr}",
"{daemon_name}",
+ "{daemon_port}",
"{if_addr}",
"{if_name}",
"{mail_addr}",
/* mail queue(s) (default: \fBhold\fR, \fBincoming\fR, \fBactive\fR and
/* \fBdeferred\fR).
/*
-/* If a \fIqueue_id\fR of \fB-\fR is specified, the program reads
-/* queue IDs from standard input. For example, to delete all mail
+/* To delete multiple files, specify the \fB-d\fR option multiple
+/* times, or specify a \fIqueue_id\fR of \fB-\fR to read queue IDs
+/* from standard input. For example, to delete all mail
/* with exactly one recipient \fBuser@example.com\fR:
/* .sp
/* .nf
/* mail queue(s) (default: \fBincoming\fR, \fBactive\fR and
/* \fBdeferred\fR) to the \fBhold\fR queue.
/*
-/* If a \fIqueue_id\fR of \fB-\fR is specified, the program reads
-/* queue IDs from standard input.
+/* To hold multiple files, specify the \fB-h\fR option multiple
+/* times, or specify a \fIqueue_id\fR of \fB-\fR to read queue IDs
+/* from standard input.
/* .sp
/* Specify "\fB-h ALL\fR" to hold all messages; for example, specify
/* "\fB-h ALL deferred\fR" to hold all mail in the \fBdeferred\fR queue.
/* Move one message with the named queue ID from the named
/* mail queue(s) (default: \fBhold\fR) to the \fBdeferred\fR queue.
/*
-/* If a \fIqueue_id\fR of \fB-\fR is specified, the program reads
-/* queue IDs from standard input.
+/* To release multiple files, specify the \fB-H\fR option multiple
+/* times, or specify a \fIqueue_id\fR of \fB-\fR to read queue IDs
+/* from standard input.
/* .sp
/* Note: specify "\fBpostsuper -r\fR" to release mail that was kept on
/* hold for a significant fraction of \fB$maximal_queue_lifetime\fR
/* Requeue the message with the named queue ID from the named
/* mail queue(s) (default: \fBhold\fR, \fBincoming\fR, \fBactive\fR and
/* \fBdeferred\fR).
-/* To requeue multiple messages, specify multiple \fB-r\fR
-/* command-line options.
/*
-/* Alternatively, if a \fIqueue_id\fR of \fB-\fR is specified,
-/* the program reads queue IDs from standard input.
+/* To requeue multiple files, specify the \fB-r\fR option multiple
+/* times, or specify a \fIqueue_id\fR of \fB-\fR to read queue IDs
+/* from standard input.
/* .sp
/* Specify "\fB-r ALL\fR" to requeue all messages. As a safety
/* measure, the word \fBALL\fR must be specified in upper case.
" " XCLIENT_NAME " " XCLIENT_ADDR
" " XCLIENT_PROTO " " XCLIENT_HELO
" " XCLIENT_REVERSE_NAME " " XCLIENT_PORT
- XCLIENT_LOGIN_KLUDGE);
+ XCLIENT_LOGIN_KLUDGE
+ " " XCLIENT_DESTADDR
+ " " XCLIENT_DESTPORT);
else if (xclient_hosts && xclient_hosts->error)
cant_announce_feature(state, XCLIENT_CMD);
}
MAIL_ATTR_ACT_CLIENT_ADDR, state->addr);
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ACT_CLIENT_PORT, state->port);
+ rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+ MAIL_ATTR_ACT_SERVER_ADDR, state->dest_addr);
+ rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
+ MAIL_ATTR_ACT_SERVER_PORT, state->dest_port);
if (state->helo_name)
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
MAIL_ATTR_ACT_HELO_NAME, state->helo_name);
}
#endif
+ /*
+ * DESTADDR=substitute SMTP server network address.
+ */
+ else if (STREQ(attr_name, XCLIENT_DESTADDR)) {
+ if (STREQ(attr_value, XCLIENT_UNAVAILABLE)) {
+ attr_value = SERVER_ADDR_UNKNOWN;
+ bare_value = attr_value;
+ } else {
+ if ((bare_value = valid_mailhost_addr(attr_value, DONT_GRIPE)) == 0) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
+ XCLIENT_DESTADDR, attr_value);
+ return (-1);
+ }
+ }
+ UPDATE_STR(state->dest_addr, bare_value);
+ /* XXX Require same address family as client address. */
+ }
+
+ /*
+ * DESTPORT=substitute SMTP server port number.
+ */
+ else if (STREQ(attr_name, XCLIENT_DESTPORT)) {
+ if (STREQ(attr_value, XCLIENT_UNAVAILABLE)) {
+ attr_value = SERVER_PORT_UNKNOWN;
+ } else {
+ if (!alldig(attr_value)
+ || strlen(attr_value) > sizeof("65535") - 1) {
+ state->error_mask |= MAIL_ERROR_PROTOCOL;
+ smtpd_chat_reply(state, "501 5.5.4 Bad %s syntax: %s",
+ XCLIENT_DESTPORT, attr_value);
+ return (-1);
+ }
+ }
+ UPDATE_STR(state->dest_port, attr_value);
+ }
+
/*
* Unknown attribute name. Complain.
*/
char *namaddr; /* name[address]:port */
char *rfc_addr; /* address for RFC 2821 */
int addr_family; /* address family */
- char *dest_addr; /* for Dovecot AUTH */
+ char *dest_addr; /* Dovecot AUTH, Milter {daemon_addr} */
+ char *dest_port; /* Milter {daemon_port} */
struct sockaddr_storage sockaddr; /* binary client endpoint */
SOCKADDR_SIZE sockaddr_len; /* binary client endpoint */
int name_status; /* 2=ok 4=soft 5=hard 6=forged */
#define CLIENT_DOMAIN_UNKNOWN 0
#define CLIENT_LOGIN_UNKNOWN 0
+#define SERVER_ATTR_UNKNOWN "unknown"
+
+#define SERVER_ADDR_UNKNOWN SERVER_ATTR_UNKNOWN
+#define SERVER_PORT_UNKNOWN SERVER_ATTR_UNKNOWN
+
#define IS_AVAIL_CLIENT_ATTR(v) ((v) && strcmp((v), CLIENT_ATTR_UNKNOWN))
#define IS_AVAIL_CLIENT_NAME(v) IS_AVAIL_CLIENT_ATTR(v)
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*
/* TLS support originally by:
/* Lutz Jaenicke
/* BTU Cottbus
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
+/*
/* TLS support originally by:
/* Lutz Jaenicke
/* BTU Cottbus
SEND_ATTR_STR(MAIL_ATTR_ACT_CLIENT_PORT, state->port),
SEND_ATTR_STR(MAIL_ATTR_ACT_REVERSE_CLIENT_NAME,
state->reverse_name),
+ SEND_ATTR_STR(MAIL_ATTR_ACT_SERVER_ADDR,
+ state->dest_addr),
+ SEND_ATTR_STR(MAIL_ATTR_ACT_SERVER_PORT,
+ state->dest_port),
SEND_ATTR_STR(MAIL_ATTR_ACT_HELO_NAME,
state->helo_name ? state->helo_name : ""),
SEND_ATTR_STR(MAIL_ATTR_SENDER,
/* both IPv6 and IPv4 support are enabled with main.cf:inet_protocols.
/* .IP \(bu
/* Update the following session context fields: addr, port,
-/* rfc_addr, addr_family, dest_addr. The addr_family field
-/* applies to the client address.
+/* rfc_addr, addr_family, dest_addr, dest_port. The addr_family
+/* field applies to the client address.
/* .IP \(bu
/* Dynamically allocate storage for string information with
/* mystrdup(). In case of error, leave unassigned string fields
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/* System library. */
state->port = mystrdup(smtp_client_port.buf);
/*
- * Avoid surprises in the Dovecot authentication server.
+ * The Dovecot authentication server needs the server IP address.
*/
state->dest_addr = mystrdup(smtp_server_addr.buf);
+ state->dest_port = mystrdup(smtp_server_port.buf);
/*
* Enable normal buffering.
state->name_status == SMTPD_PEER_CODE_FORGED ? "FORGED" :
state->name_status == SMTPD_PEER_CODE_TEMP ? "TEMP" : "FAIL");
+ if (strcmp(name, S8_MAC_DAEMON_ADDR) == 0)
+ return (state->dest_addr);
+ if (strcmp(name, S8_MAC_DAEMON_PORT) == 0)
+ return (state->dest_port);
+
/*
* HELO macros.
*/
/* String of the form "ipv4addr" or "ipv6:ipv6addr" for use
/* in Received: message headers.
/* .IP dest_addr
-/* Server address, used by the Dovecot authentication server.
+/* Server address, used by the Dovecot authentication server,
+/* available as Milter {daemon_addr} macro, and as server_address
+/* policy delegation attribute.
+/* .IP dest_port
+/* Server port, available as Milter {daemon_port} macro, and
+/* as server_port policy delegation attribute.
/* .IP name_status
/* The name_status result field specifies how the name
/* information should be interpreted:
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* Google, Inc.
+/* 111 8th Avenue
+/* New York, NY 10011, USA
/*--*/
/* System library. */
static INET_PROTO_INFO *proto_info;
/*
- * XXX If we make local endpoint (getsockname) information available to
- * Milter applications as {if_name} and {if_addr}, then we also must be able
- * to provide this via the XCLIENT command for Milter testing.
- *
- * XXX If we make local port information available to policy servers or Milter
- * applications, then we must also make this testable with the XCLIENT
- * command, otherwise there will be confusion.
- *
* XXX If we make local port information available via logging, then we must
* also support these attributes with the XFORWARD command.
*
state->name_status = SMTPD_PEER_CODE_OK;
state->reverse_name_status = SMTPD_PEER_CODE_OK;
state->port = mystrdup("0"); /* XXX bogus. */
+
+ state->dest_addr = mystrdup(state->addr); /* XXX bogus. */
+ state->dest_port = mystrdup(state->port); /* XXX bogus. */
}
/* smtpd_peer_no_client - peer went away, or peer info unavailable */
state->name_status = SMTPD_PEER_CODE_PERM;
state->reverse_name_status = SMTPD_PEER_CODE_PERM;
state->port = mystrdup(CLIENT_PORT_UNKNOWN);
+
+ state->dest_addr = mystrdup(SERVER_ADDR_UNKNOWN);
+ state->dest_port = mystrdup(SERVER_PORT_UNKNOWN);
}
/* smtpd_peer_from_pass_attr - initialize from attribute hash */
state->port = mystrdup(cp);
/*
- * Avoid surprises in the Dovecot authentication server.
+ * The Dovecot authentication server needs the server IP address.
*/
if ((cp = htable_find(attr, MAIL_ATTR_ACT_SERVER_ADDR)) == 0)
msg_fatal("missing server address from proxy");
if (valid_hostaddr(cp, DO_GRIPE) == 0)
- msg_fatal("bad IPv6 client address syntax from proxy: %s", cp);
+ msg_fatal("bad IPv6 server address syntax from proxy: %s", cp);
state->dest_addr = mystrdup(cp);
+ if ((cp = htable_find(attr, MAIL_ATTR_ACT_SERVER_PORT)) == 0)
+ msg_fatal("missing server port from proxy");
+ if (valid_hostport(cp, DO_GRIPE) == 0)
+ msg_fatal("bad TCP server port number syntax from proxy: %s", cp);
+ state->dest_port = mystrdup(cp);
+
/*
* Convert the client address from string to binary form.
*/
state->rfc_addr = 0;
state->port = 0;
state->dest_addr = 0;
+ state->dest_port = 0;
/*
* Determine the remote SMTP client address and port.
myfree(state->port);
if (state->dest_addr)
myfree(state->dest_addr);
+ if (state->dest_port)
+ myfree(state->dest_port);
}