From: Wietse Venema
Date: Tue, 28 Apr 2009 05:00:00 +0000 (-0500)
Subject: postfix-2.6.0-RC3
X-Git-Tag: v2.6.0-RC3^0
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=80146b661344c6853ea15412570f3a7a1a585ef0;p=thirdparty%2Fpostfix.git
postfix-2.6.0-RC3
---
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 58f8574a1..273c29c74 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -15133,3 +15133,64 @@ Apologies for any names omitted.
xsasl/xsasl.h, xsasl/xsasl*client.c, smtp/smtp_sasl_glue.c.
More postlink fixes. File: mantools/postlink.
+
+20090419
+
+ Bugfix: don't re-enable SIGHUP if it is ignored in the
+ parent. This may cause random "Postfix integrity check
+ failed" errors at boot time (POSIX SIGHUP death), causing
+ Postfix not to start. We duplicate code from postdrop and
+ thus avoid past mistakes. File: postsuper/postsuper.c.
+
+ Robustness: don't re-enable SIGTERM if it is ignored in the
+ parent. Files: postsuper/postsuper.c, postdrop/postdrop.c.
+
+20090422
+
+ Undo delivery agent change 20090415. The queue manager never
+ locks a queue file to read additional recipients into memory,
+ so if a delivery agent runs into a locked file, then something
+ is seriously wrong. File: global/deliver_request.c.
+
+20090424
+
+ Compatibility: the Postfix SMTP client no longer uses the
+ obsolete SSLv2 by default for opportunistic encryption.
+ This has nothing to do with security (we're willing to send
+ plaintext over an unauthenticated connection) but with the
+ loss of advanced options that give better performance.
+ Victor Duchovni. Files: proto/postconf.proto, global/mail_params.h.
+
+20090426
+
+ Feature: more accurate support for Milter macros {mail_addr}
+ and {rcpt_addr}, and new support for Milter macros {mail_host},
+ {mail_mailer}, {rcpt_host}, and {rcpt_mailer}. Files:
+ milter/milter.[hc], smtpd/smtpd.[hc], smtpd/smtpd_milter.c,
+ smtpd/smtpd_resolve.c.
+
+ Feature: support to report rejected recipients to Milters
+ (SMFIP_RCPT_REJ). Postfix reports the event as decribed in
+ Sendmail 8.14.0 documentation: {rcpt_mailer} = "error",
+ {rcpt_host} = enhanced status code (e.g., "5.7.1"), and
+ {rcpt_addr} = reason to reject (e.g., "Relay access denied").
+ Files: milter/milter.[hc], milter/milter8.c, smtpd/smtpd.[hc],
+ smtpd/smtpd_milter.c.
+
+20090427
+
+ Feature: Milter support for replacing the envelope sender
+ and adding recipients (SMFIR_CHGFROM, SMFIR_ADDRCPT_PAR).
+ This support currently ignores ESMTP command parameters.
+ Files: milter/milter8.c, cleanup/cleanup_milter.c.
+
+20090428
+
+ Compatibility: to make all the new Milter features usable,
+ raise the default milter_protocol setting from 2 to 6.
+ This has been tested with a Sendmail 8.14 libmilter.
+ File: global/mail_params.h.
+
+ Bugfix: don't disable MIME parsing with smtp_header_checks,
+ smtp_mime_header_checks, smtp_nested_header_checks or with
+ smtp_body_checks. Bug reported by Victor. File: smtp/smtp_proto.c.
diff --git a/postfix/README_FILES/FILTER_README b/postfix/README_FILES/FILTER_README
index 192ed2a48..ee5a275de 100644
--- a/postfix/README_FILES/FILTER_README
+++ b/postfix/README_FILES/FILTER_README
@@ -184,7 +184,8 @@ Once you're satisfied with the content filtering script:
store its temporary files.
* Configure Postfix to deliver mail to the content filter with the pipe(8)
- delivery agent.
+ delivery agent (see the pipe(8) manpage for a description of the command
+ syntax below).
/etc/postfix/master.cf:
# =============================================================
@@ -192,13 +193,14 @@ Once you're satisfied with the content filtering script:
# (yes) (yes) (yes) (never) (100)
# =============================================================
filter unix - n n - 10 pipe
- flags=Rq user=filter argv=/path/to/script -f ${sender} -- ${recipient}
+ flags=Rq user=filter null_sender=
+ argv=/path/to/script -f ${sender} -- ${recipient}
This runs up to 10 content filters in parallel. Instead of a limit of 10
concurrent processes, use whatever process limit is feasible for your
machine. Content inspection software can gobble up a lot of system
resources, so you don't want to have too much of it running at the same
- time.
+ time. The empty null_sender setting is required with Postfix 2.3 and later.
* To turn on content filtering for mail arriving via SMTP only, append "-
o content_filter=filter:dummy" to the master.cf entry that defines the
diff --git a/postfix/README_FILES/MILTER_README b/postfix/README_FILES/MILTER_README
index 469144924..f0094f25f 100644
--- a/postfix/README_FILES/MILTER_README
+++ b/postfix/README_FILES/MILTER_README
@@ -262,10 +262,12 @@ MMiilltteerr pprroottooccooll vveerrssiioonn
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
-version is 2. Other protocol versions are 3 and 4 (Postfix 2.3 and later), and
-6 (Postfix 2.5 an later).
+version is 6 (before Postfix 2.6 the default version is 2).
/etc/postfix/main.cf:
+ # Postfix >= 2.6
+ milter_protocol = 6
+ # 2.3 <= Postfix <= 2.5
milter_protocol = 2
If the Postfix milter_protocol setting specifies a too low version, the
@@ -313,8 +315,10 @@ with before-queue filtering.
SSeennddmmaaiill mmaaccrroo eemmuullaattiioonn
Postfix emulates a limited number of Sendmail macros, as shown in the table.
-Different macros are available at different SMTP protocol stages (EOH = end-of-
-header, EOM = end-of-message); their availability is not always the same as in
+Some macro values depend on whether a recipient is rejected (rejected
+recipients are available on request by the Milter application). Different
+macros are available at different SMTP protocol stages (EOH = end-of-header,
+EOM = end-of-message); their availability is not always the same as in
Sendmail. See the workarounds section below for solutions.
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
@@ -338,15 +342,18 @@ Sendmail. See the workarounds section below for solutions.
|{client_connections}|CONNECT |Connection concurrency for|
| | |this client |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
- | | |Client hostname, "unknown"|
- |{client_name} |Always |when lookup or |
- | | |verification fails |
+ | | |Client hostname |
+ | | |When address -> name |
+ |{client_name} |Always |lookup or name -> address |
+ | | |verification fails: |
+ | | |"unknown" |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{client_port} |Always (Postfix >=2.5) |Client TCP port |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
- | | |Client name from reverse |
- |{client_ptr} |CONNECT, HELO, MAIL, DATA|lookup, "unknown" when |
- | | |lookup fails |
+ | | |Client name from address -|
+ |{client_ptr} |CONNECT, HELO, MAIL, DATA|> name lookup |
+ | | |When address -> name |
+ | | |lookup fails: "unknown" |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{cert_issuer} |HELO, MAIL, DATA, EOH, |TLS client certificate |
| |EOM |issuer |
@@ -365,7 +372,25 @@ Sendmail. See the workarounds section below for solutions.
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{mail_addr} |MAIL |Sender address |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
- |{rcpt_addr} |RCPT |Recipient address |
+ |{mail_host} |MAIL (Postfix >= 2.6) |Sender next-hop |
+ | | |destination |
+ |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
+ |{mail_mailer} |MAIL (Postfix >= 2.6) |Sender mail delivery |
+ | | |transport |
+ |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
+ | | |Recipient address |
+ |{rcpt_addr} |RCPT |With rejected recipient: |
+ | | |descriptive text |
+ |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
+ | | |Recipient next-hop |
+ |{rcpt_host} |RCPT (Postfix >= 2.6) |destination |
+ | | |With rejected recpient: |
+ | | |enhanced status code |
+ |_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
+ | | |Recipient mail delivery |
+ |{rcpt_mailer} |RCPT (Postfix >= 2.6) |transport |
+ | | |With rejected recipient: |
+ | | |"error" |
|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _|_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ |
|{tls_version} |HELO, MAIL, DATA, EOH, |TLS protocol version |
| |EOM | |
@@ -494,26 +519,21 @@ limitations will be removed as the implementation is extended over time. Of
course the usual limitations of before-queue filtering will always apply. See
the CONTENT_INSPECTION_README document for a discussion.
- * Postfix version 2.3 introduces support for Sendmail 8 milter protocol
- versions 2, 3 and 4; Postfix version 2.5 adds support for protocol version
- 6, which is available with Sendmail 8.14. Support for other protocol types
- or protocol versions may be added later.
-
- * For applications that are written in C, you need to use the Sendmail
- libmilter library. A Postfix replacement may be provided in the future.
+ * For Milter applications that are written in C, you need to use the Sendmail
+ libmilter library.
* There are TWO sets of mail filters: filters that are used for SMTP mail
only (specified with the smtpd_milters parameter), and filters for non-SMTP
mail (specified with the non_smtpd_milters parameter). The non-SMTP filters
are primarily for local submissions.
- * When mail is filtered by non-SMTP filters, the Postfix cleanup(8) server
- has to simulate the SMTP client CONNECT and DISCONNECT events, and the SMTP
- client EHLO, MAIL FROM, RCPT TO and DATA commands. This works as expected,
- with only one exception: non-SMTP filters must not REJECT or TEMPFAIL
- simulated RCPT TO commands. When a non-SMTP filter REJECTs or TEMPFAILs a
- recipient, Postfix will report a configuration error, and mail will stay in
- the queue.
+ o When mail is filtered by non-SMTP filters, the Postfix cleanup(8)
+ server has to simulate the SMTP client CONNECT and DISCONNECT events,
+ and the SMTP client EHLO, MAIL FROM, RCPT TO and DATA commands. This
+ works as expected, with only one exception: non-SMTP filters must not
+ REJECT or TEMPFAIL simulated RCPT TO commands. When a non-SMTP filter
+ REJECTs or TEMPFAILs a recipient, Postfix will report a configuration
+ error, and mail will stay in the queue.
* Postfix currently does not apply content filters to mail that is forwarded
or aliased internally, or to mail that is generated internally such as
@@ -525,20 +545,43 @@ the CONTENT_INSPECTION_README document for a discussion.
command information; they have no access to the message header or body, and
cannot make modifications to the message or to the envelope.
- * Postfix 2.3 does not support Milter requests to replace the message body.
- Milter applications that request this unsupported operation will log a
- warning like this:
+ * Postfix version 2.6 implements all Sendmail 8.14 Milter features, except it
+ ignores the optional ESMTP command parameters with requests to replace the
+ sender (SMFIR_CHGFROM), or to append a recipient (SMFIR_ADDRCPT_PAR). When
+ a Milter application supplies ESMTP command parameters, these are logged as
+ follows:
- application name: st_optionneg[134563840]: 0x3d does not fulfill action
- requirements 0x1e
+ postfix/cleanup[40629]: warning: 100B22B3293: cleanup_chg_from: ignoring
+ ESMTP arguments "whatever"
- The solution is to use Postfix version 2.4 or later.
+ Specify "milter_protocol = 6" to enable all available Sendmail 8.14 and
+ earlier Milter features.
- * Postfix version 2.5 implements the Sendmail 8.14 features except:
+ * Postfix version 2.5 implements all Sendmail 8.14 Milter features except:
SMFIP_RCPT_REJ (report rejected recipients to the mail filter),
SMFIR_CHGFROM (replace sender, with optional ESMTP command parameters), and
SMFIR_ADDRCPT_PAR (add recipient, with optional ESMTP command parameters).
+ Specify "milter_protocol = 6" to enable all available Sendmail 8.14 and
+ earlier Milter features.
+
+ * Postfix 2.4 implements all Sendmail 8.13 Milter features.
+
+ Specify "milter_protocol = 4" to enable all available Sendmail 8.13 and
+ earlier Milter features.
+
+ * Postfix 2.3 implements all Sendmail 8.13 Milter features except requests to
+ replace the message body. Milter applications that request this unsupported
+ operation will log a warning like
+
+ application name: st_optionneg[134563840]: 0x3d does not fulfill action
+ requirements 0x1e
+
+ The solution is to use Postfix version 2.4 or later.
+
+ Specify "milter_protocol = 4" to enable all available Sendmail 8.13 and
+ earlier Milter features.
+
* Most Milter configuration options are global. Future Postfix versions may
support per-Milter timeouts, per-Milter error handling, etc.
diff --git a/postfix/README_FILES/SMTPD_ACCESS_README b/postfix/README_FILES/SMTPD_ACCESS_README
index 9bdc8874d..f2c1c4579 100644
--- a/postfix/README_FILES/SMTPD_ACCESS_README
+++ b/postfix/README_FILES/SMTPD_ACCESS_README
@@ -136,8 +136,8 @@ Each restriction list is evaluated from left to right until some restriction
produces a result of PERMIT, REJECT or DEFER (try again later). The end of the
list is equivalent to a PERMIT result. By placing a PERMIT restriction before a
REJECT restriction you can make exceptions for specific clients or users. This
-is called whitelisting; the last example above allows mail from local networks
-but otherwise rejects mail to arbitrary destinations.
+is called whitelisting; the fourth example above allows mail from local
+networks but otherwise rejects mail to arbitrary destinations.
The table below summarizes the purpose of each SMTP access restriction list.
All lists use the exact same syntax; they differ only in the time of evaluation
diff --git a/postfix/README_FILES/TLS_README b/postfix/README_FILES/TLS_README
index a408a86c5..9102c6a48 100644
--- a/postfix/README_FILES/TLS_README
+++ b/postfix/README_FILES/TLS_README
@@ -1692,7 +1692,7 @@ Example:
smtp_tls_mandatory_protocols = !SSLv2
# Also available with Postfix >= 2.6:
smtp_tls_ciphers = export
- smtp_tls_protocols =
+ smtp_tls_protocols = !SSLv2
CClliieenntt--ssiiddee SSMMTTPPSS ssuuppppoorrtt
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index bad090302..d3674c1b9 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -11,6 +11,54 @@ instead, a new snapshot is released.
The mail_release_date configuration parameter (format: yyyymmdd)
specifies the release date of a stable release or snapshot release.
+Incompatibility with snapshot 20090428
+======================================
+
+The Postfix SMTP client(!) no longer tries to use the obsolete SSLv2
+protocol by default, as this may prevent the use of modern SSL
+features. Lack of SSLv2 support should never be a problem, since
+SSLv3 was defined in 1996, and TLSv1 in 2006, but you can undo the
+change by specifying empty main.cf values for smtp_tls_protocols
+and lmtp_tls_protocols. The Postfix SMTP server maintains SSLv2
+support for backwards compatibility with ancient clients.
+
+The default Milter protocol version is increased from 2 to 6; this
+enables all available features up to and including Sendmail 8.14.0.
+The new milter_protocol setting may break compatibility with older
+Milter libraries or applications, and may cause Postfix to log
+warning messages such as:
+
+ postfix/smtpd[21045]: warning: milter inet:host:port: can't read packet
+ header: Unknown error : 0
+ postfix/cleanup[15190]: warning: milter inet:host:port: can't read packet
+ header: Success
+
+To restore compatibility, specify "milter_protocol = 2" in main.cf.
+
+Major changes with snapshot 20090428
+====================================
+
+The following improvements have been made to the Milter implementation:
+
+- Improved compatibility of the {mail_addr} and {rcpt_addr} macros.
+
+- Support for the {mail_host}, {mail_mailer}, {rcpt_host} and
+{rcpt_mailer} macros.
+
+- Milter applications can now request rejected recipients with the
+SMFIP_RCPT_REJ feature. Rejected recipients are reported with
+{rcpt_mailer} = "error", {rcpt_host} = enhanced status code, and
+{rcpt_addr} = descriptive text. This feature requires "milter_protocol
+= 6" or higher (default as of Postfix 2.6).
+
+- Milters can now replace the envelope sender address with the
+SMFIR_CHGFROM request, and can add recipients with SMFIR_ADDRCPT_PAR.
+These implementations currently ignore ESMTP command parameters
+with a warning message as follows:
+
+ postfix/cleanup[40629]: warning: 100B22B3293: cleanup_chg_from:
+ ignoring ESMTP arguments "whatever"
+
Incompatibility with snapshot 20090330
======================================
diff --git a/postfix/html/FILTER_README.html b/postfix/html/FILTER_README.html
index 0bb4332d0..f1a6c12c8 100644
--- a/postfix/html/FILTER_README.html
+++ b/postfix/html/FILTER_README.html
@@ -356,7 +356,8 @@ to the "filter" user. This is where the content filtering script
is supposed to store its temporary files.
Configure Postfix to deliver mail to the content filter
-with the pipe(8) delivery agent.
+with the pipe(8) delivery agent (see the pipe(8) manpage for a
+description of the command syntax below).
/etc/postfix/master.cf:
@@ -365,14 +366,16 @@ with the pipe(8) delivery agent.
# (yes) (yes) (yes) (never) (100)
# =============================================================
filter unix - n n - 10 pipe
- flags=Rq user=filter argv=/path/to/script -f ${sender} -- ${recipient}
+ flags=Rq user=filter null_sender=
+ argv=/path/to/script -f ${sender} -- ${recipient}
This runs up to 10 content filters in parallel. Instead of a
limit of 10 concurrent processes, use whatever process limit is
feasible for your machine. Content inspection software can gobble
up a lot of system resources, so you don't want to have too much
-of it running at the same time.
+of it running at the same time. The empty null_sender setting is
+required with Postfix 2.3 and later.
To turn on content filtering for mail arriving via SMTP
only, append "-o content_filter=filter:dummy" to the master.cf
diff --git a/postfix/html/MILTER_README.html b/postfix/html/MILTER_README.html
index c8539c523..aa2bbf206 100644
--- a/postfix/html/MILTER_README.html
+++ b/postfix/html/MILTER_README.html
@@ -442,12 +442,15 @@ in the "hold" queue, and is availabl
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 version is 2. Other protocol versions are
-3 and 4 (Postfix 2.3 and later), and 6 (Postfix 2.5 an later).
+should use. The default version is 6 (before Postfix 2.6 the default
+version is 2).
/etc/postfix/main.cf:
+ # Postfix ≥ 2.6
+ milter_protocol = 6
+ # 2.3 ≤ Postfix ≤ 2.5
milter_protocol = 2
@@ -515,7 +518,9 @@ times. This is an inherent problem with before-queue filtering.
Postfix emulates a limited number of Sendmail macros, as shown
-in the table. Different macros are available at different SMTP
+in the table. Some macro values depend on whether a recipient is
+rejected (rejected recipients are available on request by the Milter
+application). Different macros are available at different SMTP
protocol stages (EOH = end-of-header, EOM = end-of-message); their
availability is not
always the same as in Sendmail. See the
| {client_connections} | CONNECT |
Connection concurrency for this client |
- | {client_name} | Always | Client hostname,
-"unknown" when lookup or verification fails |
+ | {client_name} | Always | Client hostname
+ When address → name lookup or name → address
+verification fails: "unknown" |
| {client_port} | Always (Postfix ≥2.5) |
Client TCP port |
| {client_ptr} | CONNECT, HELO, MAIL, DATA |
- Client name from reverse lookup, "unknown" when lookup fails
- |
+
Client name from address → name lookup When address
+→ name lookup fails: "unknown" |
| {cert_issuer} | HELO, MAIL, DATA, EOH, EOM |
TLS client certificate issuer |
@@ -580,11 +586,25 @@ cipher
| {mail_addr} | MAIL | Sender address
|
+ | {mail_host} | MAIL (Postfix ≥ 2.6) |
+Sender next-hop destination |
+
+ | {mail_mailer} | MAIL (Postfix ≥ 2.6) |
+ Sender mail delivery transport |
+
| {rcpt_addr} | RCPT | Recipient address
- |
+
With rejected recipient: descriptive text
+
+ | {rcpt_host} | RCPT (Postfix ≥ 2.6) |
+Recipient next-hop destination With rejected recpient: enhanced
+status code |
+
+ | {rcpt_mailer} | RCPT (Postfix ≥ 2.6) |
+ Recipient mail delivery transport With rejected recipient:
+"error" |
- | {tls_version} | HELO, MAIL, DATA, EOH, EOM |
-TLS protocol version |
+ | {tls_version} | HELO, MAIL, DATA, EOH, EOM |
+ TLS protocol version |
| v | Always | value of milter_macro_v
|
@@ -777,15 +797,8 @@ a discussion.
--
Postfix version 2.3 introduces support for Sendmail 8
-milter protocol versions 2, 3 and 4; Postfix version 2.5 adds support
-for protocol version 6, which is available with Sendmail 8.14.
-Support for other protocol types or protocol versions may be added
-later.
-
- -
For applications that are written in C, you need to use
-the Sendmail libmilter library. A Postfix replacement may be
-provided in the future.
+ -
For Milter applications that are written in C, you need
+to use the Sendmail libmilter library.
-
There are TWO sets of mail filters: filters that are used
for SMTP mail only (specified with the smtpd_milters parameter),
@@ -793,6 +806,8 @@ and filters for non-SMTP mail (specified with the cleanup(8) server has to simulate the SMTP client CONNECT and
DISCONNECT events, and the SMTP client EHLO, MAIL FROM, RCPT TO and
@@ -802,6 +817,8 @@ commands. When a non-SMTP filter REJECTs or TEMPFAILs a recipient,
Postfix will report a configuration error, and mail will stay in
the queue.
+
+
Postfix currently does not apply content filters to mail
that is forwarded or aliased internally, or to mail that is generated
internally such as bounces or Postmaster notifications. This may
@@ -814,9 +831,37 @@ only to the SMTP command information; they have no access to the
message header or body, and cannot make modifications to the message
or to the envelope.
- Postfix 2.3 does not support Milter requests to replace
-the message body. Milter applications that request this unsupported
-operation will log a warning like this:
+ Postfix version 2.6 implements all Sendmail 8.14 Milter
+features, except it ignores the optional ESMTP command parameters
+with requests to replace the sender (SMFIR_CHGFROM), or to append
+a recipient (SMFIR_ADDRCPT_PAR). When a Milter application supplies
+ESMTP command parameters, these are logged as follows:
+
+
+postfix/cleanup[40629]: warning: 100B22B3293: cleanup_chg_from: ignoring ESMTP arguments "whatever"
+
+
+ Specify "milter_protocol = 6" to enable all available Sendmail
+8.14 and earlier Milter features.
+
+ Postfix version 2.5 implements all Sendmail 8.14 Milter
+features except: SMFIP_RCPT_REJ (report rejected recipients to the
+mail filter), SMFIR_CHGFROM (replace sender, with optional ESMTP
+command parameters), and SMFIR_ADDRCPT_PAR (add recipient, with
+optional ESMTP command parameters).
+
+ Specify "milter_protocol = 6" to enable all available Sendmail
+8.14 and earlier Milter features.
+
+ Postfix 2.4 implements all Sendmail 8.13 Milter features.
+
+
+ Specify "milter_protocol = 4" to enable all available Sendmail
+8.13 and earlier Milter features.
+
+ Postfix 2.3 implements all Sendmail 8.13 Milter features
+except requests to replace the message body. Milter applications
+that request this unsupported operation will log a warning like
@@ -826,11 +871,8 @@ operation will log a warning like this:
The solution is to use Postfix version 2.4 or later.
-
Postfix version 2.5 implements the Sendmail 8.14 features
-except: SMFIP_RCPT_REJ (report rejected recipients to the mail
-filter), SMFIR_CHGFROM (replace sender, with optional ESMTP command
-parameters), and SMFIR_ADDRCPT_PAR (add recipient, with optional
-ESMTP command parameters).
+
Specify "milter_protocol = 4" to enable all available Sendmail
+8.13 and earlier Milter features.
Most Milter configuration options are global. Future Postfix
versions may support per-Milter timeouts, per-Milter error handling,
diff --git a/postfix/html/SMTPD_ACCESS_README.html b/postfix/html/SMTPD_ACCESS_README.html
index 0f8ae5237..9476da6d7 100644
--- a/postfix/html/SMTPD_ACCESS_README.html
+++ b/postfix/html/SMTPD_ACCESS_README.html
@@ -193,8 +193,8 @@ some restriction produces a result of PERMIT, REJECT or DEFER (try
again later). The end of the list is equivalent to a PERMIT result.
By placing a PERMIT restriction before a REJECT restriction you
can make exceptions for specific clients or users. This is called
-whitelisting; the last example above allows mail from local networks
-but otherwise rejects mail to arbitrary destinations.
+whitelisting; the fourth example above allows mail from local
+networks but otherwise rejects mail to arbitrary destinations.
The table below summarizes the purpose of each SMTP access
restriction list. All lists use the exact same syntax; they differ
diff --git a/postfix/html/TLS_README.html b/postfix/html/TLS_README.html
index f056f12db..fa6571940 100644
--- a/postfix/html/TLS_README.html
+++ b/postfix/html/TLS_README.html
@@ -2277,7 +2277,7 @@ the SSL/TLS protocols used with opportunistic TLS.
smtp_tls_mandatory_protocols = !SSLv2
# Also available with Postfix ≥ 2.6:
smtp_tls_ciphers = export
- smtp_tls_protocols =
+ smtp_tls_protocols = !SSLv2
diff --git a/postfix/html/cleanup.8.html b/postfix/html/cleanup.8.html
index 0b0fa7aa5..9c6196aff 100644
--- a/postfix/html/cleanup.8.html
+++ b/postfix/html/cleanup.8.html
@@ -154,13 +154,14 @@ CLEANUP(8) CLEANUP(8)
mail that does not arrive via the Postfix smtpd(8)
server.
- milter_protocol (2)
+ milter_protocol (6)
The mail filter protocol version and optional pro-
tocol extensions for communication with a Milter
- (mail filter) application.
+ application; prior to Postfix 2.6 the default pro-
+ tocol is 2.
milter_default_action (tempfail)
- The default action when a Milter (mail filter)
+ The default action when a Milter (mail filter)
application is unavailable or mis-configured.
milter_macro_daemon_name ($myhostname)
@@ -172,55 +173,55 @@ CLEANUP(8) CLEANUP(8)
cations.
milter_connect_timeout (30s)
- The time limit for connecting to a Milter (mail
- filter) application, and for negotiating protocol
+ The time limit for connecting to a Milter (mail
+ filter) application, and for negotiating protocol
options.
milter_command_timeout (30s)
- The time limit for sending an SMTP command to a
+ The time limit for sending an SMTP command to a
Milter (mail filter) application, and for receiving
the response.
milter_content_timeout (300s)
- The time limit for sending message content to a
+ The time limit for sending message content to a
Milter (mail filter) application, and for receiving
the response.
milter_connect_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
- applications after completion of an SMTP connec-
+ The macros that are sent to Milter (mail filter)
+ applications after completion of an SMTP connec-
tion.
milter_helo_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the SMTP HELO or EHLO command.
milter_mail_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the SMTP MAIL FROM command.
milter_rcpt_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the SMTP RCPT TO command.
milter_data_macros (see 'postconf -d' output)
- The macros that are sent to version 4 or higher
- Milter (mail filter) applications after the SMTP
+ The macros that are sent to version 4 or higher
+ Milter (mail filter) applications after the SMTP
DATA command.
milter_unknown_command_macros (see 'postconf -d' output)
- The macros that are sent to version 3 or higher
- Milter (mail filter) applications after an unknown
+ The macros that are sent to version 3 or higher
+ Milter (mail filter) applications after an unknown
SMTP command.
milter_end_of_data_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the message end-of-data.
Available in Postfix version 2.5 and later:
milter_end_of_header_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the end of the message header.
MIME PROCESSING CONTROLS
@@ -238,27 +239,27 @@ CLEANUP(8) CLEANUP(8)
will handle.
strict_8bitmime (no)
- Enable both strict_7bit_headers and strict_8bit-
+ Enable both strict_7bit_headers and strict_8bit-
mime_body.
strict_7bit_headers (no)
Reject mail with 8-bit text in message headers.
strict_8bitmime_body (no)
- Reject 8-bit message body text without 8-bit MIME
+ Reject 8-bit message body text without 8-bit MIME
content encoding information.
strict_mime_encoding_domain (no)
Reject mail with invalid Content-Transfer-Encoding:
- information for the message/* or multipart/* MIME
+ information for the message/* or multipart/* MIME
content types.
Available in Postfix version 2.5 and later:
detect_8bit_encoding_header (yes)
Automatically detect 8BITMIME body content by look-
- ing at Content-Transfer-Encoding: message headers;
- historically, this behavior was hard-coded to be
+ ing at Content-Transfer-Encoding: message headers;
+ historically, this behavior was hard-coded to be
"always on".
AUTOMATIC BCC RECIPIENT CONTROLS
@@ -266,31 +267,31 @@ CLEANUP(8) CLEANUP(8)
mail enters the mail system:
always_bcc (empty)
- Optional address that receives a "blind carbon
+ Optional address that receives a "blind carbon
copy" of each message that is received by the Post-
fix mail system.
Available in Postfix version 2.1 and later:
sender_bcc_maps (empty)
- Optional BCC (blind carbon-copy) address lookup
+ Optional BCC (blind carbon-copy) address lookup
tables, indexed by sender address.
recipient_bcc_maps (empty)
- Optional BCC (blind carbon-copy) address lookup
+ Optional BCC (blind carbon-copy) address lookup
tables, indexed by recipient address.
ADDRESS TRANSFORMATION CONTROLS
- Address rewriting is delegated to the trivial-rewrite(8)
- daemon. The cleanup(8) server implements table driven
+ Address rewriting is delegated to the trivial-rewrite(8)
+ daemon. The cleanup(8) server implements table driven
address mapping.
empty_address_recipient (MAILER-DAEMON)
- The recipient of mail addressed to the null
+ The recipient of mail addressed to the null
address.
canonical_maps (empty)
- Optional address mapping lookup tables for message
+ Optional address mapping lookup tables for message
headers and envelopes.
recipient_canonical_maps (empty)
@@ -301,49 +302,49 @@ CLEANUP(8) CLEANUP(8)
Optional address mapping lookup tables for envelope
and header sender addresses.
- masquerade_classes (envelope_sender, header_sender,
+ masquerade_classes (envelope_sender, header_sender,
header_recipient)
What addresses are subject to address masquerading.
masquerade_domains (empty)
- Optional list of domains whose subdomain structure
+ Optional list of domains whose subdomain structure
will be stripped off in email addresses.
masquerade_exceptions (empty)
- Optional list of user names that are not subjected
- to address masquerading, even when their address
+ Optional list of user names that are not subjected
+ to address masquerading, even when their address
matches $masquerade_domains.
propagate_unmatched_extensions (canonical, virtual)
- What address lookup tables copy an address exten-
+ What address lookup tables copy an address exten-
sion from the lookup key to the lookup result.
Available before Postfix version 2.0:
virtual_maps (empty)
Optional lookup tables with a) names of domains for
- which all addresses are aliased to addresses in
- other local or remote domains, and b) addresses
- that are aliased to addresses in other local or
+ which all addresses are aliased to addresses in
+ other local or remote domains, and b) addresses
+ that are aliased to addresses in other local or
remote domains.
Available in Postfix version 2.0 and later:
virtual_alias_maps ($virtual_maps)
- Optional lookup tables that alias specific mail
- addresses or domains to other local or remote
+ Optional lookup tables that alias specific mail
+ addresses or domains to other local or remote
address.
Available in Postfix version 2.2 and later:
- canonical_classes (envelope_sender, envelope_recipient,
+ canonical_classes (envelope_sender, envelope_recipient,
header_sender, header_recipient)
- What addresses are subject to canonical_maps
+ What addresses are subject to canonical_maps
address mapping.
recipient_canonical_classes (envelope_recipient,
header_recipient)
- What addresses are subject to recipient_canoni-
+ What addresses are subject to recipient_canoni-
cal_maps address mapping.
sender_canonical_classes (envelope_sender, header_sender)
@@ -351,15 +352,15 @@ CLEANUP(8) CLEANUP(8)
address mapping.
remote_header_rewrite_domain (empty)
- Don't rewrite message headers from remote clients
+ Don't rewrite message headers from remote clients
at all when this parameter is empty; otherwise, re-
- write message headers and append the specified
+ write message headers and append the specified
domain name to incomplete addresses.
RESOURCE AND RATE CONTROLS
duplicate_filter_limit (1000)
- The maximal number of addresses remembered by the
- address duplicate filter for aliases(5) or vir-
+ The maximal number of addresses remembered by the
+ address duplicate filter for aliases(5) or vir-
tual(5) alias expansion, or for showq(8) queue dis-
plays.
@@ -368,16 +369,16 @@ CLEANUP(8) CLEANUP(8)
message header.
hopcount_limit (50)
- The maximal number of Received: message headers
+ The maximal number of Received: message headers
that is allowed in the primary message headers.
in_flow_delay (1s)
- Time to pause before accepting a new message, when
+ Time to pause before accepting a new message, when
the message arrival rate exceeds the message deliv-
ery rate.
message_size_limit (10240000)
- The maximal size in bytes of a message, including
+ The maximal size in bytes of a message, including
envelope information.
Available in Postfix version 2.0 and later:
@@ -395,35 +396,35 @@ CLEANUP(8) CLEANUP(8)
will handle.
queue_file_attribute_count_limit (100)
- The maximal number of (name=value) attributes that
+ The maximal number of (name=value) attributes that
may be stored in a Postfix queue file.
Available in Postfix version 2.1 and later:
virtual_alias_expansion_limit (1000)
- The maximal number of addresses that virtual alias
+ The maximal number of addresses that virtual alias
expansion produces from each original recipient.
virtual_alias_recursion_limit (1000)
- The maximal nesting depth of virtual alias expan-
+ The maximal nesting depth of virtual alias expan-
sion.
MISCELLANEOUS CONTROLS
config_directory (see 'postconf -d' output)
- The default location of the Postfix main.cf and
+ The default location of the Postfix main.cf and
master.cf configuration files.
daemon_timeout (18000s)
- How much time a Postfix daemon process may take to
- handle a request before it is terminated by a
+ How much time a Postfix daemon process may take to
+ handle a request before it is terminated by a
built-in watchdog timer.
delay_logging_resolution_limit (2)
- The maximal number of digits after the decimal
+ The maximal number of digits after the decimal
point when logging sub-second delay values.
delay_warning_time (0h)
- The time after which the sender receives the mes-
+ The time after which the sender receives the mes-
sage headers of mail that is still queued.
ipc_timeout (3600s)
@@ -431,13 +432,13 @@ CLEANUP(8) CLEANUP(8)
over an internal communication channel.
max_idle (100s)
- The maximum amount of time that an idle Postfix
- daemon process waits for an incoming connection
+ The maximum amount of time that an idle Postfix
+ daemon process waits for an incoming connection
before terminating voluntarily.
max_use (100)
- The maximal number of incoming connections that a
- Postfix daemon process will service before termi-
+ The maximal number of incoming connections that a
+ Postfix daemon process will service before termi-
nating voluntarily.
myhostname (see 'postconf -d' output)
@@ -445,19 +446,19 @@ CLEANUP(8) CLEANUP(8)
myorigin ($myhostname)
The domain name that locally-posted mail appears to
- come from, and that locally posted mail is deliv-
+ come from, and that locally posted mail is deliv-
ered to.
process_id (read-only)
- The process ID of a Postfix command or daemon
+ The process ID of a Postfix command or daemon
process.
process_name (read-only)
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
queue_directory (see 'postconf -d' output)
- The location of the Postfix top-level queue direc-
+ The location of the Postfix top-level queue direc-
tory.
soft_bounce (no)
@@ -468,14 +469,14 @@ CLEANUP(8) CLEANUP(8)
The syslog facility of Postfix logging.
syslog_name (see 'postconf -d' output)
- The mail system name that is prepended to the
- process name in syslog records, so that "smtpd"
+ The mail system name that is prepended to the
+ process name in syslog records, so that "smtpd"
becomes, for example, "postfix/smtpd".
Available in Postfix version 2.1 and later:
enable_original_recipient (yes)
- Enable support for the X-Original-To message
+ Enable support for the X-Original-To message
header.
FILES
@@ -499,7 +500,7 @@ CLEANUP(8) CLEANUP(8)
CONTENT_INSPECTION_README content inspection
LICENSE
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
AUTHOR(S)
diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html
index f435276cb..f6e9232a9 100644
--- a/postfix/html/lmtp.8.html
+++ b/postfix/html/lmtp.8.html
@@ -517,7 +517,7 @@ SMTP(8) SMTP(8)
Available in Postfix version 2.6 and later:
- smtp_tls_protocols (empty)
+ smtp_tls_protocols (!SSLv2)
List of TLS protocols that the Postfix SMTP client
will exclude or include with opportunistic TLS
encryption.
diff --git a/postfix/html/local.8.html b/postfix/html/local.8.html
index 363755725..ff058f925 100644
--- a/postfix/html/local.8.html
+++ b/postfix/html/local.8.html
@@ -308,10 +308,6 @@ LOCAL(8) LOCAL(8)
ward+foo or in ~name/.forward, to the mailbox owned by the
user name, or it is sent back as undeliverable.
- In all cases the local(8) daemon prepends an optional
- `Delivered-To: header line with the final recipient
- address.
-
DELIVERY RIGHTS
Deliveries to external files and external commands are
made with the rights of the receiving user on whose behalf
diff --git a/postfix/html/pipe.8.html b/postfix/html/pipe.8.html
index 5589058d0..4ce64ec8b 100644
--- a/postfix/html/pipe.8.html
+++ b/postfix/html/pipe.8.html
@@ -183,13 +183,13 @@ PIPE(8) PIPE(8)
by naive software. For example, when the pipe(8)
daemon executes a command such as:
- command -f$sender -- $recipient (bad)
+ Wrong: command -f$sender -- $recipient
the command will mis-parse the -f option value when
the sender address is a null string. For correct
parsing, specify $sender as an argument by itself:
- command -f $sender -- $recipient (good)
+ Right: command -f $sender -- $recipient
This feature is available as of Postfix 2.3.
diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html
index 9ba2d0d9f..4098156e7 100644
--- a/postfix/html/postconf.5.html
+++ b/postfix/html/postconf.5.html
@@ -5697,10 +5697,11 @@ for a list of available macro names and their meanings.
milter_protocol
-(default: 2)
+(default: 6)
The mail filter protocol version and optional protocol extensions
-for communication with a Milter (mail filter) application. Postfix
+for communication with a Milter application; prior to Postfix 2.6
+the default protocol is 2. Postfix
sends this version number during the initial protocol handshake.
It should match the version number that is expected by the mail
filter application (or by its Milter library).
@@ -5710,14 +5711,15 @@ filter application (or by its Milter library).
- 2
- Use Sendmail 8 mail filter protocol version 2 (default
-as of Sendmail version 8.11).
+with Sendmail version 8.11 .. 8.13 and Postfix version 2.3 ..
+2.5).
3 Use Sendmail 8 mail filter protocol version 3.
4 Use Sendmail 8 mail filter protocol version 4.
6 Use Sendmail 8 mail filter protocol version 6 (default
-as of Sendmail version 8.14).
+with Sendmail version 8.14 and Postfix version 2.6).
@@ -9533,8 +9535,8 @@ introduced in Postfix 2.3. Starting with Postfix 2.3, and independently
of how the policy is specified, the smtp_tls_mandatory_ciphers and
smtp_tls_mandatory_protocols parameters apply when TLS encryption
is mandatory. Connections for which encryption is optional typically
-enable all "export" grade and better ciphers and all SSL/TLS protocols
-(see smtp_tls_ciphers and smtp_tls_protocols).
+enable all "export" grade and better ciphers (see smtp_tls_ciphers
+and smtp_tls_protocols).
As long as no secure DNS lookup mechanism is available, false
hostnames in MX or CNAME responses can change the server hostname
@@ -9689,12 +9691,12 @@ configurations in environments where DNS security is not assured.
smtp_tls_protocols
-(default: empty)
+(default: !SSLv2)
- List of TLS protocols that the Postfix SMTP client will exclude
-or include with opportunistic TLS encryption. This parameter SHOULD be
-left at its default empty value, allowing all protocols to be used with
-opportunistic TLS.
+ List of TLS protocols that the Postfix SMTP client will exclude or
+include with opportunistic TLS encryption. Starting with Postfix 2.6,
+the Postfix SMTP client will by default not use the obsolete SSLv2
+protocol.
In main.cf the values are separated by whitespace, commas or
colons. In the policy table (see smtp_tls_policy_maps) the only valid
@@ -9713,7 +9715,8 @@ they cannot be excluded using either syntax.
Example:
-smtp_tls_protocols = !SSLv2
+# TLSv1 only!
+smtp_tls_protocols = !SSLv2, !SSLv3
This feature is available in Postfix 2.6 and later.
@@ -9867,12 +9870,12 @@ Examples:
# Opportunistic TLS.
smtp_tls_security_level = may
# Postfix ≥ 2.6:
-# Do not tweak opportunistic ciphers or protocols unless it is essential
+# Do not tweak opportunistic ciphers unless it is essential
# to do so (if a security vulnerability is found in the SSL library that
# can be mitigated by disabling a particular protocol or raising the
# cipher grade from "export" to "low" or "medium").
smtp_tls_ciphers = export
-smtp_tls_protocols =
+smtp_tls_protocols = !SSLv2
diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html
index f435276cb..f6e9232a9 100644
--- a/postfix/html/smtp.8.html
+++ b/postfix/html/smtp.8.html
@@ -517,7 +517,7 @@ SMTP(8) SMTP(8)
Available in Postfix version 2.6 and later:
- smtp_tls_protocols (empty)
+ smtp_tls_protocols (!SSLv2)
List of TLS protocols that the Postfix SMTP client
will exclude or include with opportunistic TLS
encryption.
diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html
index 84256e063..836e9c09c 100644
--- a/postfix/html/smtpd.8.html
+++ b/postfix/html/smtpd.8.html
@@ -209,13 +209,14 @@ SMTPD(8) SMTPD(8)
A list of Milter (mail filter) applications for new
mail that arrives via the Postfix smtpd(8) server.
- milter_protocol (2)
+ milter_protocol (6)
The mail filter protocol version and optional pro-
tocol extensions for communication with a Milter
- (mail filter) application.
+ application; prior to Postfix 2.6 the default pro-
+ tocol is 2.
milter_default_action (tempfail)
- The default action when a Milter (mail filter)
+ The default action when a Milter (mail filter)
application is unavailable or mis-configured.
milter_macro_daemon_name ($myhostname)
@@ -227,169 +228,170 @@ SMTPD(8) SMTPD(8)
cations.
milter_connect_timeout (30s)
- The time limit for connecting to a Milter (mail
- filter) application, and for negotiating protocol
+ The time limit for connecting to a Milter (mail
+ filter) application, and for negotiating protocol
options.
milter_command_timeout (30s)
- The time limit for sending an SMTP command to a
+ The time limit for sending an SMTP command to a
Milter (mail filter) application, and for receiving
the response.
milter_content_timeout (300s)
- The time limit for sending message content to a
+ The time limit for sending message content to a
Milter (mail filter) application, and for receiving
the response.
milter_connect_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
- applications after completion of an SMTP connec-
+ The macros that are sent to Milter (mail filter)
+ applications after completion of an SMTP connec-
tion.
milter_helo_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the SMTP HELO or EHLO command.
milter_mail_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the SMTP MAIL FROM command.
milter_rcpt_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the SMTP RCPT TO command.
milter_data_macros (see 'postconf -d' output)
- The macros that are sent to version 4 or higher
- Milter (mail filter) applications after the SMTP
+ The macros that are sent to version 4 or higher
+ Milter (mail filter) applications after the SMTP
DATA command.
milter_unknown_command_macros (see 'postconf -d' output)
- The macros that are sent to version 3 or higher
- Milter (mail filter) applications after an unknown
+ The macros that are sent to version 3 or higher
+ Milter (mail filter) applications after an unknown
SMTP command.
milter_end_of_header_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the end of the message header.
milter_end_of_data_macros (see 'postconf -d' output)
- The macros that are sent to Milter (mail filter)
+ The macros that are sent to Milter (mail filter)
applications after the message end-of-data.
GENERAL CONTENT INSPECTION CONTROLS
- The following parameters are applicable for both built-in
+ The following parameters are applicable for both built-in
and external content filters.
Available in Postfix version 2.1 and later:
receive_override_options (empty)
- Enable or disable recipient validation, built-in
+ Enable or disable recipient validation, built-in
content filtering, or address mapping.
EXTERNAL CONTENT INSPECTION CONTROLS
- The following parameters are applicable for both before-
+ The following parameters are applicable for both before-
queue and after-queue content filtering.
Available in Postfix version 2.1 and later:
smtpd_authorized_xforward_hosts (empty)
- What SMTP clients are allowed to use the XFORWARD
+ What SMTP clients are allowed to use the XFORWARD
feature.
SASL AUTHENTICATION CONTROLS
- Postfix SASL support (RFC 4954) can be used to authenti-
- cate remote SMTP clients to the Postfix SMTP server, and
- to authenticate the Postfix SMTP client to a remote SMTP
+ Postfix SASL support (RFC 4954) can be used to authenti-
+ cate remote SMTP clients to the Postfix SMTP server, and
+ to authenticate the Postfix SMTP client to a remote SMTP
server. See the SASL_README document for details.
broken_sasl_auth_clients (no)
- Enable inter-operability with SMTP clients that
- implement an obsolete version of the AUTH command
+ Enable inter-operability with SMTP clients that
+ implement an obsolete version of the AUTH command
(RFC 4954).
smtpd_sasl_auth_enable (no)
- Enable SASL authentication in the Postfix SMTP
+ Enable SASL authentication in the Postfix SMTP
server.
smtpd_sasl_local_domain (empty)
- The name of the Postfix SMTP server's local SASL
+ The name of the Postfix SMTP server's local SASL
authentication realm.
smtpd_sasl_security_options (noanonymous)
- Postfix SMTP server SASL security options; as of
- Postfix 2.3 the list of available features depends
- on the SASL server implementation that is selected
+ Postfix SMTP server SASL security options; as of
+ Postfix 2.3 the list of available features depends
+ on the SASL server implementation that is selected
with smtpd_sasl_type.
smtpd_sender_login_maps (empty)
- Optional lookup table with the SASL login names
+ Optional lookup table with the SASL login names
that own sender (MAIL FROM) addresses.
Available in Postfix version 2.1 and later:
smtpd_sasl_exceptions_networks (empty)
- What remote SMTP clients the Postfix SMTP server
+ What remote SMTP clients the Postfix SMTP server
will not offer AUTH support to.
Available in Postfix version 2.1 and 2.2:
smtpd_sasl_application_name (smtpd)
- The application name that the Postfix SMTP server
+ The application name that the Postfix SMTP server
uses for SASL server initialization.
Available in Postfix version 2.3 and later:
smtpd_sasl_authenticated_header (no)
- Report the SASL authenticated user name in the
+ Report the SASL authenticated user name in the
smtpd(8) Received message header.
smtpd_sasl_path (smtpd)
- Implementation-specific information that the Post-
- fix SMTP server passes through to the SASL plug-in
- implementation that is selected with
+ Implementation-specific information that the Post-
+ fix SMTP server passes through to the SASL plug-in
+ implementation that is selected with
smtpd_sasl_type.
smtpd_sasl_type (cyrus)
- The SASL plug-in type that the Postfix SMTP server
+ The SASL plug-in type that the Postfix SMTP server
should use for authentication.
Available in Postfix version 2.5 and later:
cyrus_sasl_config_path (empty)
- Search path for Cyrus SASL application configura-
- tion files, currently used only to locate the
+ Search path for Cyrus SASL application configura-
+ tion files, currently used only to locate the
$smtpd_sasl_path.conf file.
STARTTLS SUPPORT CONTROLS
- Detailed information about STARTTLS configuration may be
+ Detailed information about STARTTLS configuration may be
found in the TLS_README document.
smtpd_tls_security_level (empty)
- The SMTP TLS security level for the Postfix SMTP
- server; when a non-empty value is specified, this
+ The SMTP TLS security level for the Postfix SMTP
+ server; when a non-empty value is specified, this
overrides the obsolete parameters smtpd_use_tls and
smtpd_enforce_tls.
smtpd_sasl_tls_security_options ($smtpd_sasl_secu-
rity_options)
- The SASL authentication security options that the
- Postfix SMTP server uses for TLS encrypted SMTP
+ The SASL authentication security options that the
+ Postfix SMTP server uses for TLS encrypted SMTP
sessions.
smtpd_starttls_timeout (300s)
- The time limit for Postfix SMTP server write and
- read operations during TLS startup and shutdown
+ The time limit for Postfix SMTP server write and
+ read operations during TLS startup and shutdown
handshake procedures.
smtpd_tls_CAfile (empty)
- A file containing (PEM format) CA certificates of
- root CAs trusted to sign either remote SMTP client
+ A file containing (PEM format) CA certificates of
+ root CAs trusted to sign either remote SMTP client
certificates or intermediate CA certificates.
- smtpd_tls_CAfile (empty)
- A file containing (PEM format) CA certificates of
- root CAs trusted to sign either remote SMTP client
- certificates or intermediate CA certificates.
+ smtpd_tls_CApath (empty)
+ A directory containing (PEM format) CA certificates
+ of root CAs trusted to sign either remote SMTP
+ client certificates or intermediate CA certifi-
+ cates.
smtpd_tls_always_issue_session_ids (yes)
Force the Postfix SMTP server to issue a TLS ses-
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index 6ad3b76fe..32d879201 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -3162,9 +3162,10 @@ after the SMTP MAIL FROM command. See MILTER_README
for a list of available macro names and their meanings.
.PP
This feature is available in Postfix 2.3 and later.
-.SH milter_protocol (default: 2)
+.SH milter_protocol (default: 6)
The mail filter protocol version and optional protocol extensions
-for communication with a Milter (mail filter) application. Postfix
+for communication with a Milter application; prior to Postfix 2.6
+the default protocol is 2. Postfix
sends this version number during the initial protocol handshake.
It should match the version number that is expected by the mail
filter application (or by its Milter library).
@@ -3172,14 +3173,15 @@ filter application (or by its Milter library).
Protocol versions:
.IP "2"
Use Sendmail 8 mail filter protocol version 2 (default
-as of Sendmail version 8.11).
+with Sendmail version 8.11 .. 8.13 and Postfix version 2.3 ..
+2.5).
.IP "3"
Use Sendmail 8 mail filter protocol version 3.
.IP "4"
Use Sendmail 8 mail filter protocol version 4.
.IP "6"
Use Sendmail 8 mail filter protocol version 6 (default
-as of Sendmail version 8.14).
+with Sendmail version 8.14 and Postfix version 2.6).
.PP
Protocol extensions:
.IP "no_header_reply"
@@ -5617,8 +5619,8 @@ introduced in Postfix 2.3. Starting with Postfix 2.3, and independently
of how the policy is specified, the smtp_tls_mandatory_ciphers and
smtp_tls_mandatory_protocols parameters apply when TLS encryption
is mandatory. Connections for which encryption is optional typically
-enable all "export" grade and better ciphers and all SSL/TLS protocols
-(see smtp_tls_ciphers and smtp_tls_protocols).
+enable all "export" grade and better ciphers (see smtp_tls_ciphers
+and smtp_tls_protocols).
.PP
As long as no secure DNS lookup mechanism is available, false
hostnames in MX or CNAME responses can change the server hostname
@@ -5761,11 +5763,11 @@ DNS forgery. Do not use the \fBhostname\fR strategy for secure-channel
configurations in environments where DNS security is not assured.
.PP
This feature is available in Postfix 2.3 and later.
-.SH smtp_tls_protocols (default: empty)
-List of TLS protocols that the Postfix SMTP client will exclude
-or include with opportunistic TLS encryption. This parameter SHOULD be
-left at its default empty value, allowing all protocols to be used with
-opportunistic TLS.
+.SH smtp_tls_protocols (default: !SSLv2)
+List of TLS protocols that the Postfix SMTP client will exclude or
+include with opportunistic TLS encryption. Starting with Postfix 2.6,
+the Postfix SMTP client will by default not use the obsolete SSLv2
+protocol.
.PP
In main.cf the values are separated by whitespace, commas or
colons. In the policy table (see smtp_tls_policy_maps) the only valid
@@ -5786,7 +5788,8 @@ Example:
.nf
.na
.ft C
-smtp_tls_protocols = !SSLv2
+# TLSv1 only!
+smtp_tls_protocols = !SSLv2, !SSLv3
.fi
.ad
.ft R
@@ -5926,12 +5929,12 @@ smtp_tls_security_level = none
# Opportunistic TLS.
smtp_tls_security_level = may
# Postfix >= 2.6:
-# Do not tweak opportunistic ciphers or protocols unless it is essential
+# Do not tweak opportunistic ciphers unless it is essential
# to do so (if a security vulnerability is found in the SSL library that
# can be mitigated by disabling a particular protocol or raising the
# cipher grade from "export" to "low" or "medium").
smtp_tls_ciphers = export
-smtp_tls_protocols =
+smtp_tls_protocols = !SSLv2
.fi
.ad
.ft R
diff --git a/postfix/man/man8/cleanup.8 b/postfix/man/man8/cleanup.8
index 6b1884268..de5f912f0 100644
--- a/postfix/man/man8/cleanup.8
+++ b/postfix/man/man8/cleanup.8
@@ -144,9 +144,10 @@ see the MILTER_README document.
.IP "\fBnon_smtpd_milters (empty)\fR"
A list of Milter (mail filter) applications for new mail that
does not arrive via the Postfix \fBsmtpd\fR(8) server.
-.IP "\fBmilter_protocol (2)\fR"
+.IP "\fBmilter_protocol (6)\fR"
The mail filter protocol version and optional protocol extensions
-for communication with a Milter (mail filter) application.
+for communication with a Milter application; prior to Postfix 2.6
+the default protocol is 2.
.IP "\fBmilter_default_action (tempfail)\fR"
The default action when a Milter (mail filter) application is
unavailable or mis-configured.
diff --git a/postfix/man/man8/local.8 b/postfix/man/man8/local.8
index 382637136..4a847abbc 100644
--- a/postfix/man/man8/local.8
+++ b/postfix/man/man8/local.8
@@ -320,10 +320,6 @@ or to the alias \fIname\fR, to the destinations listed in
~\fIname\fR/.\fBforward\fR+\fIfoo\fR or in ~\fIname\fR/.\fBforward\fR,
to the mailbox owned by the user \fIname\fR, or it is sent back as
undeliverable.
-
-In all cases the \fBlocal\fR(8) daemon prepends an optional
-`\fBDelivered-To:\fR header line with the final recipient
-address.
.SH "DELIVERY RIGHTS"
.na
.nf
diff --git a/postfix/man/man8/pipe.8 b/postfix/man/man8/pipe.8
index 527bd404c..474899745 100644
--- a/postfix/man/man8/pipe.8
+++ b/postfix/man/man8/pipe.8
@@ -170,7 +170,7 @@ naive software. For example, when the \fBpipe\fR(8) daemon
executes a command such as:
.sp
.nf
- command -f$sender -- $recipient (\fIbad\fR)
+ \fIWrong\fR: command -f$sender -- $recipient
.fi
.IP
the command will mis-parse the -f option value when the
@@ -178,7 +178,7 @@ sender address is a null string. For correct parsing,
specify \fB$sender\fR as an argument by itself:
.sp
.nf
- command -f $sender -- $recipient (\fIgood\fR)
+ \fIRight\fR: command -f $sender -- $recipient
.fi
.IP
This feature is available as of Postfix 2.3.
diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8
index c3baf168b..4fc471b79 100644
--- a/postfix/man/man8/smtp.8
+++ b/postfix/man/man8/smtp.8
@@ -420,9 +420,9 @@ The message digest algorithm used to construct remote SMTP server
certificate fingerprints.
.PP
Available in Postfix version 2.6 and later:
-.IP "\fBsmtp_tls_protocols (empty)\fR"
-List of TLS protocols that the Postfix SMTP client will exclude
-or include with opportunistic TLS encryption.
+.IP "\fBsmtp_tls_protocols (!SSLv2)\fR"
+List of TLS protocols that the Postfix SMTP client will exclude or
+include with opportunistic TLS encryption.
.IP "\fBsmtp_tls_ciphers (export)\fR"
The minimum TLS cipher grade that the Postfix SMTP client
will use with opportunistic TLS encryption.
diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8
index 9439ff6e6..dc7ebc13d 100644
--- a/postfix/man/man8/smtpd.8
+++ b/postfix/man/man8/smtpd.8
@@ -200,9 +200,10 @@ mail is queued. For details see the MILTER_README document.
.IP "\fBsmtpd_milters (empty)\fR"
A list of Milter (mail filter) applications for new mail that
arrives via the Postfix \fBsmtpd\fR(8) server.
-.IP "\fBmilter_protocol (2)\fR"
+.IP "\fBmilter_protocol (6)\fR"
The mail filter protocol version and optional protocol extensions
-for communication with a Milter (mail filter) application.
+for communication with a Milter application; prior to Postfix 2.6
+the default protocol is 2.
.IP "\fBmilter_default_action (tempfail)\fR"
The default action when a Milter (mail filter) application is
unavailable or mis-configured.
@@ -340,9 +341,9 @@ during TLS startup and shutdown handshake procedures.
A file containing (PEM format) CA certificates of root CAs trusted
to sign either remote SMTP client certificates or intermediate CA
certificates.
-.IP "\fBsmtpd_tls_CAfile (empty)\fR"
-A file containing (PEM format) CA certificates of root CAs trusted
-to sign either remote SMTP client certificates or intermediate CA
+.IP "\fBsmtpd_tls_CApath (empty)\fR"
+A directory containing (PEM format) CA certificates of root CAs
+trusted to sign either remote SMTP client certificates or intermediate CA
certificates.
.IP "\fBsmtpd_tls_always_issue_session_ids (yes)\fR"
Force the Postfix SMTP server to issue a TLS session id, even
diff --git a/postfix/proto/FILTER_README.html b/postfix/proto/FILTER_README.html
index 9f036b1cb..d021d8a33 100644
--- a/postfix/proto/FILTER_README.html
+++ b/postfix/proto/FILTER_README.html
@@ -356,7 +356,8 @@ to the "filter" user. This is where the content filtering script
is supposed to store its temporary files.
Configure Postfix to deliver mail to the content filter
-with the pipe(8) delivery agent.
+with the pipe(8) delivery agent (see the pipe(8) manpage for a
+description of the command syntax below).
/etc/postfix/master.cf:
@@ -365,14 +366,16 @@ with the pipe(8) delivery agent.
# (yes) (yes) (yes) (never) (100)
# =============================================================
filter unix - n n - 10 pipe
- flags=Rq user=filter argv=/path/to/script -f ${sender} -- ${recipient}
+ flags=Rq user=filter null_sender=
+ argv=/path/to/script -f ${sender} -- ${recipient}
This runs up to 10 content filters in parallel. Instead of a
limit of 10 concurrent processes, use whatever process limit is
feasible for your machine. Content inspection software can gobble
up a lot of system resources, so you don't want to have too much
-of it running at the same time.
+of it running at the same time. The empty null_sender setting is
+required with Postfix 2.3 and later.
To turn on content filtering for mail arriving via SMTP
only, append "-o content_filter=filter:dummy" to the master.cf
diff --git a/postfix/proto/MILTER_README.html b/postfix/proto/MILTER_README.html
index b88a88493..ca544dd69 100644
--- a/postfix/proto/MILTER_README.html
+++ b/postfix/proto/MILTER_README.html
@@ -442,12 +442,15 @@ in the "hold" queue, and is available with Postfix 2.6 or later.
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 version is 2. Other protocol versions are
-3 and 4 (Postfix 2.3 and later), and 6 (Postfix 2.5 an later).
+should use. The default version is 6 (before Postfix 2.6 the default
+version is 2).
/etc/postfix/main.cf:
+ # Postfix ≥ 2.6
+ milter_protocol = 6
+ # 2.3 ≤ Postfix ≤ 2.5
milter_protocol = 2
@@ -515,7 +518,9 @@ times. This is an inherent problem with before-queue filtering.
Postfix emulates a limited number of Sendmail macros, as shown
-in the table. Different macros are available at different SMTP
+in the table. Some macro values depend on whether a recipient is
+rejected (rejected recipients are available on request by the Milter
+application). Different macros are available at different SMTP
protocol stages (EOH = end-of-header, EOM = end-of-message); their
availability is not
always the same as in Sendmail. See the
| {client_connections} | CONNECT |
Connection concurrency for this client |
- | {client_name} | Always | Client hostname,
-"unknown" when lookup or verification fails |
+ | {client_name} | Always | Client hostname
+ When address → name lookup or name → address
+verification fails: "unknown" |
| {client_port} | Always (Postfix ≥2.5) |
Client TCP port |
| {client_ptr} | CONNECT, HELO, MAIL, DATA |
- Client name from reverse lookup, "unknown" when lookup fails
- |
+
Client name from address → name lookup When address
+→ name lookup fails: "unknown" |
| {cert_issuer} | HELO, MAIL, DATA, EOH, EOM |
TLS client certificate issuer |
@@ -580,11 +586,25 @@ milter_macro_daemon_name
| {mail_addr} | MAIL | Sender address
|
+ | {mail_host} | MAIL (Postfix ≥ 2.6) |
+Sender next-hop destination |
+
+ | {mail_mailer} | MAIL (Postfix ≥ 2.6) |
+ Sender mail delivery transport |
+
| {rcpt_addr} | RCPT | Recipient address
- |
+
With rejected recipient: descriptive text
+
+ | {rcpt_host} | RCPT (Postfix ≥ 2.6) |
+Recipient next-hop destination With rejected recpient: enhanced
+status code |
+
+ | {rcpt_mailer} | RCPT (Postfix ≥ 2.6) |
+ Recipient mail delivery transport With rejected recipient:
+"error" |
- | {tls_version} | HELO, MAIL, DATA, EOH, EOM |
-TLS protocol version |
+ | {tls_version} | HELO, MAIL, DATA, EOH, EOM |
+ TLS protocol version |
| v | Always | value of milter_macro_v
|
@@ -777,15 +797,8 @@ a discussion.
--
Postfix version 2.3 introduces support for Sendmail 8
-milter protocol versions 2, 3 and 4; Postfix version 2.5 adds support
-for protocol version 6, which is available with Sendmail 8.14.
-Support for other protocol types or protocol versions may be added
-later.
-
- -
For applications that are written in C, you need to use
-the Sendmail libmilter library. A Postfix replacement may be
-provided in the future.
+ -
For Milter applications that are written in C, you need
+to use the Sendmail libmilter library.
-
There are TWO sets of mail filters: filters that are used
for SMTP mail only (specified with the smtpd_milters parameter),
@@ -793,6 +806,8 @@ and filters for non-SMTP mail (specified with the non_smtpd_milters
parameter). The non-SMTP filters are primarily for local submissions.
+
+
-
When mail is filtered by non-SMTP filters, the Postfix
cleanup(8) server has to simulate the SMTP client CONNECT and
DISCONNECT events, and the SMTP client EHLO, MAIL FROM, RCPT TO and
@@ -802,6 +817,8 @@ commands. When a non-SMTP filter REJECTs or TEMPFAILs a recipient,
Postfix will report a configuration error, and mail will stay in
the queue.
+
+
-
Postfix currently does not apply content filters to mail
that is forwarded or aliased internally, or to mail that is generated
internally such as bounces or Postmaster notifications. This may
@@ -814,9 +831,37 @@ only to the SMTP command information; they have no access to the
message header or body, and cannot make modifications to the message
or to the envelope.
- -
Postfix 2.3 does not support Milter requests to replace
-the message body. Milter applications that request this unsupported
-operation will log a warning like this:
+ -
Postfix version 2.6 implements all Sendmail 8.14 Milter
+features, except it ignores the optional ESMTP command parameters
+with requests to replace the sender (SMFIR_CHGFROM), or to append
+a recipient (SMFIR_ADDRCPT_PAR). When a Milter application supplies
+ESMTP command parameters, these are logged as follows:
+
+
+postfix/cleanup[40629]: warning: 100B22B3293: cleanup_chg_from: ignoring ESMTP arguments "whatever"
+
+
+ Specify "milter_protocol = 6" to enable all available Sendmail
+8.14 and earlier Milter features.
+
+ -
Postfix version 2.5 implements all Sendmail 8.14 Milter
+features except: SMFIP_RCPT_REJ (report rejected recipients to the
+mail filter), SMFIR_CHGFROM (replace sender, with optional ESMTP
+command parameters), and SMFIR_ADDRCPT_PAR (add recipient, with
+optional ESMTP command parameters).
+
+ Specify "milter_protocol = 6" to enable all available Sendmail
+8.14 and earlier Milter features.
+
+ -
Postfix 2.4 implements all Sendmail 8.13 Milter features.
+
+
+ Specify "milter_protocol = 4" to enable all available Sendmail
+8.13 and earlier Milter features.
+
+ -
Postfix 2.3 implements all Sendmail 8.13 Milter features
+except requests to replace the message body. Milter applications
+that request this unsupported operation will log a warning like
@@ -826,11 +871,8 @@ operation will log a warning like this:
The solution is to use Postfix version 2.4 or later.
-
-
Postfix version 2.5 implements the Sendmail 8.14 features
-except: SMFIP_RCPT_REJ (report rejected recipients to the mail
-filter), SMFIR_CHGFROM (replace sender, with optional ESMTP command
-parameters), and SMFIR_ADDRCPT_PAR (add recipient, with optional
-ESMTP command parameters).
+
Specify "milter_protocol = 4" to enable all available Sendmail
+8.13 and earlier Milter features.
-
Most Milter configuration options are global. Future Postfix
versions may support per-Milter timeouts, per-Milter error handling,
diff --git a/postfix/proto/SMTPD_ACCESS_README.html b/postfix/proto/SMTPD_ACCESS_README.html
index 39210a4f3..e40a402b7 100644
--- a/postfix/proto/SMTPD_ACCESS_README.html
+++ b/postfix/proto/SMTPD_ACCESS_README.html
@@ -193,8 +193,8 @@ some restriction produces a result of PERMIT, REJECT or DEFER (try
again later). The end of the list is equivalent to a PERMIT result.
By placing a PERMIT restriction before a REJECT restriction you
can make exceptions for specific clients or users. This is called
-whitelisting; the last example above allows mail from local networks
-but otherwise rejects mail to arbitrary destinations.
+whitelisting; the fourth example above allows mail from local
+networks but otherwise rejects mail to arbitrary destinations.
The table below summarizes the purpose of each SMTP access
restriction list. All lists use the exact same syntax; they differ
diff --git a/postfix/proto/TLS_README.html b/postfix/proto/TLS_README.html
index c2d999b50..f42bee9c6 100644
--- a/postfix/proto/TLS_README.html
+++ b/postfix/proto/TLS_README.html
@@ -2277,7 +2277,7 @@ the SSL/TLS protocols used with opportunistic TLS.
smtp_tls_mandatory_protocols = !SSLv2
# Also available with Postfix ≥ 2.6:
smtp_tls_ciphers = export
- smtp_tls_protocols =
+ smtp_tls_protocols = !SSLv2
diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto
index 1848dd3b3..b1d88550c 100644
--- a/postfix/proto/postconf.proto
+++ b/postfix/proto/postconf.proto
@@ -9121,8 +9121,8 @@ introduced in Postfix 2.3. Starting with Postfix 2.3, and independently
of how the policy is specified, the smtp_tls_mandatory_ciphers and
smtp_tls_mandatory_protocols parameters apply when TLS encryption
is mandatory. Connections for which encryption is optional typically
-enable all "export" grade and better ciphers and all SSL/TLS protocols
-(see smtp_tls_ciphers and smtp_tls_protocols).
+enable all "export" grade and better ciphers (see smtp_tls_ciphers
+and smtp_tls_protocols).
As long as no secure DNS lookup mechanism is available, false
hostnames in MX or CNAME responses can change the server hostname
@@ -10389,12 +10389,12 @@ smtp_tls_security_level = none
# Opportunistic TLS.
smtp_tls_security_level = may
# Postfix ≥ 2.6:
-# Do not tweak opportunistic ciphers or protocols unless it is essential
+# Do not tweak opportunistic ciphers unless it is essential
# to do so (if a security vulnerability is found in the SSL library that
# can be mitigated by disabling a particular protocol or raising the
# cipher grade from "export" to "low" or "medium").
smtp_tls_ciphers = export
-smtp_tls_protocols =
+smtp_tls_protocols = !SSLv2
@@ -10454,10 +10454,11 @@ for details.
This feature is available in Postfix 2.3 and later.
-%PARAM milter_protocol 2
+%PARAM milter_protocol 6
The mail filter protocol version and optional protocol extensions
-for communication with a Milter (mail filter) application. Postfix
+for communication with a Milter application; prior to Postfix 2.6
+the default protocol is 2. Postfix
sends this version number during the initial protocol handshake.
It should match the version number that is expected by the mail
filter application (or by its Milter library).
@@ -10467,14 +10468,15 @@ filter application (or by its Milter library).
- 2
- Use Sendmail 8 mail filter protocol version 2 (default
-as of Sendmail version 8.11).
+with Sendmail version 8.11 .. 8.13 and Postfix version 2.3 ..
+2.5).
3 Use Sendmail 8 mail filter protocol version 3.
4 Use Sendmail 8 mail filter protocol version 4.
6 Use Sendmail 8 mail filter protocol version 6 (default
-as of Sendmail version 8.14).
+with Sendmail version 8.14 and Postfix version 2.6).
@@ -11284,12 +11286,12 @@ the hostname and IP address. The logging format is "host[address]:port".
This feature is available in Postfix 2.5 and later.
-%PARAM smtp_tls_protocols
+%PARAM smtp_tls_protocols !SSLv2
- List of TLS protocols that the Postfix SMTP client will exclude
-or include with opportunistic TLS encryption. This parameter SHOULD be
-left at its default empty value, allowing all protocols to be used with
-opportunistic TLS.
+ List of TLS protocols that the Postfix SMTP client will exclude or
+include with opportunistic TLS encryption. Starting with Postfix 2.6,
+the Postfix SMTP client will by default not use the obsolete SSLv2
+protocol.
In main.cf the values are separated by whitespace, commas or
colons. In the policy table (see smtp_tls_policy_maps) the only valid
@@ -11308,7 +11310,8 @@ they cannot be excluded using either syntax.
Example:
-smtp_tls_protocols = !SSLv2
+# TLSv1 only!
+smtp_tls_protocols = !SSLv2, !SSLv3
This feature is available in Postfix 2.6 and later.
diff --git a/postfix/src/bounce/bounce_notify_service.c b/postfix/src/bounce/bounce_notify_service.c
index 2f9fdb81b..75c490082 100644
--- a/postfix/src/bounce/bounce_notify_service.c
+++ b/postfix/src/bounce/bounce_notify_service.c
@@ -174,7 +174,7 @@ int bounce_notify_service(int flags, char *service, char *queue_name,
postmaster = var_2bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
@@ -213,7 +213,7 @@ int bounce_notify_service(int flags, char *service, char *queue_name,
*/
else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
@@ -267,7 +267,7 @@ int bounce_notify_service(int flags, char *service, char *queue_name,
postmaster = var_bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
count = -1;
diff --git a/postfix/src/bounce/bounce_notify_verp.c b/postfix/src/bounce/bounce_notify_verp.c
index 749b347c8..3968c73aa 100644
--- a/postfix/src/bounce/bounce_notify_verp.c
+++ b/postfix/src/bounce/bounce_notify_verp.c
@@ -160,7 +160,7 @@ int bounce_notify_verp(int flags, char *service, char *queue_name,
} else {
verp_sender(verp_buf, verp_delims, recipient, rcpt);
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, STR(verp_buf),
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
@@ -219,7 +219,7 @@ int bounce_notify_verp(int flags, char *service, char *queue_name,
postmaster = var_bounce_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
if (bounce_header(bounce, bounce_info, postmaster,
diff --git a/postfix/src/bounce/bounce_one_service.c b/postfix/src/bounce/bounce_one_service.c
index 5373e74e1..7a3da8230 100644
--- a/postfix/src/bounce/bounce_one_service.c
+++ b/postfix/src/bounce/bounce_one_service.c
@@ -147,7 +147,7 @@ int bounce_one_service(int flags, char *queue_name, char *queue_id,
} else {
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_2bounce_rcpt,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
@@ -183,7 +183,7 @@ int bounce_one_service(int flags, char *queue_name, char *queue_id,
bounce_status = 0;
} else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, orig_sender,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
@@ -228,7 +228,7 @@ int bounce_one_service(int flags, char *queue_name, char *queue_id,
*/
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_bounce_rcpt,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
if (bounce_header(bounce, bounce_info, var_bounce_rcpt,
diff --git a/postfix/src/bounce/bounce_trace_service.c b/postfix/src/bounce/bounce_trace_service.c
index 78d1b9362..850515902 100644
--- a/postfix/src/bounce/bounce_trace_service.c
+++ b/postfix/src/bounce/bounce_trace_service.c
@@ -140,7 +140,7 @@ int bounce_trace_service(int flags, char *service, char *queue_name,
* a new queue file.
*/
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
count = -1;
diff --git a/postfix/src/bounce/bounce_warn_service.c b/postfix/src/bounce/bounce_warn_service.c
index cb19579a1..f4b62c75b 100644
--- a/postfix/src/bounce/bounce_warn_service.c
+++ b/postfix/src/bounce/bounce_warn_service.c
@@ -164,7 +164,7 @@ int bounce_warn_service(int unused_flags, char *service, char *queue_name,
postmaster = var_delay_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
@@ -202,7 +202,7 @@ int bounce_warn_service(int unused_flags, char *service, char *queue_name,
*/
else {
if ((bounce = post_mail_fopen_nowait(NULL_SENDER, recipient,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
@@ -252,7 +252,7 @@ int bounce_warn_service(int unused_flags, char *service, char *queue_name,
postmaster = var_delay_rcpt;
if ((bounce = post_mail_fopen_nowait(mail_addr_double_bounce(),
postmaster,
- INT_FILT_BOUNCE,
+ INT_FILT_MASK_BOUNCE,
NULL_TRACE_FLAGS,
new_id)) != 0) {
count = -1;
diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in
index d2bc00fcf..161ebf2dd 100644
--- a/postfix/src/cleanup/Makefile.in
+++ b/postfix/src/cleanup/Makefile.in
@@ -74,7 +74,9 @@ milter_tests: cleanup_milter_test bug_tests \
cleanup_milter_test5 cleanup_milter_test6 cleanup_milter_test7 \
cleanup_milter_test8 cleanup_milter_test9 cleanup_milter_test10a \
cleanup_milter_test10b cleanup_milter_test10c cleanup_milter_test10d \
- cleanup_milter_test10e cleanup_milter_test11 cleanup_milter_test12
+ cleanup_milter_test10e cleanup_milter_test11 cleanup_milter_test12 \
+ cleanup_milter_test13a cleanup_milter_test13b cleanup_milter_test13c \
+ cleanup_milter_test13d
root_tests:
@@ -296,6 +298,42 @@ cleanup_milter_test12: cleanup_milter test-queue-file12 cleanup_milter.in12 \
diff cleanup_milter.ref12 cleanup_milter.tmp
rm -f test-queue-file12.tmp cleanup_milter.tmp
+cleanup_milter_test13a: cleanup_milter test-queue-file13a cleanup_milter.in13a \
+ cleanup_milter.ref13a ../postcat/postcat
+ cp test-queue-file13a test-queue-file13a.tmp
+ chmod u+w test-queue-file13a.tmp
+ ./cleanup_milter /dev/null >cleanup_milter.tmp
+ diff cleanup_milter.ref13a cleanup_milter.tmp
+ rm -f test-queue-file13a.tmp cleanup_milter.tmp
+
+cleanup_milter_test13b: cleanup_milter test-queue-file13b cleanup_milter.in13b \
+ cleanup_milter.ref13b ../postcat/postcat
+ cp test-queue-file13b test-queue-file13b.tmp
+ chmod u+w test-queue-file13b.tmp
+ ./cleanup_milter /dev/null >cleanup_milter.tmp
+ diff cleanup_milter.ref13b cleanup_milter.tmp
+ rm -f test-queue-file13b.tmp cleanup_milter.tmp
+
+cleanup_milter_test13c: cleanup_milter test-queue-file13c cleanup_milter.in13c \
+ cleanup_milter.ref13c ../postcat/postcat
+ cp test-queue-file13c test-queue-file13c.tmp
+ chmod u+w test-queue-file13c.tmp
+ ./cleanup_milter /dev/null >cleanup_milter.tmp
+ diff cleanup_milter.ref13c cleanup_milter.tmp
+ rm -f test-queue-file13c.tmp cleanup_milter.tmp
+
+cleanup_milter_test13d: cleanup_milter test-queue-file13d cleanup_milter.in13d \
+ cleanup_milter.ref13d ../postcat/postcat
+ cp test-queue-file13d test-queue-file13d.tmp
+ chmod u+w test-queue-file13d.tmp
+ ./cleanup_milter /dev/null >cleanup_milter.tmp
+ diff cleanup_milter.ref13d cleanup_milter.tmp
+ rm -f test-queue-file13d.tmp cleanup_milter.tmp
+
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
diff --git a/postfix/src/cleanup/cleanup.c b/postfix/src/cleanup/cleanup.c
index a9dbdf5b7..0289931e9 100644
--- a/postfix/src/cleanup/cleanup.c
+++ b/postfix/src/cleanup/cleanup.c
@@ -124,9 +124,10 @@
/* .IP "\fBnon_smtpd_milters (empty)\fR"
/* A list of Milter (mail filter) applications for new mail that
/* does not arrive via the Postfix \fBsmtpd\fR(8) server.
-/* .IP "\fBmilter_protocol (2)\fR"
+/* .IP "\fBmilter_protocol (6)\fR"
/* The mail filter protocol version and optional protocol extensions
-/* for communication with a Milter (mail filter) application.
+/* for communication with a Milter application; prior to Postfix 2.6
+/* the default protocol is 2.
/* .IP "\fBmilter_default_action (tempfail)\fR"
/* The default action when a Milter (mail filter) application is
/* unavailable or mis-configured.
diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h
index 514b72066..d8bfe08f8 100644
--- a/postfix/src/cleanup/cleanup.h
+++ b/postfix/src/cleanup/cleanup.h
@@ -72,6 +72,8 @@ typedef struct CLEANUP_STATE {
off_t body_offset; /* start of body content */
off_t xtra_offset; /* start of extra segment */
off_t cont_length; /* length including Milter edits */
+ off_t sender_pt_offset; /* replace sender here */
+ off_t sender_pt_target; /* record after sender address */
off_t append_rcpt_pt_offset; /* append recipient here */
off_t append_rcpt_pt_target; /* target of above record */
off_t append_hdr_pt_offset; /* append header here */
diff --git a/postfix/src/cleanup/cleanup_envelope.c b/postfix/src/cleanup/cleanup_envelope.c
index b21da3e85..a7a964692 100644
--- a/postfix/src/cleanup/cleanup_envelope.c
+++ b/postfix/src/cleanup/cleanup_envelope.c
@@ -377,7 +377,20 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
state->errs |= CLEANUP_STAT_BAD;
return;
}
+ if (state->milters || cleanup_milters) {
+ /* Remember the sender record offset. */
+ if ((state->sender_pt_offset = vstream_ftell(state->dst)) < 0)
+ msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
+ }
cleanup_addr_sender(state, buf);
+ if (state->milters || cleanup_milters) {
+ /* Make room to replace sender. */
+ if (len < REC_TYPE_PTR_PAYL_SIZE)
+ rec_pad(state->dst, REC_TYPE_PTR, REC_TYPE_PTR_PAYL_SIZE - len);
+ /* Remember the after-sender record offset. */
+ if ((state->sender_pt_target = vstream_ftell(state->dst)) < 0)
+ msg_fatal("%s: vstream_ftell %s: %m:", myname, cleanup_path);
+ }
if (cleanup_milters != 0
&& state->milters == 0
&& CLEANUP_MILTER_OK(state))
diff --git a/postfix/src/cleanup/cleanup_milter.c b/postfix/src/cleanup/cleanup_milter.c
index def810f14..fdab9f5cc 100644
--- a/postfix/src/cleanup/cleanup_milter.c
+++ b/postfix/src/cleanup/cleanup_milter.c
@@ -959,6 +959,99 @@ static const char *cleanup_del_header(void *context, ssize_t index,
return (CLEANUP_OUT_OK(state) ? 0 : cleanup_milter_error(state, 0));
}
+/* cleanup_chg_from - replace sender address, ignore ESMTP arguments */
+
+static const char *cleanup_chg_from(void *context, const char *ext_from,
+ const char *esmtp_args)
+{
+ const char *myname = "cleanup_chg_from";
+ CLEANUP_STATE *state = (CLEANUP_STATE *) context;
+ off_t new_sender_offset;
+ int addr_count;
+ TOK822 *tree;
+ TOK822 *tp;
+ VSTRING *int_sender_buf;
+
+ if (msg_verbose)
+ msg_info("%s: \"%s\" \"%s\"", myname, ext_from, esmtp_args);
+
+ if (esmtp_args[0])
+ msg_warn("%s: %s: ignoring ESMTP arguments \"%.100s\"",
+ state->queue_id, myname, esmtp_args);
+
+ /*
+ * The cleanup server remembers the location of the the original sender
+ * address record (offset in sender_pt_offset) and the file offset of the
+ * record that follows the sender address (offset in sender_pt_target).
+ * Short original sender records are padded, so that they can safely be
+ * overwritten with a pointer record to the new sender address record.
+ */
+ if (state->sender_pt_offset < 0)
+ msg_panic("%s: no original sender record offset", myname);
+ if (state->sender_pt_target < 0)
+ msg_panic("%s: no post-sender record offset", myname);
+
+ /*
+ * Allocate space after the end of the queue file, and write the new
+ * sender record, followed by a reverse pointer record that points to the
+ * record that follows the original sender address record. No padding is
+ * needed for a "new" short sender record, since the record is not meant
+ * to be overwritten. When the "new" sender is replaced, we allocate a
+ * new record at the end of the queue file.
+ *
+ * We update the queue file in a safe manner: save the new sender after the
+ * end of the queue file, write the reverse pointer, and only then
+ * overwrite the old sender record with the forward pointer to the new
+ * sender.
+ */
+ if ((new_sender_offset = vstream_fseek(state->dst, (off_t) 0, SEEK_END)) < 0) {
+ msg_warn("%s: seek file %s: %m", myname, cleanup_path);
+ return (cleanup_milter_error(state, errno));
+ }
+
+ /*
+ * Transform the address from external form to internal form. This also
+ * removes the enclosing <>, if present.
+ *
+ * XXX vstring_alloc() rejects zero-length requests.
+ */
+ int_sender_buf = vstring_alloc(strlen(ext_from) + 1);
+ tree = tok822_parse(ext_from);
+ for (addr_count = 0, tp = tree; tp != 0; tp = tp->next) {
+ if (tp->type == TOK822_ADDR) {
+ if (addr_count == 0) {
+ tok822_internalize(int_sender_buf, tp->head, TOK822_STR_DEFL);
+ addr_count += 1;
+ } else {
+ msg_warn("%s: Milter request to add multi-sender: \"%s\"",
+ state->queue_id, ext_from);
+ break;
+ }
+ }
+ }
+ tok822_free_tree(tree);
+ cleanup_addr_sender(state, STR(int_sender_buf));
+ vstring_free(int_sender_buf);
+ cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT,
+ (long) state->sender_pt_target);
+
+ /*
+ * Overwrite the original sender record with the pointer to the new
+ * sender address record.
+ */
+ if (vstream_fseek(state->dst, state->sender_pt_offset, SEEK_SET) < 0) {
+ msg_warn("%s: seek file %s: %m", myname, cleanup_path);
+ return (cleanup_milter_error(state, errno));
+ }
+ cleanup_out_format(state, REC_TYPE_PTR, REC_TYPE_PTR_FORMAT,
+ (long) new_sender_offset);
+
+ /*
+ * In case of error while doing record output.
+ */
+ return (CLEANUP_OUT_OK(state) ? 0 : cleanup_milter_error(state, 0));
+}
+
/* cleanup_add_rcpt - append recipient address */
static const char *cleanup_add_rcpt(void *context, const char *ext_rcpt)
@@ -1065,6 +1158,20 @@ static const char *cleanup_add_rcpt(void *context, const char *ext_rcpt)
return (CLEANUP_OUT_OK(state) ? 0 : cleanup_milter_error(state, 0));
}
+/* cleanup_add_rcpt_par - append recipient address, ignore ESMTP arguments */
+
+static const char *cleanup_add_rcpt_par(void *context, const char *ext_rcpt,
+ const char *esmtp_args)
+{
+ const char *myname = "cleanup_add_rcpt";
+ CLEANUP_STATE *state = (CLEANUP_STATE *) context;
+
+ if (esmtp_args[0])
+ msg_warn("%s: %s: ignoring ESMTP arguments \"%.100s\"",
+ state->queue_id, myname, esmtp_args);
+ return (cleanup_add_rcpt(context, ext_rcpt));
+}
+
/* cleanup_del_rcpt - remove recipient and all its expansions */
static const char *cleanup_del_rcpt(void *context, const char *ext_rcpt)
@@ -1366,7 +1473,8 @@ void cleanup_milter_receive(CLEANUP_STATE *state, int count)
milter_edit_callback(state->milters,
cleanup_add_header, cleanup_upd_header,
cleanup_ins_header, cleanup_del_header,
- cleanup_add_rcpt, cleanup_del_rcpt,
+ cleanup_chg_from, cleanup_add_rcpt,
+ cleanup_add_rcpt_par, cleanup_del_rcpt,
cleanup_repl_body, (void *) state);
}
@@ -1399,7 +1507,7 @@ static const char *cleanup_milter_apply(CLEANUP_STATE *state, const char *event,
switch (resp[0]) {
case 'H':
/* XXX Should log the reason here. */
- if (state->flags & CLEANUP_FLAG_HOLD)
+ if (state->flags & CLEANUP_FLAG_HOLD)
return (0);
state->flags |= CLEANUP_FLAG_HOLD;
action = "milter-hold";
@@ -1538,7 +1646,8 @@ void cleanup_milter_emul_mail(CLEANUP_STATE *state,
milter_edit_callback(milters,
cleanup_add_header, cleanup_upd_header,
cleanup_ins_header, cleanup_del_header,
- cleanup_add_rcpt, cleanup_del_rcpt,
+ cleanup_chg_from, cleanup_add_rcpt,
+ cleanup_add_rcpt_par, cleanup_del_rcpt,
cleanup_repl_body, (void *) state);
if (state->client_name == 0)
cleanup_milter_client_init(state);
@@ -1608,7 +1717,7 @@ void cleanup_milter_emul_rcpt(CLEANUP_STATE *state,
vstring_strcpy(state->milter_ext_rcpt, addr);
argv[0] = STR(state->milter_ext_rcpt);
argv[1] = 0;
- if ((resp = milter_rcpt_event(milters, argv)) != 0
+ if ((resp = milter_rcpt_event(milters, MILTER_FLAG_NONE, argv)) != 0
&& cleanup_milter_apply(state, "RCPT", resp) != 0) {
msg_warn("%s: milter configuration error: can't reject recipient "
"in non-smtpd(8) submission", state->queue_id);
@@ -1768,6 +1877,14 @@ static void open_queue_file(CLEANUP_STATE *state, const char *path)
cleanup_path, STR(buf));
state->data_offset = data_offset;
state->xtra_offset = data_offset + msg_seg_len;
+ } else if (rec_type == REC_TYPE_FROM) {
+ state->sender_pt_offset = curr_offset;
+ if (LEN(buf) < REC_TYPE_PTR_PAYL_SIZE
+ && rec_get_raw(state->dst, buf, 0, REC_FLAG_NONE) != REC_TYPE_PTR)
+ msg_fatal("file %s: missing PTR record after short sender",
+ cleanup_path);
+ if ((state->sender_pt_target = vstream_ftell(state->dst)) < 0)
+ msg_fatal("file %s: missing END record", cleanup_path);
} else if (rec_type == REC_TYPE_PTR) {
if (state->data_offset < 0)
msg_fatal("file %s: missing SIZE record", cleanup_path);
@@ -1826,6 +1943,8 @@ int main(int unused_argc, char **argv)
int istty = isatty(vstream_fileno(VSTREAM_IN));
CLEANUP_STATE *state = cleanup_state_alloc((VSTREAM *) 0);
+ state->queue_id = mystrdup("NOQUEUE");
+
msg_vstream_init(argv[0], VSTREAM_ERR);
var_line_limit = DEF_LINE_LIMIT;
var_header_limit = DEF_HEADER_LIMIT;
@@ -1910,12 +2029,24 @@ int main(int unused_argc, char **argv)
} else {
cleanup_del_header(state, index, argv->argv[2]);
}
+ } else if (strcmp(argv->argv[0], "chg_from") == 0) {
+ if (argv->argc != 3) {
+ msg_warn("bad chg_from argument count: %d", argv->argc);
+ } else {
+ cleanup_chg_from(state, argv->argv[1], argv->argv[2]);
+ }
} else if (strcmp(argv->argv[0], "add_rcpt") == 0) {
if (argv->argc != 2) {
msg_warn("bad add_rcpt argument count: %d", argv->argc);
} else {
cleanup_add_rcpt(state, argv->argv[1]);
}
+ } else if (strcmp(argv->argv[0], "add_rcpt_par") == 0) {
+ if (argv->argc != 3) {
+ msg_warn("bad add_rcpt_par argument count: %d", argv->argc);
+ } else {
+ cleanup_add_rcpt_par(state, argv->argv[1], argv->argv[2]);
+ }
} else if (strcmp(argv->argv[0], "del_rcpt") == 0) {
if (argv->argc != 2) {
msg_warn("bad del_rcpt argument count: %d", argv->argc);
diff --git a/postfix/src/cleanup/cleanup_milter.in13a b/postfix/src/cleanup/cleanup_milter.in13a
new file mode 100644
index 000000000..ab0f531b0
--- /dev/null
+++ b/postfix/src/cleanup/cleanup_milter.in13a
@@ -0,0 +1,22 @@
+#verbose on
+open test-queue-file13a.tmp
+
+# Add a recipient to a message that was received with "sendmail -t"
+# so that all the recipients are in the extracted queue file segment.
+
+add_rcpt_par me@porcupine.org esmtpstuff
+
+# Delete the recipient added above.
+
+del_rcpt me@porcupine.org
+
+# Add a new recipient, using a different address than above, so that
+# the duplicate filter won't suppress it.
+
+add_rcpt_par em@porcupine.org esmtpstuff
+
+# Delete the recipient.
+
+del_rcpt em@porcupine.org
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in13b b/postfix/src/cleanup/cleanup_milter.in13b
new file mode 100644
index 000000000..04ef9e22f
--- /dev/null
+++ b/postfix/src/cleanup/cleanup_milter.in13b
@@ -0,0 +1,8 @@
+#verbose on
+open test-queue-file13b.tmp
+
+# Change the sender.
+
+chg_from m@porcupine.org esmtpstuff
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in13c b/postfix/src/cleanup/cleanup_milter.in13c
new file mode 100644
index 000000000..8bfa292af
--- /dev/null
+++ b/postfix/src/cleanup/cleanup_milter.in13c
@@ -0,0 +1,9 @@
+#verbose on
+open test-queue-file13c.tmp
+
+# Change the sender.
+
+chg_from m@porcupine.org esmtpstuff
+chg_from n@porcupine.org esmtpstuff
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.in13d b/postfix/src/cleanup/cleanup_milter.in13d
new file mode 100644
index 000000000..da673fe22
--- /dev/null
+++ b/postfix/src/cleanup/cleanup_milter.in13d
@@ -0,0 +1,9 @@
+#verbose on
+open test-queue-file13d.tmp
+
+# Change the null sender, to test correct padding of short sender records.
+
+chg_from m@porcupine.org esmtpstuff
+chg_from n@porcupine.org esmtpstuff
+
+close
diff --git a/postfix/src/cleanup/cleanup_milter.ref11 b/postfix/src/cleanup/cleanup_milter.ref11
index 7eba2f3ce..f8be5d4f8 100644
--- a/postfix/src/cleanup/cleanup_milter.ref11
+++ b/postfix/src/cleanup/cleanup_milter.ref11
@@ -1,60 +1,66 @@
*** ENVELOPE RECORDS test-queue-file11.tmp ***
- 0 message_size: 358 480 1 0 358
- 81 message_arrival_time: Thu Jan 18 15:15:42 2007
- 100 create_time: Thu Jan 18 15:15:48 2007
+ 0 message_size: 366 605 1 0 366
+ 81 message_arrival_time: Mon Apr 27 20:41:30 2009
+ 100 create_time: Mon Apr 27 20:41:41 2009
124 named_attribute: rewrite_context=local
147 sender:
- 149 named_attribute: log_client_name=localhost
- 176 named_attribute: log_client_address=127.0.0.1
- 206 named_attribute: log_message_origin=localhost[127.0.0.1]
- 247 named_attribute: log_protocol_name=SMTP
- 271 named_attribute: client_name=localhost
- 294 named_attribute: reverse_client_name=localhost
- 325 named_attribute: client_address=127.0.0.1
- 351 named_attribute: client_address_type=2
- 374 named_attribute: dsn_orig_rcpt=rfc822;wietse@localhost
- 413 original_recipient: wietse@localhost
- 431 recipient: wietse@localhost.example.com
- 461 pointer_record: 0
- 478 *** MESSAGE CONTENTS test-queue-file11.tmp ***
- 480 regular_text: Received: from localhost (localhost [127.0.0.1])
- 530 regular_text: by foo.example.com (Postfix) with SMTP id 2ADF9290403
- 586 regular_text: for ; Thu, 18 Jan 2007 15:15:42 -0500 (EST)
- 650 regular_text: Message-Id: <20070118201548.2ADF9290403@foo.example.com>
- 708 regular_text: Date: Thu, 18 Jan 2007 15:15:42 -0500 (EST)
- 753 regular_text: From: MAILER-DAEMON
- 774 regular_text: To: undisclosed-recipients:;
- 804 pointer_record: 821
- 821 pointer_record: 842
- 842 regular_text:
- 844 regular_text: Sed ut perspiciatis unde omnis iste natus error sit voluptatem
- 909 regular_text: accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
- 976 regular_text: quae ab illo inventore veritatis et quasi architecto beatae vitae
- 1044 regular_text: dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit
- 1113 regular_text: aspernatur aut odit aut fugit, sed quia consequuntur magni dolores
- 1182 regular_text: eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam
- 1248 regular_text: est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
- 1316 regular_text: velit, sed quia non numquam eius modi tempora incidunt ut labore
- 1383 regular_text: et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima
- 1448 regular_text: veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,
- 1522 regular_text: nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure
- 1591 regular_text: reprehenderit qui in ea voluptate velit esse quam nihil molestiae
- 1659 regular_text: consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla
- 1726 regular_text: pariatur?
- 1738 regular_text:
- 1741 regular_text: At vero eos et accusamus et iusto odio dignissimos ducimus qui
- 1806 regular_text: blanditiis praesentium voluptatum deleniti atque corrupti quos
- 1871 regular_text: dolores et quas molestias excepturi sint occaecati cupiditate non
- 1939 regular_text: provident, similique sunt in culpa qui officia deserunt mollitia
- 2006 regular_text: animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis
- 2077 regular_text: est et expedita distinctio. Nam libero tempore, cum soluta nobis
- 2144 regular_text: est eligendi optio cumque nihil impedit quo minus id quod maxime
- 2211 regular_text: placeat facere possimus, omnis voluptas assumenda est, omnis dolor
- 2280 regular_text: repellendus. Temporibus autem quibusdam et aut officiis debitis aut
- 2350 regular_text: rerum necessitatibus saepe eveniet ut et voluptates repudiandae
- 2416 regular_text: sint et molestiae non recusandae. Itaque earum rerum hic tenetur a
- 2485 regular_text: sapiente delectus, ut aut reiciendis voluptatibus maiores alias
- 2551 regular_text: consequatur aut perferendis doloribus asperiores repellat.
- 2612 pointer_record: 838
- 838 *** HEADER EXTRACTED test-queue-file11.tmp ***
- 840 *** MESSAGE FILE END test-queue-file11.tmp ***
+ 149 pointer_record: 0
+ 164 named_attribute: log_client_name=localhost
+ 191 named_attribute: log_client_address=127.0.0.1
+ 221 named_attribute: log_client_port=51286
+ 244 named_attribute: log_message_origin=localhost[127.0.0.1]
+ 285 named_attribute: log_helo_name=localhost
+ 310 named_attribute: log_protocol_name=SMTP
+ 334 named_attribute: client_name=localhost
+ 357 named_attribute: reverse_client_name=localhost
+ 388 named_attribute: client_address=127.0.0.1
+ 414 named_attribute: client_port=51286
+ 433 named_attribute: helo_name=localhost
+ 454 named_attribute: protocol_name=SMTP
+ 474 named_attribute: client_address_type=2
+ 497 named_attribute: dsn_orig_rcpt=rfc822;wietse@localhost
+ 536 original_recipient: wietse@localhost
+ 554 recipient: wietse@localhost.porcupine.org
+ 586 pointer_record: 0
+ 603 *** MESSAGE CONTENTS test-queue-file11.tmp ***
+ 605 regular_text: Received: from localhost (localhost [127.0.0.1])
+ 655 regular_text: by hades.porcupine.org (Postfix) with SMTP id 382B12B3292
+ 715 regular_text: for ; Mon, 27 Apr 2009 20:41:30 -0400 (EDT)
+ 779 regular_text: Message-Id: <20090428004141.382B12B3292@hades.porcupine.org>
+ 841 regular_text: Date: Mon, 27 Apr 2009 20:41:30 -0400 (EDT)
+ 886 regular_text: From: MAILER-DAEMON
+ 907 regular_text: To: undisclosed-recipients:;
+ 937 pointer_record: 954
+ 954 pointer_record: 975
+ 975 regular_text:
+ 977 regular_text: Sed ut perspiciatis unde omnis iste natus error sit voluptatem
+ 1042 regular_text: accusantium doloremque laudantium, totam rem aperiam, eaque ipsa
+ 1109 regular_text: quae ab illo inventore veritatis et quasi architecto beatae vitae
+ 1177 regular_text: dicta sunt explicabo. Nemo enim ipsam voluptatem quia voluptas sit
+ 1246 regular_text: aspernatur aut odit aut fugit, sed quia consequuntur magni dolores
+ 1315 regular_text: eos qui ratione voluptatem sequi nesciunt. Neque porro quisquam
+ 1381 regular_text: est, qui dolorem ipsum quia dolor sit amet, consectetur, adipisci
+ 1449 regular_text: velit, sed quia non numquam eius modi tempora incidunt ut labore
+ 1516 regular_text: et dolore magnam aliquam quaerat voluptatem. Ut enim ad minima
+ 1581 regular_text: veniam, quis nostrum exercitationem ullam corporis suscipit laboriosam,
+ 1655 regular_text: nisi ut aliquid ex ea commodi consequatur? Quis autem vel eum iure
+ 1724 regular_text: reprehenderit qui in ea voluptate velit esse quam nihil molestiae
+ 1792 regular_text: consequatur, vel illum qui dolorem eum fugiat quo voluptas nulla
+ 1859 regular_text: pariatur?
+ 1871 regular_text:
+ 1874 regular_text: At vero eos et accusamus et iusto odio dignissimos ducimus qui
+ 1939 regular_text: blanditiis praesentium voluptatum deleniti atque corrupti quos
+ 2004 regular_text: dolores et quas molestias excepturi sint occaecati cupiditate non
+ 2072 regular_text: provident, similique sunt in culpa qui officia deserunt mollitia
+ 2139 regular_text: animi, id est laborum et dolorum fuga. Et harum quidem rerum facilis
+ 2210 regular_text: est et expedita distinctio. Nam libero tempore, cum soluta nobis
+ 2277 regular_text: est eligendi optio cumque nihil impedit quo minus id quod maxime
+ 2344 regular_text: placeat facere possimus, omnis voluptas assumenda est, omnis dolor
+ 2413 regular_text: repellendus. Temporibus autem quibusdam et aut officiis debitis aut
+ 2483 regular_text: rerum necessitatibus saepe eveniet ut et voluptates repudiandae
+ 2549 regular_text: sint et molestiae non recusandae. Itaque earum rerum hic tenetur a
+ 2618 regular_text: sapiente delectus, ut aut reiciendis voluptatibus maiores alias
+ 2684 regular_text: consequatur aut perferendis doloribus asperiores repellat.
+ 2745 pointer_record: 971
+ 971 *** HEADER EXTRACTED test-queue-file11.tmp ***
+ 973 *** MESSAGE FILE END test-queue-file11.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref13a b/postfix/src/cleanup/cleanup_milter.ref13a
new file mode 100644
index 000000000..8a1d610e8
--- /dev/null
+++ b/postfix/src/cleanup/cleanup_milter.ref13a
@@ -0,0 +1,33 @@
+*** ENVELOPE RECORDS test-queue-file13a.tmp ***
+ 0 message_size: 332 182 1 0 332
+ 81 message_arrival_time: Sun Jan 21 13:32:59 2007
+ 100 create_time: Sun Jan 21 13:33:08 2007
+ 124 named_attribute: rewrite_context=local
+ 147 sender_fullname: Wietse Venema
+ 162 sender: me@porcupine.org
+ 180 *** MESSAGE CONTENTS test-queue-file13a.tmp ***
+ 182 regular_text: Received: by hades.porcupine.org (Postfix, from userid 1001)
+ 244 regular_text: id DE040290405; Sun, 21 Jan 2007 13:33:08 -0500 (EST)
+ 300 regular_text: From: me@porcupine.org
+ 324 regular_text: To: you@porcupine.org
+ 347 regular_text: Message-Id: <20060725192735.5EC2D29013F@hades.porcupine.org>
+ 409 regular_text: Date: Tue, 25 Jul 2006 15:27:19 -0400 (EDT)
+ 454 regular_text: Subject: hey!
+ 469 padding: 0
+ 472 pointer_record: 0
+ 489 regular_text:
+ 491 regular_text: text
+ 497 pointer_record: 0
+ 514 *** HEADER EXTRACTED test-queue-file13a.tmp ***
+ 516 original_recipient: you@porcupine.org
+ 535 recipient: you@porcupine.org
+ 554 pointer_record: 573
+ 573 named_attribute: notify_flags=1
+ 589 original_recipient: me@porcupine.org
+ 607 canceled_recipient: me@porcupine.org
+ 625 pointer_record: 642
+ 642 named_attribute: notify_flags=1
+ 658 original_recipient: em@porcupine.org
+ 676 canceled_recipient: em@porcupine.org
+ 694 pointer_record: 571
+ 571 *** MESSAGE FILE END test-queue-file13a.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref13b b/postfix/src/cleanup/cleanup_milter.ref13b
new file mode 100644
index 000000000..bb55fb64d
--- /dev/null
+++ b/postfix/src/cleanup/cleanup_milter.ref13b
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file13b.tmp ***
+ 0 message_size: 332 182 1 0 332
+ 81 message_arrival_time: Sun Jan 21 13:32:59 2007
+ 100 create_time: Sun Jan 21 13:33:08 2007
+ 124 named_attribute: rewrite_context=local
+ 147 sender_fullname: Wietse Venema
+ 162 pointer_record: 573
+ 573 sender: m@porcupine.org
+ 590 pointer_record: 180
+ 180 *** MESSAGE CONTENTS test-queue-file13b.tmp ***
+ 182 regular_text: Received: by hades.porcupine.org (Postfix, from userid 1001)
+ 244 regular_text: id DE040290405; Sun, 21 Jan 2007 13:33:08 -0500 (EST)
+ 300 regular_text: From: me@porcupine.org
+ 324 regular_text: To: you@porcupine.org
+ 347 regular_text: Message-Id: <20060725192735.5EC2D29013F@hades.porcupine.org>
+ 409 regular_text: Date: Tue, 25 Jul 2006 15:27:19 -0400 (EDT)
+ 454 regular_text: Subject: hey!
+ 469 padding: 0
+ 472 pointer_record: 0
+ 489 regular_text:
+ 491 regular_text: text
+ 497 pointer_record: 0
+ 514 *** HEADER EXTRACTED test-queue-file13b.tmp ***
+ 516 original_recipient: you@porcupine.org
+ 535 recipient: you@porcupine.org
+ 554 pointer_record: 0
+ 571 *** MESSAGE FILE END test-queue-file13b.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref13c b/postfix/src/cleanup/cleanup_milter.ref13c
new file mode 100644
index 000000000..17df1b845
--- /dev/null
+++ b/postfix/src/cleanup/cleanup_milter.ref13c
@@ -0,0 +1,27 @@
+*** ENVELOPE RECORDS test-queue-file13c.tmp ***
+ 0 message_size: 332 182 1 0 332
+ 81 message_arrival_time: Sun Jan 21 13:32:59 2007
+ 100 create_time: Sun Jan 21 13:33:08 2007
+ 124 named_attribute: rewrite_context=local
+ 147 sender_fullname: Wietse Venema
+ 162 pointer_record: 607
+ 607 sender: n@porcupine.org
+ 624 pointer_record: 180
+ 180 *** MESSAGE CONTENTS test-queue-file13c.tmp ***
+ 182 regular_text: Received: by hades.porcupine.org (Postfix, from userid 1001)
+ 244 regular_text: id DE040290405; Sun, 21 Jan 2007 13:33:08 -0500 (EST)
+ 300 regular_text: From: me@porcupine.org
+ 324 regular_text: To: you@porcupine.org
+ 347 regular_text: Message-Id: <20060725192735.5EC2D29013F@hades.porcupine.org>
+ 409 regular_text: Date: Tue, 25 Jul 2006 15:27:19 -0400 (EDT)
+ 454 regular_text: Subject: hey!
+ 469 padding: 0
+ 472 pointer_record: 0
+ 489 regular_text:
+ 491 regular_text: text
+ 497 pointer_record: 0
+ 514 *** HEADER EXTRACTED test-queue-file13c.tmp ***
+ 516 original_recipient: you@porcupine.org
+ 535 recipient: you@porcupine.org
+ 554 pointer_record: 0
+ 571 *** MESSAGE FILE END test-queue-file13c.tmp ***
diff --git a/postfix/src/cleanup/cleanup_milter.ref13d b/postfix/src/cleanup/cleanup_milter.ref13d
new file mode 100644
index 000000000..9820162e5
--- /dev/null
+++ b/postfix/src/cleanup/cleanup_milter.ref13d
@@ -0,0 +1,37 @@
+*** ENVELOPE RECORDS test-queue-file13d.tmp ***
+ 0 message_size: 366 605 1 0 366
+ 81 message_arrival_time: Mon Apr 27 20:41:30 2009
+ 100 create_time: Mon Apr 27 20:41:41 2009
+ 124 named_attribute: rewrite_context=local
+ 147 pointer_record: 1009
+ 1009 sender: n@porcupine.org
+ 1026 pointer_record: 164
+ 164 named_attribute: log_client_name=localhost
+ 191 named_attribute: log_client_address=127.0.0.1
+ 221 named_attribute: log_client_port=51286
+ 244 named_attribute: log_message_origin=localhost[127.0.0.1]
+ 285 named_attribute: log_helo_name=localhost
+ 310 named_attribute: log_protocol_name=SMTP
+ 334 named_attribute: client_name=localhost
+ 357 named_attribute: reverse_client_name=localhost
+ 388 named_attribute: client_address=127.0.0.1
+ 414 named_attribute: client_port=51286
+ 433 named_attribute: helo_name=localhost
+ 454 named_attribute: protocol_name=SMTP
+ 474 named_attribute: client_address_type=2
+ 497 named_attribute: dsn_orig_rcpt=rfc822;wietse@localhost
+ 536 original_recipient: wietse@localhost
+ 554 recipient: wietse@localhost.porcupine.org
+ 586 pointer_record: 0
+ 603 *** MESSAGE CONTENTS test-queue-file13d.tmp ***
+ 605 regular_text: Received: from localhost (localhost [127.0.0.1])
+ 655 regular_text: by hades.porcupine.org (Postfix) with SMTP id 382B12B3292
+ 715 regular_text: for ; Mon, 27 Apr 2009 20:41:30 -0400 (EDT)
+ 779 regular_text: Message-Id: <20090428004141.382B12B3292@hades.porcupine.org>
+ 841 regular_text: Date: Mon, 27 Apr 2009 20:41:30 -0400 (EDT)
+ 886 regular_text: From: MAILER-DAEMON
+ 907 regular_text: To: undisclosed-recipients:;
+ 937 pointer_record: 0
+ 954 pointer_record: 0
+ 971 *** HEADER EXTRACTED test-queue-file13d.tmp ***
+ 973 *** MESSAGE FILE END test-queue-file13d.tmp ***
diff --git a/postfix/src/cleanup/cleanup_state.c b/postfix/src/cleanup/cleanup_state.c
index ea8b13b11..7ce732cd2 100644
--- a/postfix/src/cleanup/cleanup_state.c
+++ b/postfix/src/cleanup/cleanup_state.c
@@ -91,6 +91,8 @@ CLEANUP_STATE *cleanup_state_alloc(VSTREAM *src)
state->body_offset = -1;
state->xtra_offset = -1;
state->cont_length = 0;
+ state->sender_pt_offset = -1;
+ state->sender_pt_target = -1;
state->append_rcpt_pt_offset = -1;
state->append_rcpt_pt_target = -1;
state->append_hdr_pt_offset = -1;
diff --git a/postfix/src/cleanup/test-queue-file11 b/postfix/src/cleanup/test-queue-file11
index 440f31640..745dc90ae 100644
Binary files a/postfix/src/cleanup/test-queue-file11 and b/postfix/src/cleanup/test-queue-file11 differ
diff --git a/postfix/src/cleanup/test-queue-file13a b/postfix/src/cleanup/test-queue-file13a
new file mode 100644
index 000000000..4979c1df5
Binary files /dev/null and b/postfix/src/cleanup/test-queue-file13a differ
diff --git a/postfix/src/cleanup/test-queue-file13b b/postfix/src/cleanup/test-queue-file13b
new file mode 100644
index 000000000..4979c1df5
Binary files /dev/null and b/postfix/src/cleanup/test-queue-file13b differ
diff --git a/postfix/src/cleanup/test-queue-file13c b/postfix/src/cleanup/test-queue-file13c
new file mode 100644
index 000000000..4979c1df5
Binary files /dev/null and b/postfix/src/cleanup/test-queue-file13c differ
diff --git a/postfix/src/cleanup/test-queue-file13d b/postfix/src/cleanup/test-queue-file13d
new file mode 100644
index 000000000..745dc90ae
Binary files /dev/null and b/postfix/src/cleanup/test-queue-file13d differ
diff --git a/postfix/src/global/deliver_request.c b/postfix/src/global/deliver_request.c
index 05c074380..060c04f90 100644
--- a/postfix/src/global/deliver_request.c
+++ b/postfix/src/global/deliver_request.c
@@ -207,7 +207,6 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
static RCPT_BUF *rcpt_buf;
int rcpt_count;
int dsn_ret;
- int lock_tries;
/*
* Initialize. For some reason I wanted to allow for multiple instances
@@ -319,6 +318,14 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
* duplicate deliveries when the queue is flushed immediately after queue
* manager restart.
*
+ * The queue manager locks the file exclusively when it enters the active
+ * queue, and releases the lock before starting deliveries from that
+ * file. The queue manager does not lock the file again when reading more
+ * recipients into memory. When the queue manager is restarted, the new
+ * process moves files from the active queue to the incoming queue to cool
+ * off for a while. Delivery agents should therefore never try to open a
+ * file that is locked by a queue manager process.
+ *
* Opening the queue file can fail for a variety of reasons, such as the
* system running out of resources. Instead of throwing away mail, we're
* raising a fatal error which forces the mail system to back off, and
@@ -336,21 +343,8 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
}
if (msg_verbose)
msg_info("%s: file %s", myname, VSTREAM_PATH(request->fp));
-
- /*
- * XXX Originally, the queue manager would read new recipients AFTER all
- * the in-memory recipients were processed. either the queue manager held
- * an exclusive lock or delivery agents held a shared lock. Now we try a
- * few times.
- */
- for (lock_tries = 0; /* see below */; lock_tries++) {
- if (myflock(vstream_fileno(request->fp), INTERNAL_LOCK, DELIVER_LOCK_MODE) == 0)
- break;
- if (lock_tries < 5)
- sleep(1);
- else
- msg_fatal("shared lock %s: %m", VSTREAM_PATH(request->fp));
- }
+ if (myflock(vstream_fileno(request->fp), INTERNAL_LOCK, DELIVER_LOCK_MODE) < 0)
+ msg_fatal("shared lock %s: %m", VSTREAM_PATH(request->fp));
close_on_exec(vstream_fileno(request->fp), CLOSE_ON_EXEC);
return (0);
diff --git a/postfix/src/global/int_filt.c b/postfix/src/global/int_filt.c
index 528824170..a93a3e698 100644
--- a/postfix/src/global/int_filt.c
+++ b/postfix/src/global/int_filt.c
@@ -14,12 +14,12 @@
/* the internal_mail_filter_classes configuration parameter.
/*
/* Specify one of the following:
-/* .IP INT_FILT_NONE
+/* .IP INT_FILT_MASK_NONE
/* Mail that must be excluded from inspection (address probes, etc.).
-/* .IP INT_FILT_NOTIFY
+/* .IP INT_FILT_MASK_NOTIFY
/* Postmaster notifications from the smtpd(8) and smtp(8)
/* protocol adapters.
-/* .IP INT_FILT_BOUNCE
+/* .IP INT_FILT_MASK_BOUNCE
/* Delivery status notifications from the bounce(8) server.
/* DIAGNOSTICS
/* Fatal: invalid mail category name.
@@ -54,8 +54,8 @@
int int_filt_flags(int class)
{
static const NAME_MASK table[] = {
- "notify", INT_FILT_NOTIFY,
- "bounce", INT_FILT_BOUNCE,
+ INT_FILT_CLASS_NOTIFY, INT_FILT_MASK_NOTIFY,
+ INT_FILT_CLASS_BOUNCE, INT_FILT_MASK_BOUNCE,
0,
};
int filtered_classes = 0;
diff --git a/postfix/src/global/int_filt.h b/postfix/src/global/int_filt.h
index 932fe3c3b..a85d62d41 100644
--- a/postfix/src/global/int_filt.h
+++ b/postfix/src/global/int_filt.h
@@ -14,9 +14,9 @@
/*
* External interface.
*/
-#define INT_FILT_NONE (0)
-#define INT_FILT_NOTIFY (1<<1)
-#define INT_FILT_BOUNCE (1<<2)
+#define INT_FILT_MASK_NONE (0)
+#define INT_FILT_MASK_NOTIFY (1<<1)
+#define INT_FILT_MASK_BOUNCE (1<<2)
extern int int_filt_flags(int);
diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h
index d2b4c20f8..e2498fef3 100644
--- a/postfix/src/global/mail_params.h
+++ b/postfix/src/global/mail_params.h
@@ -1428,9 +1428,9 @@ extern int var_lmtp_tls_scache_timeout;
extern char *var_smtp_tls_policy;
#define VAR_SMTP_TLS_PROTO "smtp_tls_protocols"
-#define DEF_SMTP_TLS_PROTO ""
+#define DEF_SMTP_TLS_PROTO "!SSLv2"
#define VAR_LMTP_TLS_PROTO "lmtp_tls_protocols"
-#define DEF_LMTP_TLS_PROTO ""
+#define DEF_LMTP_TLS_PROTO "!SSLv2"
extern char *var_smtp_tls_proto;
#define VAR_SMTP_TLS_MAND_PROTO "smtp_tls_mandatory_protocols"
@@ -2929,11 +2929,13 @@ extern char *var_milt_helo_macros;
#define VAR_MILT_MAIL_MACROS "milter_mail_macros"
#define DEF_MILT_MAIL_MACROS "i {auth_type} {auth_authen}" \
- " {auth_author} {mail_addr}"
+ " {auth_author} {mail_addr}" \
+ " {mail_host} {mail_mailer}"
extern char *var_milt_mail_macros;
#define VAR_MILT_RCPT_MACROS "milter_rcpt_macros"
-#define DEF_MILT_RCPT_MACROS "i {rcpt_addr}"
+#define DEF_MILT_RCPT_MACROS "i {rcpt_addr} {rcpt_host}" \
+ " {rcpt_mailer}"
extern char *var_milt_rcpt_macros;
#define VAR_MILT_DATA_MACROS "milter_data_macros"
@@ -2965,7 +2967,7 @@ extern int var_milt_cmd_time;
extern int var_milt_msg_time;
#define VAR_MILT_PROTOCOL "milter_protocol"
-#define DEF_MILT_PROTOCOL "2"
+#define DEF_MILT_PROTOCOL "6"
extern char *var_milt_protocol;
#define VAR_MILT_DEF_ACTION "milter_default_action"
@@ -2984,8 +2986,12 @@ extern char *var_milt_v;
* What internal mail do we inspect/stamp/etc.? This is not yet safe enough
* to enable world-wide.
*/
+#define INT_FILT_CLASS_NONE ""
+#define INT_FILT_CLASS_NOTIFY "notify"
+#define INT_FILT_CLASS_BOUNCE "bounce"
+
#define VAR_INT_FILT_CLASSES "internal_mail_filter_classes"
-#define DEF_INT_FILT_CLASSES ""
+#define DEF_INT_FILT_CLASSES INT_FILT_CLASS_NONE
extern char *var_int_filt_classes;
/*
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 68990a929..dca6e868d 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -20,8 +20,8 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20090418"
-#define MAIL_VERSION_NUMBER "2.6.0-RC2"
+#define MAIL_RELEASE_DATE "20090428"
+#define MAIL_VERSION_NUMBER "2.6.0-RC3"
#ifdef SNAPSHOT
# define MAIL_VERSION_DATE "-" MAIL_RELEASE_DATE
diff --git a/postfix/src/local/local.c b/postfix/src/local/local.c
index ebbf47d38..fecd18293 100644
--- a/postfix/src/local/local.c
+++ b/postfix/src/local/local.c
@@ -300,10 +300,6 @@
/* ~\fIname\fR/.\fBforward\fR+\fIfoo\fR or in ~\fIname\fR/.\fBforward\fR,
/* to the mailbox owned by the user \fIname\fR, or it is sent back as
/* undeliverable.
-/*
-/* In all cases the \fBlocal\fR(8) daemon prepends an optional
-/* `\fBDelivered-To:\fR header line with the final recipient
-/* address.
/* DELIVERY RIGHTS
/* .ad
/* .fi
diff --git a/postfix/src/milter/milter.c b/postfix/src/milter/milter.c
index 6854b358c..5ec673248 100644
--- a/postfix/src/milter/milter.c
+++ b/postfix/src/milter/milter.c
@@ -35,14 +35,17 @@
/* void *mac_context;
/*
/* void milter_edit_callback(milters, add_header, upd_header,
-/* ins_header, del_header, add_rcpt,
-/* del_rcpt, repl_body, context)
+/* ins_header, del_header, chg_from,
+/* add_rcpt, add_rcpt_par, del_rcpt,
+/* repl_body, context)
/* MILTERS *milters;
/* MILTER_ADD_HEADER_FN add_header;
/* MILTER_EDIT_HEADER_FN upd_header;
/* MILTER_EDIT_HEADER_FN ins_header;
/* MILTER_DEL_HEADER_FN del_header;
+/* MILTER_EDIT_FROM_FN chg_from;
/* MILTER_EDIT_RCPT_FN add_rcpt;
+/* MILTER_EDIT_RCPT_PAR_FN add_rcpt_par;
/* MILTER_EDIT_RCPT_FN del_rcpt;
/* MILTER_EDIT_BODY_FN repl_body;
/* void *context;
@@ -67,8 +70,9 @@
/* MILTERS *milters;
/* const char **argv;
/*
-/* const char *milter_rcpt_event(milters, argv)
+/* const char *milter_rcpt_event(milters, flags, argv)
/* MILTERS *milters;
+/* int flags;
/* const char **argv;
/*
/* const char *milter_data_event(milters)
@@ -107,7 +111,7 @@
/*
/* The functions that inspect content or envelope commands
/* return either an SMTP reply ([45]XX followed by enhanced
-/* status code and text), "D" (discard), "H" (quarantine),
+/* status code and text), "D" (discard), "H" (quarantine),
/* "S" (shutdown connection), or a null pointer, which means
/* "no news is good news".
/*
@@ -159,8 +163,15 @@
/*
/* milter_rcpt_event() reports an RCPT TO event to the specified
/* milter instances, after sending the macros that were specified
-/* with the milter_create() rcpt_macros argument.
-/*
+/* with the milter_create() rcpt_macros argument. The flags
+/* argument supports the following:
+/* .IP MILTER_FLAG_WANT_RCPT_REJ
+/* When this flag is cleared, invoke all milters. When this
+/* flag is set, invoke only milters that want to receive
+/* rejected recipients; with Sendmail V8 Milters, {rcpt_mailer}
+/* is set to "error", {rcpt_host} is set to an enhanced status
+/* code, and {rcpt_addr} is set to descriptive text.
+/* .PP
/* milter_data_event() reports a DATA event to the specified
/* milter instances, after sending the macros that were specified
/* with the milter_create() data_macros argument.
@@ -286,7 +297,9 @@ void milter_edit_callback(MILTERS *milters,
MILTER_EDIT_HEADER_FN upd_header,
MILTER_EDIT_HEADER_FN ins_header,
MILTER_DEL_HEADER_FN del_header,
+ MILTER_EDIT_FROM_FN chg_from,
MILTER_EDIT_RCPT_FN add_rcpt,
+ MILTER_EDIT_RCPT_PAR_FN add_rcpt_par,
MILTER_EDIT_RCPT_FN del_rcpt,
MILTER_EDIT_BODY_FN repl_body,
void *chg_context)
@@ -295,7 +308,9 @@ void milter_edit_callback(MILTERS *milters,
milters->upd_header = upd_header;
milters->ins_header = ins_header;
milters->del_header = del_header;
+ milters->chg_from = chg_from;
milters->add_rcpt = add_rcpt;
+ milters->add_rcpt_par = add_rcpt_par;
milters->del_rcpt = del_rcpt;
milters->repl_body = repl_body;
milters->chg_context = chg_context;
@@ -382,7 +397,7 @@ const char *milter_mail_event(MILTERS *milters, const char **argv)
/* milter_rcpt_event - report rcpt to event */
-const char *milter_rcpt_event(MILTERS *milters, const char **argv)
+const char *milter_rcpt_event(MILTERS *milters, int flags, const char **argv)
{
const char *resp;
MILTER *m;
@@ -390,12 +405,16 @@ const char *milter_rcpt_event(MILTERS *milters, const char **argv)
ARGV *any_macros;
if (msg_verbose)
- msg_info("report recipient to all milters");
+ msg_info("report recipient to all milters (flags=0x%x)", flags);
for (resp = 0, m = milters->milter_list; resp == 0 && m != 0; m = m->next) {
- any_macros = MILTER_MACRO_EVAL(global_macros, m, milters, rcpt_macros);
- resp = m->rcpt_event(m, argv, any_macros);
- if (any_macros != global_macros)
- argv_free(any_macros);
+ if ((flags & MILTER_FLAG_WANT_RCPT_REJ) == 0
+ || (m->flags & MILTER_FLAG_WANT_RCPT_REJ) != 0) {
+ any_macros =
+ MILTER_MACRO_EVAL(global_macros, m, milters, rcpt_macros);
+ resp = m->rcpt_event(m, argv, any_macros);
+ if (any_macros != global_macros)
+ argv_free(any_macros);
+ }
}
if (global_macros)
argv_free(global_macros);
diff --git a/postfix/src/milter/milter.h b/postfix/src/milter/milter.h
index f27c047d8..17d163dc4 100644
--- a/postfix/src/milter/milter.h
+++ b/postfix/src/milter/milter.h
@@ -31,6 +31,7 @@
*/
typedef struct MILTER {
char *name; /* full name including transport */
+ int flags; /* see below */
struct MILTER *next; /* linkage */
struct MILTERS *parent; /* parent information */
struct MILTER_MACROS *macros; /* private macros */
@@ -49,6 +50,9 @@ typedef struct MILTER {
void (*free) (struct MILTER *);
} MILTER;
+#define MILTER_FLAG_NONE (0)
+#define MILTER_FLAG_WANT_RCPT_REJ (1<<0) /* see S8_RCPT_MAILER_ERROR */
+
extern MILTER *milter8_create(const char *, int, int, int, const char *, const char *, struct MILTERS *);
extern MILTER *milter8_receive(VSTREAM *, struct MILTERS *);
@@ -87,7 +91,9 @@ typedef const char *(*MILTER_MAC_LOOKUP_FN) (const char *, void *);
typedef const char *(*MILTER_ADD_HEADER_FN) (void *, const char *, const char *, const char *);
typedef const char *(*MILTER_EDIT_HEADER_FN) (void *, ssize_t, const char *, const char *, const char *);
typedef const char *(*MILTER_DEL_HEADER_FN) (void *, ssize_t, const char *);
+typedef const char *(*MILTER_EDIT_FROM_FN) (void *, const char *, const char *);
typedef const char *(*MILTER_EDIT_RCPT_FN) (void *, const char *);
+typedef const char *(*MILTER_EDIT_RCPT_PAR_FN) (void *, const char *, const char *);
typedef const char *(*MILTER_EDIT_BODY_FN) (void *, int, VSTRING *);
typedef struct MILTERS {
@@ -100,7 +106,9 @@ typedef struct MILTERS {
MILTER_EDIT_HEADER_FN upd_header;
MILTER_DEL_HEADER_FN del_header;
MILTER_EDIT_HEADER_FN ins_header;
+ MILTER_EDIT_FROM_FN chg_from;
MILTER_EDIT_RCPT_FN add_rcpt;
+ MILTER_EDIT_RCPT_PAR_FN add_rcpt_par;
MILTER_EDIT_RCPT_FN del_rcpt;
MILTER_EDIT_BODY_FN repl_body;
} MILTERS;
@@ -119,13 +127,14 @@ extern MILTERS *milter_new(const char *, int, int, int, const char *,
extern void milter_macro_callback(MILTERS *, MILTER_MAC_LOOKUP_FN, void *);
extern void milter_edit_callback(MILTERS *milters, MILTER_ADD_HEADER_FN,
MILTER_EDIT_HEADER_FN, MILTER_EDIT_HEADER_FN,
- MILTER_DEL_HEADER_FN, MILTER_EDIT_RCPT_FN,
+ MILTER_DEL_HEADER_FN, MILTER_EDIT_FROM_FN,
+ MILTER_EDIT_RCPT_FN, MILTER_EDIT_RCPT_PAR_FN,
MILTER_EDIT_RCPT_FN, MILTER_EDIT_BODY_FN,
void *);
extern const char *milter_conn_event(MILTERS *, const char *, const char *, const char *, unsigned);
extern const char *milter_helo_event(MILTERS *, const char *, int);
extern const char *milter_mail_event(MILTERS *, const char **);
-extern const char *milter_rcpt_event(MILTERS *, const char **);
+extern const char *milter_rcpt_event(MILTERS *, int, const char **);
extern const char *milter_data_event(MILTERS *);
extern const char *milter_message(MILTERS *, VSTREAM *, off_t);
extern const char *milter_unknown_event(MILTERS *, const char *);
@@ -181,6 +190,8 @@ extern void milter_free(MILTERS *);
#define S8_MAC_RCPT_HOST "{rcpt_host}" /* recip nexthop */
#define S8_MAC_RCPT_ADDR "{rcpt_addr}" /* recip address */
+#define S8_RCPT_MAILER_ERROR "error" /* see MILTER_FLAG_WANT_RCPT_REJ */
+
/* LICENSE
/* .ad
/* .fi
diff --git a/postfix/src/milter/milter8.c b/postfix/src/milter/milter8.c
index 3d660a4b5..1c437e8c7 100644
--- a/postfix/src/milter/milter8.c
+++ b/postfix/src/milter/milter8.c
@@ -430,7 +430,7 @@ typedef struct {
#define MILTER8_V3_PROTO_MASK (MILTER8_V2_PROTO_MASK | SMFIP_NOUNKNOWN)
#define MILTER8_V4_PROTO_MASK (MILTER8_V3_PROTO_MASK | SMFIP_NODATA)
#define MILTER8_V6_PROTO_MASK \
- (MILTER8_V4_PROTO_MASK | SMFIP_SKIP /* | SMFIP_RCPT_REJ */ \
+ (MILTER8_V4_PROTO_MASK | SMFIP_SKIP | SMFIP_RCPT_REJ \
| SMFIP_NOREPLY_MASK | SMFIP_HDR_LEADSPC)
/*
@@ -1412,6 +1412,30 @@ static const char *milter8_event(MILTER8 *milter, int event,
STR(milter->body));
continue;
+ /*
+ * Modification request: replace sender, with optional
+ * ESMTP args.
+ */
+ case SMFIR_CHGFROM:
+ if (milter8_read_data(milter, &data_size,
+ MILTER8_DATA_STRING, milter->buf,
+ MILTER8_DATA_MORE) != 0)
+ MILTER8_EVENT_BREAK(milter->def_reply);
+ if (data_size > 0) {
+ if (milter8_read_data(milter, &data_size,
+ MILTER8_DATA_STRING, milter->body,
+ MILTER8_DATA_END) != 0)
+ MILTER8_EVENT_BREAK(milter->def_reply);
+ } else
+ STR(milter->body)[0] = 0;
+ /* Skip to the next request after previous edit error. */
+ if (edit_resp)
+ continue;
+ edit_resp = parent->chg_from(parent->chg_context,
+ STR(milter->buf),
+ STR(milter->body));
+ continue;
+
/*
* Modification request: append recipient.
*/
@@ -1427,6 +1451,30 @@ static const char *milter8_event(MILTER8 *milter, int event,
STR(milter->buf));
continue;
+ /*
+ * Modification request: append recipient, with optional
+ * ESMTP args.
+ */
+ case SMFIR_ADDRCPT_PAR:
+ if (milter8_read_data(milter, &data_size,
+ MILTER8_DATA_STRING, milter->buf,
+ MILTER8_DATA_MORE) != 0)
+ MILTER8_EVENT_BREAK(milter->def_reply);
+ if (data_size > 0) {
+ if (milter8_read_data(milter, &data_size,
+ MILTER8_DATA_STRING, milter->body,
+ MILTER8_DATA_END) != 0)
+ MILTER8_EVENT_BREAK(milter->def_reply);
+ } else
+ STR(milter->body)[0] = 0;
+ /* Skip to the next request after previous edit error. */
+ if (edit_resp)
+ continue;
+ edit_resp = parent->add_rcpt_par(parent->chg_context,
+ STR(milter->buf),
+ STR(milter->body));
+ continue;
+
/*
* Modification request: delete (expansion of) recipient.
*/
@@ -1542,10 +1590,8 @@ static void milter8_connect(MILTER8 *milter)
| SMFIF_DELRCPT | SMFIF_CHGHDRS
| SMFIF_CHGBODY
| SMFIF_QUARANTINE
-#if 0
| SMFIF_CHGFROM
| SMFIF_ADDRCPT_PAR
-#endif
| SMFIF_SETSYMLIST
);
UINT32_TYPE my_version = 0;
@@ -1720,6 +1766,8 @@ static void milter8_connect(MILTER8 *milter)
(void) milter8_comm_error(milter);
return;
}
+ if (milter->ev_mask & SMFIP_RCPT_REJ)
+ milter->m.flags |= MILTER_FLAG_WANT_RCPT_REJ;
/*
* Initial negotiations completed.
@@ -2703,6 +2751,7 @@ static MILTER8 *milter8_alloc(const char *name, int conn_timeout,
*/
milter = (MILTER8 *) mymalloc(sizeof(*milter));
milter->m.name = mystrdup(name);
+ milter->m.flags = 0;
milter->m.next = 0;
milter->m.parent = parent;
milter->m.macros = 0;
diff --git a/postfix/src/milter/test-milter.c b/postfix/src/milter/test-milter.c
index 8980f416e..9e5072994 100644
--- a/postfix/src/milter/test-milter.c
+++ b/postfix/src/milter/test-milter.c
@@ -22,13 +22,19 @@
/* .IP "\fB-A address\fR"
/* Add the specified recipient address. Multiple -A options
/* are supported.
-/* .IP "\fB-d\fI level\fR"
-/* Enable libmilter debugging at the specified level.
+/* .IP "\fB-b pathname
+/* Replace the message body by the content of the specified file.
/* .IP "\fB-c connect|helo|mail|rcpt|data|header|eoh|body|eom|unknown|close|abort\fR"
/* When to send the non-default reply specified with \fB-a\fR.
/* The default protocol stage is \fBconnect\fR.
/* .IP "\fB-C\fI count\fR"
/* Terminate after \fIcount\fR connections.
+/* .IP "\fB-d\fI level\fR"
+/* Enable libmilter debugging at the specified level.
+/* .IP "\fB-f \fIsender\fR
+/* Replace the sender by the specified address.
+/* .IP "\fB-h \fI'index header-label header-value'\fR"
+/* Replace the message header at the specified position.
/* .IP "\fB-i \fI'index header-label header-value'\fR"
/* Insert header at specified position.
/* .IP "\fB-l\fR"
@@ -46,10 +52,8 @@
/* The event for which the filter will not reply.
/* .IP "\fB-p inet:\fIport\fB@\fIhost\fB|unix:\fIpathname\fR"
/* The mail filter listen endpoint.
-/* .IP "\fB-r \fI'index header-label header-value'\fR"
-/* Replace the message header at the specified position.
-/* .IP "\fB-R pathname
-/* Replace the message body by the content of the specified file.
+/* .IP "\fB-r\fR"
+/* Request rejected recipients from the MTA.
/* .IP "\fB-v\fR"
/* Make the program more verbose.
/* LICENSE
@@ -130,6 +134,11 @@ static char *reply_code;
static char *reply_dsn;
static char *reply_message;
+#ifdef SMFIR_CHGFROM
+static char *chg_from;
+
+#endif
+
#ifdef SMFIR_INSHEADER
static char *ins_hdr;
static int ins_idx;
@@ -153,9 +162,46 @@ static char *body_file;
int rcpt_count = 0;
char *rcpt_addr[MAX_RCPT];
+static const char *macro_names[] = {
+ "_",
+ "i",
+ "j",
+ "v",
+ "{auth_authen}",
+ "{auth_author}",
+ "{auth_type}",
+ "{cert_issuer}",
+ "{cert_subject}",
+ "{cipher}",
+ "{cipher_bits}",
+ "{client_addr}",
+ "{client_connections}",
+ "{client_name}",
+ "{client_port}",
+ "{client_ptr}",
+ "{client_resolve}",
+ "{daemon_name}",
+ "{if_addr}",
+ "{if_name}",
+ "{mail_addr}",
+ "{mail_host}",
+ "{mail_mailer}",
+ "{rcpt_addr}",
+ "{rcpt_host}",
+ "{rcpt_mailer}",
+ "{tls_version}",
+ 0,
+};
+
static int test_reply(SMFICTX *ctx, int code)
{
- (void) fflush(stdout); /* In case output redirected. */
+ const char **cpp;
+ const char *symval;
+
+ for (cpp = macro_names; *cpp; cpp++)
+ if ((symval = smfi_getsymval(ctx, (char *) *cpp)) != 0)
+ printf("macro: %s=\"%s\"\n", *cpp, symval);
+ (void) fflush(stdout); /* In case output redirected. */
if (code == SMFIR_REPLYCODE) {
if (smfi_setmlreply(ctx, reply_code, reply_dsn, reply_message, reply_message, (char *) 0) == MI_FAILURE)
@@ -293,6 +339,12 @@ static sfsistat test_eom(SMFICTX *ctx)
}
}
#endif
+#ifdef SMFIR_CHGFROM
+ if (chg_from != 0 && smfi_chgfrom(ctx, chg_from, "whatever") == MI_FAILURE)
+ fprintf(stderr, "smfi_chgfrom failed\n");
+ else
+ printf("smfi_chgfrom OK\n");
+#endif
#ifdef SMFIR_INSHEADER
if (ins_hdr && smfi_insheader(ctx, ins_idx, ins_hdr, ins_val) == MI_FAILURE)
fprintf(stderr, "smfi_insheader failed\n");
@@ -356,7 +408,7 @@ static struct smfiDesc smfilter =
{
"test-milter",
SMFI_VERSION,
- SMFIF_ADDRCPT | SMFIF_DELRCPT | SMFIF_ADDHDRS | SMFIF_CHGHDRS | SMFIF_CHGBODY,
+ SMFIF_ADDRCPT | SMFIF_DELRCPT | SMFIF_ADDHDRS | SMFIF_CHGHDRS | SMFIF_CHGBODY | SMFIF_CHGFROM,
test_connect,
test_helo,
test_mail,
@@ -478,7 +530,7 @@ int main(int argc, char **argv)
char *noreply = 0;
const struct noproto_map *np;
- while ((ch = getopt(argc, argv, "a:A:c:C:d:i:lm:M:n:N:p:r:R:v")) > 0) {
+ while ((ch = getopt(argc, argv, "a:A:b:c:C:d:f:h:i:lm:M:n:N:p:rv")) > 0) {
switch (ch) {
case 'a':
action = optarg;
@@ -490,6 +542,17 @@ int main(int argc, char **argv)
}
rcpt_addr[rcpt_count++] = optarg;
break;
+ case 'b':
+#ifdef SMFIR_REPLBODY
+ if (body_file) {
+ fprintf(stderr, "too many -b options\n");
+ exit(1);
+ }
+ body_file = optarg;
+#else
+ fprintf(stderr, "no libmilter support to replace body\n");
+#endif
+ break;
case 'c':
command = optarg;
break;
@@ -499,6 +562,30 @@ int main(int argc, char **argv)
exit(1);
}
break;
+ case 'f':
+#ifdef SMFIR_CHGFROM
+ if (chg_from) {
+ fprintf(stderr, "too many -f options\n");
+ exit(1);
+ }
+ chg_from = optarg;
+#else
+ fprintf(stderr, "no libmilter support to change sender\n");
+ exit(1);
+#endif
+ break;
+ case 'h':
+#ifdef SMFIR_CHGHEADER
+ if (chg_hdr) {
+ fprintf(stderr, "too many -h options\n");
+ exit(1);
+ }
+ parse_hdr_info(optarg, &chg_idx, &chg_hdr, &chg_val);
+#else
+ fprintf(stderr, "no libmilter support to change header\n");
+ exit(1);
+#endif
+ break;
case 'i':
#ifdef SMFIR_INSHEADER
if (ins_hdr) {
@@ -575,15 +662,10 @@ int main(int argc, char **argv)
}
break;
case 'r':
-#ifdef SMFIR_CHGHEADER
- if (chg_hdr) {
- fprintf(stderr, "too many -r options\n");
- exit(1);
- }
- parse_hdr_info(optarg, &chg_idx, &chg_hdr, &chg_val);
+#ifdef SMFIP_RCPT_REJ
+ misc_mask |= SMFIP_RCPT_REJ;
#else
- fprintf(stderr, "no libmilter support to change header\n");
- exit(1);
+ fprintf(stderr, "no libmilter support for rejected recipients\n");
#endif
break;
case 'v':
@@ -592,29 +674,21 @@ int main(int argc, char **argv)
case 'C':
conn_count = atoi(optarg);
break;
-#ifdef SMFIR_REPLBODY
- case 'R':
- if (body_file) {
- fprintf(stderr, "too many -R options\n");
- exit(1);
- }
- body_file = optarg;
-#endif
- break;
default:
fprintf(stderr,
"usage: %s [-dv] \n"
"\t[-a action] non-default action\n"
+ "\t[-b body_text] replace body\n",
"\t[-c command] non-default action trigger\n"
+ "\t[-h 'index label value'] replace header\n"
"\t[-i 'index label value'] insert header\n"
"\t[-m macro_state] non-default macro state\n"
"\t[-M macro_list] non-default macro list\n"
"\t[-n events] don't receive these events\n"
"\t[-N events] don't reply to these events\n"
"\t-p port milter application\n"
- "\t[-r 'index label value'] replace header\n"
+ "\t-r request rejected recipients\n"
"\t[-C conn_count] when to exit\n",
- "\t[-R body_text] replace body\n",
argv[0]);
exit(1);
}
diff --git a/postfix/src/pipe/pipe.c b/postfix/src/pipe/pipe.c
index a17ba7f63..e9def71da 100644
--- a/postfix/src/pipe/pipe.c
+++ b/postfix/src/pipe/pipe.c
@@ -160,7 +160,7 @@
/* executes a command such as:
/* .sp
/* .nf
-/* command -f$sender -- $recipient (\fIbad\fR)
+/* \fIWrong\fR: command -f$sender -- $recipient
/* .fi
/* .IP
/* the command will mis-parse the -f option value when the
@@ -168,7 +168,7 @@
/* specify \fB$sender\fR as an argument by itself:
/* .sp
/* .nf
-/* command -f $sender -- $recipient (\fIgood\fR)
+/* \fIRight\fR: command -f $sender -- $recipient
/* .fi
/* .IP
/* This feature is available as of Postfix 2.3.
diff --git a/postfix/src/postdrop/postdrop.c b/postfix/src/postdrop/postdrop.c
index 8a3c7c2a0..a2fdc7355 100644
--- a/postfix/src/postdrop/postdrop.c
+++ b/postfix/src/postdrop/postdrop.c
@@ -340,7 +340,8 @@ int main(int argc, char **argv)
signal(SIGINT, postdrop_sig);
signal(SIGQUIT, postdrop_sig);
- signal(SIGTERM, postdrop_sig);
+ if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
+ signal(SIGTERM, postdrop_sig);
if (signal(SIGHUP, SIG_IGN) == SIG_DFL)
signal(SIGHUP, postdrop_sig);
msg_cleanup(postdrop_cleanup);
diff --git a/postfix/src/postsuper/postsuper.c b/postfix/src/postsuper/postsuper.c
index 088df7652..7b6ea74f5 100644
--- a/postfix/src/postsuper/postsuper.c
+++ b/postfix/src/postsuper/postsuper.c
@@ -974,11 +974,17 @@ static void interrupted(int sig)
/*
* This commands requires root privileges. We therefore do not worry
* about hostile signals, and report problems via msg_warn().
+ *
+ * We use the in-kernel SIGINT handler address as an atomic variable to
+ * prevent nested interrupted() calls. For this reason, main() must
+ * configure interrupted() as SIGINT handler before other signal handlers
+ * are allowed to invoke interrupted(). See also similar code in
+ * postdrop.
*/
- if (signal(SIGHUP, SIG_IGN) != SIG_IGN) {
- (void) signal(SIGINT, SIG_IGN);
+ if (signal(SIGINT, SIG_IGN) != SIG_IGN) {
(void) signal(SIGQUIT, SIG_IGN);
(void) signal(SIGTERM, SIG_IGN);
+ (void) signal(SIGHUP, SIG_IGN);
if (inode_mismatch > 0 || inode_fixed > 0 || position_mismatch > 0)
msg_warn("OPERATION INCOMPLETE -- RERUN COMMAND TO FIX THE QUEUE FIRST");
if (sig)
@@ -1175,11 +1181,20 @@ int main(int argc, char **argv)
*
* Set up signal handlers after permanently dropping super-user privileges,
* so that signal handlers will always run with the correct privileges.
+ *
+ * XXX Don't enable SIGHUP or SIGTERM if it was ignored by the parent.
+ *
+ * interrupted() uses the in-kernel SIGINT handler address as an atomic
+ * variable to prevent nested interrupted() calls. For this reason, the
+ * SIGINT handler must be configured before other signal handlers are
+ * allowed to invoke interrupted(). See also similar code in postdrop.
*/
- signal(SIGHUP, interrupted);
signal(SIGINT, interrupted);
signal(SIGQUIT, interrupted);
- signal(SIGTERM, interrupted);
+ if (signal(SIGTERM, SIG_IGN) == SIG_DFL)
+ signal(SIGTERM, interrupted);
+ if (signal(SIGHUP, SIG_IGN) == SIG_DFL)
+ signal(SIGHUP, interrupted);
msg_cleanup(fatal_warning);
/*
diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c
index c0f9f553b..d43625434 100644
--- a/postfix/src/smtp/smtp.c
+++ b/postfix/src/smtp/smtp.c
@@ -390,9 +390,9 @@
/* certificate fingerprints.
/* .PP
/* Available in Postfix version 2.6 and later:
-/* .IP "\fBsmtp_tls_protocols (empty)\fR"
-/* List of TLS protocols that the Postfix SMTP client will exclude
-/* or include with opportunistic TLS encryption.
+/* .IP "\fBsmtp_tls_protocols (!SSLv2)\fR"
+/* List of TLS protocols that the Postfix SMTP client will exclude or
+/* include with opportunistic TLS encryption.
/* .IP "\fBsmtp_tls_ciphers (export)\fR"
/* The minimum TLS cipher grade that the Postfix SMTP client
/* will use with opportunistic TLS encryption.
diff --git a/postfix/src/smtp/smtp_chat.c b/postfix/src/smtp/smtp_chat.c
index 9bb4aca40..e13b54568 100644
--- a/postfix/src/smtp/smtp_chat.c
+++ b/postfix/src/smtp/smtp_chat.c
@@ -407,7 +407,7 @@ void smtp_chat_notify(SMTP_SESSION *session)
notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_error_rcpt,
- INT_FILT_NOTIFY,
+ INT_FILT_MASK_NOTIFY,
NULL_TRACE_FLAGS, NO_QUEUE_ID);
if (notice == 0) {
msg_warn("postmaster notify: %m");
diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c
index 86a3d5a8e..c74b5fbce 100644
--- a/postfix/src/smtp/smtp_proto.c
+++ b/postfix/src/smtp/smtp_proto.c
@@ -1753,12 +1753,15 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
* XXX Don't downgrade just because generic_maps is turned
* on.
*/
- if (downgrading || smtp_generic_maps || smtp_header_checks
- || smtp_body_checks)
+#define SMTP_ANY_CHECKS (smtp_header_checks || smtp_body_checks)
+
+ if (downgrading || smtp_generic_maps || SMTP_ANY_CHECKS)
session->mime_state = mime_state_alloc(downgrading ?
MIME_OPT_DOWNGRADE
| MIME_OPT_REPORT_NESTING :
- MIME_OPT_DISABLE_MIME,
+ SMTP_ANY_CHECKS == 0 ?
+ MIME_OPT_DISABLE_MIME :
+ 0,
smtp_generic_maps
|| smtp_header_checks ?
smtp_header_rewrite :
diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in
index 7139248f5..91a274b68 100644
--- a/postfix/src/smtpd/Makefile.in
+++ b/postfix/src/smtpd/Makefile.in
@@ -1,12 +1,13 @@
SHELL = /bin/sh
SRCS = smtpd.c smtpd_token.c smtpd_check.c smtpd_chat.c smtpd_state.c \
smtpd_peer.c smtpd_sasl_proto.c smtpd_sasl_glue.c smtpd_proxy.c \
- smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c
+ smtpd_xforward.c smtpd_dsn_fix.c smtpd_milter.c smtpd_resolve.c
OBJS = smtpd.o smtpd_token.o smtpd_check.o smtpd_chat.o smtpd_state.o \
smtpd_peer.o smtpd_sasl_proto.o smtpd_sasl_glue.o smtpd_proxy.o \
- smtpd_xforward.o smtpd_dsn_fix.o smtpd_milter.o
+ smtpd_xforward.o smtpd_dsn_fix.o smtpd_milter.o smtpd_resolve.o
HDRS = smtpd_token.h smtpd_check.h smtpd_chat.h smtpd_sasl_proto.h \
- smtpd_sasl_glue.h smtpd_proxy.h smtpd_dsn_fix.h smtpd_milter.h
+ smtpd_sasl_glue.h smtpd_proxy.h smtpd_dsn_fix.h smtpd_milter.h \
+ smtpd_resolve.h
TESTSRC = smtpd_token_test.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -34,7 +35,8 @@ update: ../../libexec/$(PROG)
../../libexec/$(PROG): $(PROG)
cp $(PROG) ../../libexec
-SMTPD_CHECK_OBJ = smtpd_state.o smtpd_peer.o smtpd_xforward.o smtpd_dsn_fix.o
+SMTPD_CHECK_OBJ = smtpd_state.o smtpd_peer.o smtpd_xforward.o smtpd_dsn_fix.o \
+ smtpd_resolve.o
smtpd_token: smtpd_token.c $(LIBS)
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIBS) $(SYSLIBS)
@@ -170,6 +172,7 @@ smtpd.o: ../../include/off_cvt.h
smtpd.o: ../../include/quote_822_local.h
smtpd.o: ../../include/quote_flags.h
smtpd.o: ../../include/rec_type.h
+smtpd.o: ../../include/recipient_list.h
smtpd.o: ../../include/record.h
smtpd.o: ../../include/resolve_clnt.h
smtpd.o: ../../include/smtp_stream.h
@@ -292,6 +295,7 @@ smtpd_check.o: smtpd.h
smtpd_check.o: smtpd_check.c
smtpd_check.o: smtpd_check.h
smtpd_check.o: smtpd_dsn_fix.h
+smtpd_check.o: smtpd_resolve.h
smtpd_check.o: smtpd_sasl_glue.h
smtpd_dsn_fix.o: ../../include/msg.h
smtpd_dsn_fix.o: ../../include/sys_defs.h
@@ -307,6 +311,7 @@ smtpd_milter.o: ../../include/name_code.h
smtpd_milter.o: ../../include/name_mask.h
smtpd_milter.o: ../../include/quote_821_local.h
smtpd_milter.o: ../../include/quote_flags.h
+smtpd_milter.o: ../../include/resolve_clnt.h
smtpd_milter.o: ../../include/sys_defs.h
smtpd_milter.o: ../../include/tls.h
smtpd_milter.o: ../../include/vbuf.h
@@ -315,6 +320,7 @@ smtpd_milter.o: ../../include/vstring.h
smtpd_milter.o: smtpd.h
smtpd_milter.o: smtpd_milter.c
smtpd_milter.o: smtpd_milter.h
+smtpd_milter.o: smtpd_resolve.h
smtpd_milter.o: smtpd_sasl_glue.h
smtpd_peer.o: ../../include/argv.h
smtpd_peer.o: ../../include/attr.h
@@ -366,6 +372,21 @@ smtpd_proxy.o: ../../include/xtext.h
smtpd_proxy.o: smtpd.h
smtpd_proxy.o: smtpd_proxy.c
smtpd_proxy.o: smtpd_proxy.h
+smtpd_resolve.o: ../../include/attr.h
+smtpd_resolve.o: ../../include/ctable.h
+smtpd_resolve.o: ../../include/iostuff.h
+smtpd_resolve.o: ../../include/mail_proto.h
+smtpd_resolve.o: ../../include/msg.h
+smtpd_resolve.o: ../../include/mymalloc.h
+smtpd_resolve.o: ../../include/resolve_clnt.h
+smtpd_resolve.o: ../../include/rewrite_clnt.h
+smtpd_resolve.o: ../../include/stringops.h
+smtpd_resolve.o: ../../include/sys_defs.h
+smtpd_resolve.o: ../../include/vbuf.h
+smtpd_resolve.o: ../../include/vstream.h
+smtpd_resolve.o: ../../include/vstring.h
+smtpd_resolve.o: smtpd_resolve.c
+smtpd_resolve.o: smtpd_resolve.h
smtpd_sasl_glue.o: ../../include/argv.h
smtpd_sasl_glue.o: ../../include/attr.h
smtpd_sasl_glue.o: ../../include/mail_params.h
diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c
index da68506ba..33c6b927a 100644
--- a/postfix/src/smtpd/smtpd.c
+++ b/postfix/src/smtpd/smtpd.c
@@ -176,9 +176,10 @@
/* .IP "\fBsmtpd_milters (empty)\fR"
/* A list of Milter (mail filter) applications for new mail that
/* arrives via the Postfix \fBsmtpd\fR(8) server.
-/* .IP "\fBmilter_protocol (2)\fR"
+/* .IP "\fBmilter_protocol (6)\fR"
/* The mail filter protocol version and optional protocol extensions
-/* for communication with a Milter (mail filter) application.
+/* for communication with a Milter application; prior to Postfix 2.6
+/* the default protocol is 2.
/* .IP "\fBmilter_default_action (tempfail)\fR"
/* The default action when a Milter (mail filter) application is
/* unavailable or mis-configured.
@@ -308,9 +309,9 @@
/* A file containing (PEM format) CA certificates of root CAs trusted
/* to sign either remote SMTP client certificates or intermediate CA
/* certificates.
-/* .IP "\fBsmtpd_tls_CAfile (empty)\fR"
-/* A file containing (PEM format) CA certificates of root CAs trusted
-/* to sign either remote SMTP client certificates or intermediate CA
+/* .IP "\fBsmtpd_tls_CApath (empty)\fR"
+/* A directory containing (PEM format) CA certificates of root CAs
+/* trusted to sign either remote SMTP client certificates or intermediate CA
/* certificates.
/* .IP "\fBsmtpd_tls_always_issue_session_ids (yes)\fR"
/* Force the Postfix SMTP server to issue a TLS session id, even
@@ -2341,6 +2342,7 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
const char *dsn_orcpt_type = 0;
int dsn_notify = 0;
const char *coded_addr;
+ const char *milter_err;
/*
* Sanity checks.
@@ -2441,24 +2443,24 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
return (-1);
}
if (SMTPD_STAND_ALONE(state) == 0) {
- if ((err = smtpd_check_rcpt(state, STR(state->addr_buf))) != 0) {
- smtpd_chat_reply(state, "%s", err);
- return (-1);
- }
+ err = smtpd_check_rcpt(state, STR(state->addr_buf));
if (smtpd_milters != 0
&& (state->saved_flags & MILTER_SKIP_FLAGS) == 0) {
PUSH_STRING(saved_rcpt, state->recipient, STR(state->addr_buf));
- err = milter_rcpt_event(smtpd_milters,
+ state->milter_reject_text = err;
+ milter_err = milter_rcpt_event(smtpd_milters,
+ err == 0 ? MILTER_FLAG_NONE :
+ MILTER_FLAG_WANT_RCPT_REJ,
milter_argv(state, argc - 2, argv + 2));
- if (err != 0) {
+ if (err == 0 && milter_err != 0) {
/* Log reject etc. with correct recipient information. */
- err = check_milter_reply(state, err);
+ err = check_milter_reply(state, milter_err);
}
POP_STRING(saved_rcpt, state->recipient);
- if (err != 0) {
- smtpd_chat_reply(state, "%s", err);
- return (-1);
- }
+ }
+ if (err != 0) {
+ smtpd_chat_reply(state, "%s", err);
+ return (-1);
}
}
diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h
index fc7ac56ed..3f921bcbd 100644
--- a/postfix/src/smtpd/smtpd.h
+++ b/postfix/src/smtpd/smtpd.h
@@ -176,8 +176,9 @@ typedef struct SMTPD_STATE {
/*
* Milter support.
*/
- const char **milter_argv;
- ssize_t milter_argc;
+ const char **milter_argv; /* SMTP command vector */
+ ssize_t milter_argc; /* SMTP command vector */
+ const char *milter_reject_text; /* input to call-back from Milter */
} SMTPD_STATE;
#define SMTPD_FLAG_HANGUP (1<<0) /* 421/521 disconnect */
diff --git a/postfix/src/smtpd/smtpd_chat.c b/postfix/src/smtpd/smtpd_chat.c
index e78f5936d..fac66d3d6 100644
--- a/postfix/src/smtpd/smtpd_chat.c
+++ b/postfix/src/smtpd/smtpd_chat.c
@@ -246,7 +246,7 @@ void smtpd_chat_notify(SMTPD_STATE *state)
notice = post_mail_fopen_nowait(mail_addr_double_bounce(),
var_error_rcpt,
- INT_FILT_NOTIFY,
+ INT_FILT_MASK_NOTIFY,
NULL_TRACE_FLAGS, NO_QUEUE_ID);
if (notice == 0) {
msg_warn("postmaster notify: %m");
diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c
index cbe8c69ed..1a18f92e3 100644
--- a/postfix/src/smtpd/smtpd_check.c
+++ b/postfix/src/smtpd/smtpd_check.c
@@ -244,6 +244,7 @@
#include "smtpd_sasl_glue.h"
#include "smtpd_check.h"
#include "smtpd_dsn_fix.h"
+#include "smtpd_resolve.h"
#define RESTRICTION_SEPARATORS ", \t\r\n"
@@ -264,7 +265,6 @@ static jmp_buf smtpd_check_buf;
* memory manager routines.
*/
static VSTRING *error_text;
-static CTABLE *smtpd_resolve_cache;
static CTABLE *smtpd_rbl_cache;
/*
@@ -435,48 +435,6 @@ typedef struct {
const char *txt; /* randomly selected trimmed TXT rr */
} SMTPD_RBL_EXPAND_CONTEXT;
-/* resolve_pagein - page in an address resolver result */
-
-static void *resolve_pagein(const char *addr, void *unused_context)
-{
- static VSTRING *query;
- RESOLVE_REPLY *reply;
-
- /*
- * Initialize on the fly.
- */
- if (query == 0)
- query = vstring_alloc(10);
-
- /*
- * Initialize.
- */
- reply = (RESOLVE_REPLY *) mymalloc(sizeof(*reply));
- resolve_clnt_init(reply);
-
- /*
- * Resolve the address.
- */
- rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, addr, query);
- resolve_clnt_query(STR(query), reply);
- lowercase(STR(reply->recipient));
-
- /*
- * Save the result.
- */
- return ((void *) reply);
-}
-
-/* resolve_pageout - page out an address resolver result */
-
-static void resolve_pageout(void *data, void *unused_context)
-{
- RESOLVE_REPLY *reply = (RESOLVE_REPLY *) data;
-
- resolve_clnt_free(reply);
- myfree((void *) reply);
-}
-
/* policy_client_register - register policy service endpoint */
static void policy_client_register(const char *name)
@@ -668,8 +626,7 @@ void smtpd_check_init(void)
* Initialize the resolved address cache. Note: the cache persists across
* SMTP sessions so we cannot make it dependent on session state.
*/
- smtpd_resolve_cache = ctable_create(100, resolve_pagein,
- resolve_pageout, (void *) 0);
+ smtpd_resolve_init(100);
/*
* Initialize the RBL lookup cache. Note: the cache persists across SMTP
@@ -1351,8 +1308,7 @@ static int permit_auth_destination(SMTPD_STATE *state, char *recipient)
/*
* Resolve the address.
*/
- reply = (const RESOLVE_REPLY *)
- ctable_locate(smtpd_resolve_cache, recipient);
+ reply = smtpd_resolve_addr(recipient);
if (reply->flags & RESOLVE_FLAG_FAIL)
reject_dict_retry(state, recipient);
@@ -1625,8 +1581,7 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient,
/*
* Resolve the address.
*/
- reply = (const RESOLVE_REPLY *)
- ctable_locate(smtpd_resolve_cache, recipient);
+ reply = smtpd_resolve_addr(recipient);
if (reply->flags & RESOLVE_FLAG_FAIL)
reject_dict_retry(state, recipient);
@@ -1794,7 +1749,7 @@ static int reject_unknown_address(SMTPD_STATE *state, const char *addr,
/*
* Resolve the address.
*/
- reply = (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, addr);
+ reply = smtpd_resolve_addr(addr);
if (reply->flags & RESOLVE_FLAG_FAIL)
reject_dict_retry(state, addr);
@@ -2733,7 +2688,7 @@ static int check_mail_access(SMTPD_STATE *state, const char *table,
/*
* Resolve the address.
*/
- reply = (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, addr);
+ reply = smtpd_resolve_addr(addr);
if (reply->flags & RESOLVE_FLAG_FAIL)
reject_dict_retry(state, addr);
@@ -3327,7 +3282,7 @@ static int reject_auth_sender_login_mismatch(SMTPD_STATE *state, const char *sen
* Reject if the client is logged in and does not own the sender address.
*/
if (smtpd_sasl_is_active(state) && state->sasl_username != 0) {
- reply = (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, sender);
+ reply = smtpd_resolve_addr(sender);
if (reply->flags & RESOLVE_FLAG_FAIL)
reject_dict_retry(state, sender);
if ((owners = check_mail_addr_find(state, sender, smtpd_sender_login_maps,
@@ -3360,7 +3315,7 @@ static int reject_unauth_sender_login_mismatch(SMTPD_STATE *state, const char *s
* owner.
*/
if (smtpd_sasl_is_active(state) && state->sasl_username == 0) {
- reply = (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, sender);
+ reply = smtpd_resolve_addr(sender);
if (reply->flags & RESOLVE_FLAG_FAIL)
reject_dict_retry(state, sender);
if (check_mail_addr_find(state, sender, smtpd_sender_login_maps,
@@ -4004,8 +3959,7 @@ int smtpd_check_addr(const char *addr)
*/
if (addr == 0 || *addr == 0)
return (0);
- resolve_reply = (const RESOLVE_REPLY *)
- ctable_locate(smtpd_resolve_cache, addr);
+ resolve_reply = smtpd_resolve_addr(addr);
if (resolve_reply->flags & RESOLVE_FLAG_ERROR)
return (-1);
return (0);
@@ -4430,8 +4384,7 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient,
/*
* Resolve the address.
*/
- reply = (const RESOLVE_REPLY *)
- ctable_locate(smtpd_resolve_cache, recipient);
+ reply = smtpd_resolve_addr(recipient);
if (reply->flags & RESOLVE_FLAG_FAIL)
reject_dict_retry(state, recipient);
diff --git a/postfix/src/smtpd/smtpd_milter.c b/postfix/src/smtpd/smtpd_milter.c
index 763e38e2b..2557b3dcc 100644
--- a/postfix/src/smtpd/smtpd_milter.c
+++ b/postfix/src/smtpd/smtpd_milter.c
@@ -33,6 +33,8 @@
/* Utility library. */
+#include
+
/* Global library. */
#include
@@ -46,6 +48,7 @@
#include
#include
+#include
#include
/*
@@ -58,13 +61,19 @@
const char *smtpd_milter_eval(const char *name, void *ptr)
{
SMTPD_STATE *state = (SMTPD_STATE *) ptr;
+ const RESOLVE_REPLY *reply;
+ char *cp;
+
+ /*
+ * On-the-fly initialization.
+ */
+ if (state->expand_buf == 0)
+ state->expand_buf = vstring_alloc(10);
/*
* Canonicalize the name.
*/
if (*name != '{') { /* } */
- if (state->expand_buf == 0)
- state->expand_buf = vstring_alloc(10);
vstring_sprintf(state->expand_buf, "{%s}", name);
name = STR(state->expand_buf);
}
@@ -81,8 +90,6 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
* Connect macros.
*/
if (strcmp(name, S8_MAC__) == 0) {
- if (state->expand_buf == 0)
- state->expand_buf = vstring_alloc(10);
vstring_sprintf(state->expand_buf, "%s [%s]",
state->reverse_name, state->addr);
if (strcasecmp(state->name, state->reverse_name) != 0)
@@ -96,8 +103,6 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
if (strcmp(name, S8_MAC_CLIENT_PORT) == 0)
return (strcmp(state->port, CLIENT_PORT_UNKNOWN) ? state->port : "0");
if (strcmp(name, S8_MAC_CLIENT_CONN) == 0) {
- if (state->expand_buf == 0)
- state->expand_buf = vstring_alloc(10);
vstring_sprintf(state->expand_buf, "%d", state->conn_count);
return (STR(state->expand_buf));
}
@@ -124,8 +129,6 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
if (strcmp(name, S8_MAC_CIPHER_BITS) == 0) {
if (state->tls_context == 0)
return (0);
- if (state->expand_buf == 0)
- state->expand_buf = vstring_alloc(10);
vstring_sprintf(state->expand_buf, "%d",
IF_ENCRYPTED(state->tls_context->cipher_usebits));
return (STR(state->expand_buf));
@@ -154,15 +157,28 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
if (strcmp(name, S8_MAC_MAIL_ADDR) == 0) {
if (state->sender == 0)
return (0);
- if (state->expand_buf == 0)
- state->expand_buf = vstring_alloc(10);
+ if (state->sender[0] == 0)
+ return ("");
+ reply = smtpd_resolve_addr(state->sender);
/* Sendmail 8.13 does not externalize the null string. */
- if (state->sender[0])
- quote_821_local(state->expand_buf, state->sender);
+ if (STR(reply->recipient)[0])
+ quote_821_local(state->expand_buf, STR(reply->recipient));
else
- vstring_strcpy(state->expand_buf, state->sender);
+ vstring_strcpy(state->expand_buf, STR(reply->recipient));
return (STR(state->expand_buf));
}
+ if (strcmp(name, S8_MAC_MAIL_HOST) == 0) {
+ if (state->sender == 0)
+ return (0);
+ reply = smtpd_resolve_addr(state->sender);
+ return (STR(reply->nexthop));
+ }
+ if (strcmp(name, S8_MAC_MAIL_MAILER) == 0) {
+ if (state->sender == 0)
+ return (0);
+ reply = smtpd_resolve_addr(state->sender);
+ return (STR(reply->transport));
+ }
/*
* RCPT TO macros.
@@ -170,14 +186,41 @@ const char *smtpd_milter_eval(const char *name, void *ptr)
if (strcmp(name, S8_MAC_RCPT_ADDR) == 0) {
if (state->recipient == 0)
return (0);
- if (state->expand_buf == 0)
- state->expand_buf = vstring_alloc(10);
+ if (state->recipient[0] == 0)
+ return ("");
+ if (state->milter_reject_text) {
+ /* 554 5.7.1 : Relay access denied */
+ vstring_strcpy(state->expand_buf, state->milter_reject_text + 4);
+ cp = split_at(STR(state->expand_buf), ' ');
+ return (cp ? split_at(cp, ' ') : cp);
+ }
+ reply = smtpd_resolve_addr(state->recipient);
/* Sendmail 8.13 does not externalize the null string. */
- if (state->recipient[0])
- quote_821_local(state->expand_buf, state->recipient);
+ if (STR(reply->recipient)[0])
+ quote_821_local(state->expand_buf, STR(reply->recipient));
else
- vstring_strcpy(state->expand_buf, state->recipient);
+ vstring_strcpy(state->expand_buf, STR(reply->recipient));
return (STR(state->expand_buf));
}
+ if (strcmp(name, S8_MAC_RCPT_HOST) == 0) {
+ if (state->recipient == 0)
+ return (0);
+ if (state->milter_reject_text) {
+ /* 554 5.7.1 : Relay access denied */
+ vstring_strcpy(state->expand_buf, state->milter_reject_text + 4);
+ (void) split_at(STR(state->expand_buf), ' ');
+ return (STR(state->expand_buf));
+ }
+ reply = smtpd_resolve_addr(state->recipient);
+ return (STR(reply->nexthop));
+ }
+ if (strcmp(name, S8_MAC_RCPT_MAILER) == 0) {
+ if (state->recipient == 0)
+ return (0);
+ if (state->milter_reject_text)
+ return (S8_RCPT_MAILER_ERROR);
+ reply = smtpd_resolve_addr(state->recipient);
+ return (STR(reply->transport));
+ }
return (0);
}
diff --git a/postfix/src/smtpd/smtpd_resolve.c b/postfix/src/smtpd/smtpd_resolve.c
new file mode 100644
index 000000000..2166ebb34
--- /dev/null
+++ b/postfix/src/smtpd/smtpd_resolve.c
@@ -0,0 +1,149 @@
+/*++
+/* NAME
+/* smtpd_resolve 3
+/* SUMMARY
+/* caching resolve client
+/* SYNOPSIS
+/* #include
+/*
+/* void smtpd_resolve_init(cache_size)
+/* int cache_size;
+/*
+/* const RESOLVE_REPLY *smtpd_resolve_addr(addr)
+/* const char *addr;
+/* DESCRIPTION
+/* This module maintains a resolve client cache that persists
+/* across SMTP sessions (not process life times). Addresses
+/* are always resolved in local rewriting context.
+/*
+/* smtpd_resolve_init() initializes the cache and must
+/* called once before the cache can be used.
+/*
+/* smtpd_resolve_addr() resolves one address or returns
+/* a known result from cache.
+/*
+/* Arguments:
+/* .IP cache_size
+/* The requested cache size.
+/* .IP addr
+/* The address to resolve.
+/* DIAGNOSTICS
+/* All errors are fatal.
+/* BUGS
+/* The recipient address is always case folded to lowercase.
+/* Changing this requires great care, since the address is used
+/* for policy lookups.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include
+
+/* Utility library. */
+
+#include
+#include
+#include
+#include
+#include
+
+/* Global library. */
+
+#include
+#include
+#include
+
+/* Application-specific. */
+
+#include
+
+static CTABLE *smtpd_resolve_cache;
+
+#define STR(x) vstring_str(x)
+
+/* resolve_pagein - page in an address resolver result */
+
+static void *resolve_pagein(const char *addr, void *unused_context)
+{
+ static VSTRING *query;
+ RESOLVE_REPLY *reply;
+
+ /*
+ * Initialize on the fly.
+ */
+ if (query == 0)
+ query = vstring_alloc(10);
+
+ /*
+ * Initialize.
+ */
+ reply = (RESOLVE_REPLY *) mymalloc(sizeof(*reply));
+ resolve_clnt_init(reply);
+
+ /*
+ * Resolve the address.
+ */
+ rewrite_clnt_internal(MAIL_ATTR_RWR_LOCAL, addr, query);
+ resolve_clnt_query(STR(query), reply);
+ lowercase(STR(reply->recipient)); /* XXX */
+
+ /*
+ * Save the result.
+ */
+ return ((void *) reply);
+}
+
+/* resolve_pageout - page out an address resolver result */
+
+static void resolve_pageout(void *data, void *unused_context)
+{
+ RESOLVE_REPLY *reply = (RESOLVE_REPLY *) data;
+
+ resolve_clnt_free(reply);
+ myfree((void *) reply);
+}
+
+/* smtpd_resolve_init - set up global cache */
+
+void smtpd_resolve_init(int cache_size)
+{
+
+ /*
+ * Sanity check.
+ */
+ if (smtpd_resolve_cache)
+ msg_panic("smtpd_resolve_init: multiple initialization");
+
+ /*
+ * Initialize the resolved address cache. Note: the cache persists across
+ * SMTP sessions so we cannot make it dependent on session state.
+ */
+ smtpd_resolve_cache = ctable_create(cache_size, resolve_pagein,
+ resolve_pageout, (void *) 0);
+}
+
+/* smtpd_resolve_addr - resolve cached addres */
+
+const RESOLVE_REPLY *smtpd_resolve_addr(const char *addr)
+{
+
+ /*
+ * Sanity check.
+ */
+ if (smtpd_resolve_cache == 0)
+ msg_panic("smtpd_resolve_addr: missing initialization");
+
+ /*
+ * Reply from the read-through cache.
+ */
+ return (const RESOLVE_REPLY *) ctable_locate(smtpd_resolve_cache, addr);
+}
diff --git a/postfix/src/smtpd/smtpd_resolve.h b/postfix/src/smtpd/smtpd_resolve.h
new file mode 100644
index 000000000..bfbc494da
--- /dev/null
+++ b/postfix/src/smtpd/smtpd_resolve.h
@@ -0,0 +1,38 @@
+/*++
+/* NAME
+/* smtpd_resolve 3h
+/* SUMMARY
+/* caching resolve client
+/* SYNOPSIS
+/* include
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Global library.
+ */
+#include
+
+ /*
+ * External interface.
+ */
+extern void smtpd_resolve_init(int);
+extern const RESOLVE_REPLY *smtpd_resolve_addr(const char *);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*
+/* TLS support originally by:
+/* Lutz Jaenicke
+/* BTU Cottbus
+/* Allgemeine Elektrotechnik
+/* Universitaetsplatz 3-4
+/* D-03044 Cottbus, Germany
+/*--*/
diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in
index 3db912c7e..de0172e2f 100644
--- a/postfix/src/util/Makefile.in
+++ b/postfix/src/util/Makefile.in
@@ -569,6 +569,7 @@ argv.o: sys_defs.h
argv_split.o: argv.h
argv_split.o: argv_split.c
argv_split.o: mymalloc.h
+argv_split.o: msg.h
argv_split.o: stringops.h
argv_split.o: sys_defs.h
argv_split.o: vbuf.h
diff --git a/postfix/src/util/argv.h b/postfix/src/util/argv.h
index f369c084d..b039fbb72 100644
--- a/postfix/src/util/argv.h
+++ b/postfix/src/util/argv.h
@@ -28,6 +28,7 @@ extern void argv_truncate(ARGV *, ssize_t);
extern ARGV *argv_free(ARGV *);
extern ARGV *argv_split(const char *, const char *);
+extern ARGV *argv_split_count(const char *, const char *, ssize_t);
extern ARGV *argv_split_append(ARGV *, const char *, const char *);
#define ARGV_END ((char *) 0)
diff --git a/postfix/src/util/argv_split.c b/postfix/src/util/argv_split.c
index d7e6bafa2..920bf399a 100644
--- a/postfix/src/util/argv_split.c
+++ b/postfix/src/util/argv_split.c
@@ -9,6 +9,10 @@
/* ARGV *argv_split(string, delim)
/* const char *string;
/*
+/* ARGV *argv_split_count(string, delim, count)
+/* const char *string;
+/* ssize_t count;
+/*
/* ARGV *argv_split_append(argv, string, delim)
/* ARGV *argv;
/* const char *string;
@@ -18,6 +22,11 @@
/* to the delimiters specified in \fIdelim\fR. The result is
/* a null-terminated string array.
/*
+/* argv_split_count() is like argv_split() but stops splitting
+/* input after at most \fIcount\fR -1 times and leaves the
+/* remainder, if any, in the last array element. It is an error
+/* to specify a count < 1.
+/*
/* argv_split_append() performs the same operation as argv_split(),
/* but appends the result to an existing string array.
/* SEE ALSO
@@ -38,12 +47,14 @@
/* System libraries. */
#include
+#include
/* Application-specific. */
#include "mymalloc.h"
#include "stringops.h"
#include "argv.h"
+#include "msg.h"
/* argv_split - split string into token array */
@@ -61,6 +72,28 @@ ARGV *argv_split(const char *string, const char *delim)
return (argvp);
}
+/* argv_split_count - split string into token array */
+
+ARGV *argv_split_count(const char *string, const char *delim, ssize_t count)
+{
+ ARGV *argvp = argv_alloc(1);
+ char *saved_string = mystrdup(string);
+ char *bp = saved_string;
+ char *arg;
+
+ if (count < 1)
+ msg_panic("argv_split_count: bad count: %ld", (long) count);
+ while (count-- > 1 && (arg = mystrtok(&bp, delim)) != 0)
+ argv_add(argvp, arg, (char *) 0);
+ if (*bp)
+ bp += strspn(bp, delim);
+ if (*bp)
+ argv_add(argvp, bp, (char *) 0);
+ argv_terminate(argvp);
+ myfree(saved_string);
+ return (argvp);
+}
+
/* argv_split_append - split string into token array, append to array */
ARGV *argv_split_append(ARGV *argvp, const char *string, const char *delim)
diff --git a/postfix/src/verify/verify.c b/postfix/src/verify/verify.c
index 803998428..6b04c8f00 100644
--- a/postfix/src/verify/verify.c
+++ b/postfix/src/verify/verify.c
@@ -471,7 +471,7 @@ static void verify_query_service(VSTREAM *client_stream)
STR(addr), addr_status, now, updated);
post_mail_fopen_async(strcmp(var_verify_sender, "<>") == 0 ?
"" : var_verify_sender, STR(addr),
- INT_FILT_NONE,
+ INT_FILT_MASK_NONE,
DEL_REQ_FLAG_MTA_VRFY,
(VSTRING *) 0,
verify_post_mail_action,
diff --git a/postfix/src/xsasl/xsasl_dovecot_server.c b/postfix/src/xsasl/xsasl_dovecot_server.c
index 4883d097e..4af958ebd 100644
--- a/postfix/src/xsasl/xsasl_dovecot_server.c
+++ b/postfix/src/xsasl/xsasl_dovecot_server.c
@@ -282,6 +282,7 @@ static int xsasl_dovecot_server_connect(XSASL_DOVECOT_SERVER_IMPL *xp)
VSTREAM_CTL_TIMEOUT, AUTH_TIMEOUT,
VSTREAM_CTL_END);
+ /* XXX Encapsulate for logging. */
vstream_fprintf(sasl_stream,
"VERSION\t%u\t%u\n"
"CPID\t%u\n",
@@ -294,6 +295,7 @@ static int xsasl_dovecot_server_connect(XSASL_DOVECOT_SERVER_IMPL *xp)
}
success = 0;
line_str = vstring_alloc(256);
+ /* XXX Encapsulate for logging. */
while (vstring_get_nonl(line_str, sasl_stream) != VSTREAM_EOF) {
line = vstring_str(line_str);
@@ -543,6 +545,7 @@ static int xsasl_dovecot_handle_reply(XSASL_DOVECOT_SERVER *server,
const char *myname = "xsasl_dovecot_handle_reply";
char *line, *cmd;
+ /* XXX Encapsulate for logging. */
while (vstring_get_nonl(server->sasl_line,
server->impl->sasl_stream) != VSTREAM_EOF) {
line = vstring_str(server->sasl_line);
@@ -637,12 +640,14 @@ int xsasl_dovecot_server_first(XSASL_SERVER *xp, const char *sasl_method,
}
/* send the request */
server->last_request_id = ++server->impl->request_id_counter;
+ /* XXX Encapsulate for logging. */
vstream_fprintf(server->impl->sasl_stream,
"AUTH\t%u\t%s\tservice=%s\tnologin\tlip=%s\trip=%s",
server->last_request_id, sasl_method,
server->service, server->server_addr,
server->client_addr);
if (server->tls_flag)
+ /* XXX Encapsulate for logging. */
vstream_fputs("\tsecured", server->impl->sasl_stream);
if (init_response) {
@@ -650,9 +655,11 @@ int xsasl_dovecot_server_first(XSASL_SERVER *xp, const char *sasl_method,
* initial response is already base64 encoded, so we can send it
* directly.
*/
+ /* XXX Encapsulate for logging. */
vstream_fprintf(server->impl->sasl_stream,
"\tresp=%s", init_response);
}
+ /* XXX Encapsulate for logging. */
VSTREAM_PUTC('\n', server->impl->sasl_stream);
if (vstream_fflush(server->impl->sasl_stream) != VSTREAM_EOF)
@@ -683,6 +690,7 @@ static int xsasl_dovecot_server_next(XSASL_SERVER *xp, const char *request,
vstring_strcpy(reply, "Invalid base64 data in continued response");
return XSASL_AUTH_FAIL;
}
+ /* XXX Encapsulate for logging. */
vstream_fprintf(server->impl->sasl_stream,
"CONT\t%u\t%s\n", server->last_request_id, request);
if (vstream_fflush(server->impl->sasl_stream) == VSTREAM_EOF) {