Bugfix (introduced 20100305) the new smtp_address_preference
feature was not tested with LMTP support. Problem reported
by Stefan Foerster. File: smtp/smtp.c.
+
+20100407
+
+ Bugfix (introduced 20100305): reject_rhsbl_reverse_client
+ was skipped if the forward-confirmed reverse DNS (FCRDNS)
+ remote SMTP client hostname was "unknown". Victor Duchovni.
+ File: smtpd/smtpd_check.c.
+
+20100422
+
+ Workaround (introduced: postfix-19990906 a.k.a. Postfix
+ 0.8.0). The Postfix local delivery agent did not properly
+ distinguish between "address has no extension" and "address
+ has an extension, but the extension is invalid". In both
+ cases it would run only the full recipient local-part through
+ the alias maps. Instead, it now drops the faulty extension
+ from the recipient address local-part (it would be too
+ error-prone to replace all tests for "no extension" by tests
+ for "no valid extension". File: local/recipient.c.
+
+20100430
+
+ Feature: customized hard/soft reject responses by Jason
+ Parsons. File: smtpstone/smtp-sink.c.
+
+20100515
+
+ Bugfix (introduced Postfix 2.6): the Postfix SMTP client
+ XFORWARD implementation did not skip "unknown" SMTP client
+ attributes, causing a syntax error when sending a PORT
+ attribute. Reported by Victor Duchovni. File: smtp/smtp_proto.c.
+
+20100526
+
+ Cleanup: a unit-test driver was not updated after an internal
+ API change. Vesa-Matti J Kari File: milter/milter.c.
+
+20100529
+
+ Portability: OpenSSL 1.0.0 changes the priority of anonymous
+ cyphers. Victor Duchovni. Files: postconf.proto,
+ global/mail_params.h, tls/tls_certkey.c, tls/tls_client.c,
+ tls/tls_dh.c, tls/tls_server.c.
+
+ Portability: Mac OS 10.6.3 requires <arpa/nameser_compat.h>
+ instead of <arpa/nameser8_compat.h>. Files: makedefs,
+ util/sys_defs.h, dns/dns.h.
+
+20100531
+
+ Robustness: skip LDAP queries with non-UTF-8 search strings
+ (in anticipation of UTF8SMTP support). File: global/dict_ldap.c.
+
+ Strict UTF-8 validator per RFC 3629. File: util/valid_utf_8.c.
+
+20100601
+
+ Feature: Postfix LDAP client support for RFC 2255 LDAP URLs.
+ Victor Duchovni. Files: proto/ldap_table global/dict_ldap.c.
+
+ Safety: Postfix processes log a warning when a matchlist
+ has a #comment at the end of a line (for example mynetworks
+ or relay_domains). File: util/match_list.c.
+
+ Portability: Berkeley DB 5.x has the same API as Berkeley
+ DB 4.1 and later. File: util/dict_db.c.
to=<yyyyyy@your.domain.here> proto=ESMTP helo=<zzzzzz>
What you see are lots of "user unknown" errors with "from=<>". These are error
-reports from MAILER-DAEMONs elsewhere on the Internet.
+reports from MAILER-DAEMONs elsewhere on the Internet, about email that was
+sent with a false sender address in your domain.
H\bHo\bow\bw d\bdo\bo I\bI b\bbl\blo\boc\bck\bk b\bba\bac\bck\bks\bsc\bca\bat\btt\bte\ber\br m\bma\bai\bil\bl t\bto\bo r\bra\ban\bnd\bdo\bom\bm r\bre\bec\bci\bip\bpi\bie\ben\bnt\bt a\bad\bdd\bdr\bre\bes\bss\bse\bes\bs?\b?
Postfix does not implement SASL itself, but instead uses existing
implementations as building blocks. This means that some SASL-related
-configuration will involve files that belong to Postfix, while other
-configuration will involve files that belong to the specific SASL
-implementation that Postfix will use. This document covers both the Postfix and
-non-Postfix configuration.
+configuration files will belong to Postfix, while other configuration files
+belong to the specific SASL implementation that Postfix will use. This document
+covers both the Postfix and non-Postfix configuration.
You can read more about the following topics:
A\bAU\bUT\bTH\bH P\bPL\bLA\bAI\bIN\bN A\bAH\bHR\bRl\blc\bc3\b3Q\bQA\bAd\bdG\bGV\bVz\bzd\bdH\bHB\bBh\bhc\bc3\b3M\bM=\b=
235 Authentication successful
+To test this over a connection that is encrypted with TLS, use openssl s_client
+instead of telnet:
+
+ % o\bop\bpe\ben\bns\bss\bsl\bl s\bs_\b_c\bcl\bli\bie\ben\bnt\bt -\b-c\bco\bon\bnn\bne\bec\bct\bt s\bse\ber\brv\bve\ber\br.\b.e\bex\bxa\bam\bmp\bpl\ble\be.\b.c\bco\bom\bm:\b:2\b25\b5 -\b-s\bst\bta\bar\brt\btt\btl\bls\bs s\bsm\bmt\btp\bp
+ ...
+ 220 server.example.com ESMTP Postfix
+ E\bEH\bHL\bLO\bO c\bcl\bli\bie\ben\bnt\bt.\b.e\bex\bxa\bam\bmp\bpl\ble\be.\b.c\bco\bom\bm
+ ...see above example for more...
+
Instead of AHRlc3QAdGVzdHBhc3M=, specify the base64-encoded form of
\0username\0password (the \0 is a null byte). The example above is for a user
named `test' with password `testpass'.
Remove this file from the stable release.
+ When an alias is a member of an :include: list with owner-
+ alias, local(8) needs an option to deliver alias or alias->user
+ indirectly. What happens when an :include: list with owner-
+ alias includes another list?
+
+ Don't allow empty result values in pcre and regexp maps.
+ Postfix doesn't allow them anywhere else (check this).
+
+ Make PCRE_MAX_CAPTURE configurable.
+
Add some checks for tokens starting with #. A challenge
is to report sensible context from the guts of some low-level
parser, without introducing a great deal of clumsiness.
state->milter_reject_text when expanding {rcpt_addr} or
{rcpt_host}.
- Find out why post_mail() etc. block when the qmgr fifo
- is full. This causes delays in the queue manager.
+ Find out why post_mail() etc. block when the qmgr fifo is
+ full (answer: trigger_timeout). How can this cause delays
+ in the queue manager? When a recipient bounces during
+ (transport, nexthop, address) resolution, it is redirected
+ to the error or retry mailer; and bounce-after-delivery is
+ asynchrounous so it can't block the queue manager, either.
Add smtpd_sender_login_maps to proxy_read_maps, and make
sure that defaults are set before proxy_read_maps is
</blockquote>
<p> What you see are lots of "user unknown" errors with "from=<>".
-These are error reports from MAILER-DAEMONs elsewhere on the Internet.
+These are error reports from MAILER-DAEMONs elsewhere on the Internet,
+about email that was sent with a false sender address in your domain.
</p>
<h2><a name="random">How do I block backscatter mail to random
<p> Postfix does not implement SASL itself, but instead uses existing
implementations as building blocks. This means that some SASL-related
-configuration will involve files that belong to Postfix, while other
-configuration will involve files that belong to the specific SASL
+configuration files will belong to Postfix, while other
+configuration files belong to the specific SASL
implementation that Postfix will use. This document covers both the
Postfix and non-Postfix configuration. </p>
</pre>
</blockquote>
+<p> To test this over a connection that is encrypted with TLS, use
+<code>openssl s_client</code> instead of <code>telnet</code>:
+
+<blockquote>
+<pre>
+% <strong>openssl s_client -connect server.example.com:25 -starttls smtp</strong>
+...
+220 server.example.com ESMTP Postfix
+<strong>EHLO client.example.com</strong>
+...see above example for more...
+</pre>
+</blockquote>
+
<p> Instead of <code>AHRlc3QAdGVzdHBhc3M=</code>, specify the
base64-encoded form of <code>\0username\0password</code> (the \0
is a null byte). The example above is for a user named `<code>test</code>'
result_attribute = mailbox, maildrop
+ Don't rely on the default value ("maildrop"). Set
+ the result_attribute explicitly in all ldap table
+ configuration files. This is particularly relevant
+ when no result_attribute is applicable, e.g. cases
+ in which leaf_result_attribute and/or termi-
+ nal_result_attribute are used instead. The default
+ value is harmless if "maildrop" is also listed as a
+ leaf or terminal result attribute, but it is best
+ to not leave this to chance.
+
<b>special_result_attribute (default: empty)</b>
The attribute(s) of directory entries that can con-
- tain DNs or URLs. If found, a recursive subsequent
- search is done using their values.
+ tain DNs or <a href="http://tools.ietf.org/html/rfc2255">RFC 2255</a> LDAP URLs. If found, a recur-
+ sive search is performed to retrieve the entry ref-
+ erenced by the DN, or the entries matched by the
+ URL query.
special_result_attribute = memberdn
DN recursion retrieves the same result_attributes
as the main query, including the special attributes
- for further recursion. URI processing retrieves
- only those attributes that are included in the URI
- definition and are *also* listed in
- "result_attribute". If the URI lists any of the
- map's special result attributes, these are also
- retrieved and used recursively.
+ for further recursion.
+
+ URL processing retrieves only those attributes that
+ are included in both the URL definition and as
+ result attributes (ordinary, special, leaf or ter-
+ minal) in the Postfix table definition. If the URL
+ lists any of the table's special result attributes,
+ these are retrieved and used recursively. A URL
+ that does not specify any attribute selection, is
+ equivalent (<a href="http://tools.ietf.org/html/rfc2255">RFC 2255</a>) to a URL that selects all
+ attributes, in which case the selected attributes
+ will be the full set of result attributes in the
+ Postfix table.
+
+ If an LDAP URL attribute-descriptor or the corre-
+ sponding Postfix LDAP table result attribute (but
+ not both) uses <a href="http://tools.ietf.org/html/rfc2255">RFC 2255</a> sub-type options
+ ("attr;option"), the attribute requested from the
+ LDAP server will include the sub-type option. In
+ all other cases, the URL attribute and the table
+ attribute must match exactly. Attributes with
+ options in both the URL and the Postfix table are
+ requested only when the options are identical. LDAP
+ attribute-descriptor options are very rarely used,
+ most LDAP users will not need to concern themselves
+ with this level of nuanced detail.
<b>terminal_result_attribute (default: empty)</b>
When one or more terminal result attributes are
the group is expanded, possibly via mailing-list
manager or other special processing.
+ result_attribute =
terminal_result_attribute = maildrop
+ When using terminal and/or leaf result attributes,
+ the result_attribute is best set to an empty value
+ when it is not used, or else explicitly set to the
+ desired value, even if it is the default value
+ "maildrop".
+
This feature is available with Postfix 2.4 or
later.
terminal_result_attribute = maildrop
leaf_result_attribute = mail
+ When using terminal and/or leaf result attributes,
+ the result_attribute is best set to an empty value
+ when it is not used, or else explicitly set to the
+ desired value, even if it is the default value
+ "maildrop".
+
This feature is available with Postfix 2.4 or
later.
</DD>
<DT><b><a name="address_verify_poll_count">address_verify_poll_count</a>
-(default: ${stress?1}${stress:3})</b></DT><DD>
+(default: normal: 3, overload: 1)</b></DT><DD>
<p>
How many times to query the <a href="verify.8.html">verify(8)</a> service for the completion
<p> Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself. </p>
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
</DD>
parameter. See there for details. </p>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
parameter. See there for details. </p>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
</dl>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
The blacklist has higher precedence than whitelists. This feature
never uses the remote SMTP client hostname. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
<p> Persistent storage for the <a href="postscreen.8.html">postscreen(8)</a> server decisions. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
</dl>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
<p> In either case, <a href="postscreen.8.html">postscreen(8)</a> will not whitelist the SMTP client
IP address. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
that they speak before their turn (pre-greet). Specify an empty
value to disable this feature. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
</dl>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
real SMTP server process. When this queue is full, all clients will
receive a 421 reponse. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
process. When this queue is full, all non-whitelisted clients will
receive a 421 reponse. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
the same address syntax as the <a href="postconf.5.html#mynetworks">mynetworks</a> parameter. This feature
never uses the remote SMTP client hostname. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
<p> Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself. </p>
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
<p>
Example:
<p> Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself. </p>
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
<p>
Example:
</pre>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
to anyone else. </p>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
are removed. The result value is executed by the Postfix SMTP
server. </p>
-<p> Postfix already implements a number of workarounds for malformed
-client commands. </p>
+<p> There is no need to use <a href="postconf.5.html#smtpd_command_filter">smtpd_command_filter</a> for the following
+cases: </p>
<ul>
"<i>user@ipaddress</i>". </p>
<li> <p> Postfix already accepts the correct form
-"<i>user@[ipaddress]</i>". </p>
+"<i>user@[ipaddress]</i>". Use <a href="postconf.5.html#virtual_alias_maps">virtual_alias_maps</a> or <a href="postconf.5.html#canonical_maps">canonical_maps</a>
+to translate these into domain names if necessary. </p>
-<li> <p> Use "<a href="postconf.5.html#strict_rfc821_envelopes">strict_rfc821_envelopes</a> = no" to accept "<i>User Name
-<user@example.com></i>". Postfix will ignore the "User Name"
-part before delivering the mail. </p>
+<li> <p> Use "<a href="postconf.5.html#strict_rfc821_envelopes">strict_rfc821_envelopes</a> = no" to accept "RCPT TO:<<i>User
+Name <user@example.com>></i>". Postfix will ignore the "User
+Name" part and deliver to the <user@example.com></i> address.
+</p>
</ul>
-<p> Examples: </p>
+<p> Examples of problems that can be solved with the <a href="postconf.5.html#smtpd_command_filter">smtpd_command_filter</a>
+feature: </p>
<pre>
/etc/postfix/<a href="postconf.5.html">main.cf</a>:
</DD>
<DT><b><a name="smtpd_hard_error_limit">smtpd_hard_error_limit</a>
-(default: normal: 20, stress: 1)</b></DT><DD>
+(default: normal: 20, overload: 1)</b></DT><DD>
<p>
The maximal number of errors a remote SMTP client is allowed to
make without delivering mail. The Postfix SMTP server disconnects
when the limit is exceeded. Normally the default limit is 20, but
-it changes under overload to just 1 with Postfix 2.6 and later.
+it changes under overload to just 1. With Postfix 2.5 and earlier,
+the SMTP server always allows up to 20 errors by default.
+
</p>
</DD>
<DT><b><a name="smtpd_junk_command_limit">smtpd_junk_command_limit</a>
-(default: normal: 100, stress: 1)</b></DT><DD>
+(default: normal: 100, overload: 1)</b></DT><DD>
<p>
The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote
command count is reset after mail is delivered. See also the
<a href="postconf.5.html#smtpd_error_sleep_time">smtpd_error_sleep_time</a> and <a href="postconf.5.html#smtpd_soft_error_limit">smtpd_soft_error_limit</a> configuration
parameters. Normally the default limit is 100, but it changes under
-overload to just 1 with Postfix 2.6 and later.
-</p>
+overload to just 1. With Postfix 2.5 and earlier, the SMTP server
+always allows up to 100 junk commands by default. </p>
</DD>
connections to. In a future version there may be different
classes of SMTP service. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
</DD>
</DD>
<DT><b><a name="smtpd_timeout">smtpd_timeout</a>
-(default: normal: 300s, stress: 10s)</b></DT><DD>
+(default: normal: 300s, overload: 10s)</b></DT><DD>
<p>
The time limit for sending a Postfix SMTP server response and for
receiving a remote SMTP client request. Normally the default limit
-is 300s, but it changes under overload to just 10s with Postfix 2.6
-and later.
+is 300s, but it changes under overload to just 10s. With Postfix
+2.5 and earlier, the SMTP server always uses a time limit of 300s
+by default.
</p>
<p>
</pre>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
to anyone else. </p>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
</dl>
<p> This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
latter name. </p>
<p> This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
classified as TOP SECRET. </p>
<p> This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
</DD>
<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> and <a href="postconf.5.html#lmtp_tls_mandatory_ciphers">lmtp_tls_mandatory_ciphers</a>. This is
the cipherlist for the opportunistic ("may") TLS client security
level and is the default cipherlist for the SMTP server. You are
-strongly encouraged to not change this setting. </p>
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases. </p>
<p> This feature is available in Postfix 2.3 and later. </p>
<p> The OpenSSL cipherlist for "HIGH" grade ciphers. This defines
the meaning of the "high" setting in <a href="postconf.5.html#smtpd_tls_mandatory_ciphers">smtpd_tls_mandatory_ciphers</a>,
<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> and <a href="postconf.5.html#lmtp_tls_mandatory_ciphers">lmtp_tls_mandatory_ciphers</a>. You are
-strongly encouraged to not change this setting. </p>
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases. </p>
<p> This feature is available in Postfix 2.3 and later. </p>
<p> The OpenSSL cipherlist for "LOW" or higher grade ciphers. This defines
the meaning of the "low" setting in <a href="postconf.5.html#smtpd_tls_mandatory_ciphers">smtpd_tls_mandatory_ciphers</a>,
<a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> and <a href="postconf.5.html#lmtp_tls_mandatory_ciphers">lmtp_tls_mandatory_ciphers</a>. You are
-strongly encouraged to not change this setting. </p>
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases. </p>
<p> This feature is available in Postfix 2.3 and later. </p>
the default cipherlist for mandatory TLS encryption in the TLS
client (with anonymous ciphers disabled when verifying server
certificates). You are strongly encouraged to not change this
-setting. </p>
+setting. With OpenSSL 1.0.0 and later the cipherlist may start with an
+"aNULL:" prefix, which restores the 0.9.8-compatible ordering of the
+aNULL ciphers to the top of the list when they are enabled. This prefix
+is not needed with previous OpenSSL releases. </p>
<p> This feature is available in Postfix 2.3 and later. </p>
attempt to block the client before it sends ".".
Specify a zero delay value to abort immediately.
+ <b>-b</b> <i>soft-bounce-reply</i>
+ Use <i>soft-bounce-reply</i> for soft reject responses.
+ The default reply is "450 4.3.0 Error: command
+ failed".
+
+ <b>-B</b> <i>hard-bounce-reply</i>
+ Use <i>hard-bounce-reply</i> for hard reject responses.
+ The default reply is "500 5.3.0 Error: command
+ failed".
+
<b>-c</b> Display running counters that are updated whenever
an SMTP session ends, a QUIT command is executed,
or when "." is received.
[1-6].*) CCARGS="$CCARGS -DNO_IPV6";;
*) CCARGS="$CCARGS -DBIND_8_COMPAT -DNO_NETINFO";;
esac
+ # Darwin 10.3.0 no longer has <arpa/nameser8_compat.h>.
+ case $RELEASE in
+ ?.*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_NAMESER8_COMPAT_H";;
+ *) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_NAMESER_COMPAT_H";;
+ esac
# kqueue and/or poll are broken up to and including MacOS X 10.5
CCARGS="$CCARGS -DNO_KQUEUE"
# # Darwin 8.11.1 has kqueue support, but let's play safe
further input from the client; this is an attempt to block
the client before it sends ".". Specify a zero delay value
to abort immediately.
+.IP "\fB-b \fIsoft-bounce-reply\fR"
+Use \fIsoft-bounce-reply\fR for soft reject responses. The
+default reply is "450 4.3.0 Error: command failed".
+.IP "\fB-B \fIhard-bounce-reply\fR"
+Use \fIhard-bounce-reply\fR for hard reject responses. The
+default reply is "500 5.3.0 Error: command failed".
.IP \fB-c\fR
Display running counters that are updated whenever an SMTP
session ends, a QUIT command is executed, or when "." is
.nf
result_attribute = mailbox, maildrop
.fi
+
+Don't rely on the default value ("maildrop"). Set the
+result_attribute explicitly in all ldap table configuration
+files. This is particularly relevant when no result_attribute
+is applicable, e.g. cases in which leaf_result_attribute and/or
+terminal_result_attribute are used instead. The default value
+is harmless if "maildrop" is also listed as a leaf or terminal
+result attribute, but it is best to not leave this to chance.
.IP "\fBspecial_result_attribute (default: empty)\fR"
The attribute(s) of directory entries that can contain DNs
-or URLs. If found, a recursive subsequent search is done
-using their values.
+or RFC 2255 LDAP URLs. If found, a recursive search
+is performed to retrieve the entry referenced by the DN, or
+the entries matched by the URL query.
.nf
special_result_attribute = memberdn
DN recursion retrieves the same result_attributes as the
main query, including the special attributes for further
-recursion. URI processing retrieves only those attributes
-that are included in the URI definition and are *also*
-listed in "result_attribute". If the URI lists any of the
-map's special result attributes, these are also retrieved
-and used recursively.
+recursion.
+
+URL processing retrieves only those attributes that are included
+in both the URL definition and as result attributes (ordinary,
+special, leaf or terminal) in the Postfix table definition.
+If the URL lists any of the table's special result attributes,
+these are retrieved and used recursively. A URL that does not
+specify any attribute selection, is equivalent (RFC 2255) to a
+URL that selects all attributes, in which case the selected
+attributes will be the full set of result attributes in the
+Postfix table.
+
+If an LDAP URL attribute-descriptor or the corresponding Postfix
+LDAP table result attribute (but not both) uses RFC 2255 sub-type
+options ("attr;option"), the attribute requested from the LDAP server
+will include the sub-type option. In all other cases, the URL
+attribute and the table attribute must match exactly. Attributes
+with options in both the URL and the Postfix table are requested
+only when the options are identical. LDAP attribute-descriptor
+options are very rarely used, most LDAP users will not
+need to concern themselves with this level of nuanced detail.
.IP "\fBterminal_result_attribute (default: empty)\fR"
When one or more terminal result attributes are found in an LDAP
entry, all other result attributes are ignored and only the terminal
other special processing.
.nf
+ result_attribute =
terminal_result_attribute = maildrop
.fi
+When using terminal and/or leaf result attributes, the
+result_attribute is best set to an empty value when it is not
+used, or else explicitly set to the desired value, even if it is
+the default value "maildrop".
+
This feature is available with Postfix 2.4 or later.
.IP "\fBleaf_result_attribute (default: empty)\fR"
When one or more special result attributes are found in a non-terminal
leaf_result_attribute = mail
.fi
+When using terminal and/or leaf result attributes, the
+result_attribute is best set to an empty value when it is not
+used, or else explicitly set to the desired value, even if it is
+the default value "maildrop".
+
This feature is available with Postfix 2.4 or later.
.IP "\fBscope (default: sub)\fR"
The LDAP search scope: \fBsub\fR, \fBbase\fR, or \fBone\fR.
Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
.PP
This feature is available in Postfix 2.1 and later.
-.SH address_verify_poll_count (default: ${stress?1}${stress:3})
+.SH address_verify_poll_count (default: normal: 3, overload: 1)
How many times to query the \fBverify\fR(8) service for the completion
of an address verification request in progress.
.PP
.PP
Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself.
+after Postfix forwards mail internally, or after Postfix generates
+mail itself.
.SH anvil_rate_time_unit (default: 60s)
The time unit over which client connection rates and other rates
are calculated.
parameter. See there for details.
.PP
This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH lmtp_tls_eckey_file (default: empty)
The LMTP-specific version of the smtp_tls_eckey_file configuration
parameter. See there for details.
.PP
This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH lmtp_tls_enforce_peername (default: yes)
The LMTP-specific version of the smtp_tls_enforce_peername
configuration parameter. See there for details.
Drop the connection immediately with a 521 SMTP reply, without
reporting PREGREET, HANGUP or DNSBL results.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_blacklist_networks (default: empty)
Network addresses that are permanently blacklisted; see the
postscreen_blacklist_action parameter for possible actions. This
The blacklist has higher precedence than whitelists. This feature
never uses the remote SMTP client hostname.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_cache_cleanup_interval (default: 12h)
The amount of time between \fBpostscreen\fR(8) cache cleanup runs.
Cache cleanup increases the load on the cache database and should
Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks).
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_cache_map (default: btree:$data_directory/ps_whitelist)
Persistent storage for the \fBpostscreen\fR(8) server decisions.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_cache_retention_time (default: 1d)
The amount of time that \fBpostscreen\fR(8) will cache an expired
temporary whitelist entry before it is removed. This prevents clients
Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks).
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_cache_ttl (default: 1d)
The amount of time that \fBpostscreen\fR(8) will cache a decision for
a specific SMTP client IP address. During this time, the client IP
Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks).
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_dnsbl_action (default: continue)
The action that \fBpostscreen\fR(8) takes when an SMTP client is listed
at the DNS blocklist domains specified with the postscreen_dnsbl_sites
.IP "drop"
Drop the connection with a 521 SMTP reply.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_dnsbl_sites (default: empty)
Optional list of DNS blocklist domains. When the list is non-enpty,
the \fBdnsblog\fR(8) daemon will query these domains with the IP addresses
In either case, \fBpostscreen\fR(8) will not whitelist the SMTP client
IP address.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_greet_banner (default: $smtpd_banner)
The \fItext\fR in the optional "220-\fItext\fR..." server
response that
that they speak before their turn (pre-greet). Specify an empty
value to disable this feature.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_greet_wait (default: 4s)
The amount of time that \fBpostscreen\fR(8) will wait for an SMTP
client to send a command before its turn, and for DNS blocklist
Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks).
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_hangup_action (default: continue)
The action that \fBpostscreen\fR(8) takes when an SMTP client disconnects
without sending data, within the time specified with the
Drop the connection immediately, without reporting DNSBL lookup
results.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_post_queue_limit (default: $default_process_limit)
The number of clients that can be waiting for service from a
real SMTP server process. When this queue is full, all clients will
receive a 421 reponse.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_pre_queue_limit (default: $default_process_limit)
The number of non-whitelisted clients that can be waiting for
a decision whether they will receive service from a real SMTP server
process. When this queue is full, all non-whitelisted clients will
receive a 421 reponse.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH postscreen_whitelist_networks (default: $mynetworks)
Network addresses that are permanently whitelisted, and that
will not be subjected to \fBpostscreen\fR(8) checks. This parameter uses
the same address syntax as the mynetworks parameter. This feature
never uses the remote SMTP client hostname.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH prepend_delivered_header (default: command, file, forward)
The message delivery contexts where the Postfix \fBlocal\fR(8) delivery
agent prepends a Delivered-To: message header with the address
.PP
Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself.
+after Postfix forwards mail internally, or after Postfix generates
+mail itself.
.PP
Example:
.PP
.PP
Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself.
+after Postfix forwards mail internally, or after Postfix generates
+mail itself.
.PP
Example:
.PP
.ft R
.PP
This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH smtp_tls_eckey_file (default: $smtp_tls_eccert_file)
File with the Postfix SMTP client ECDSA private key in PEM format.
This file may be combined with the Postfix SMTP client ECDSA
to anyone else.
.PP
This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH smtp_tls_enforce_peername (default: yes)
With mandatory TLS encryption, require that the remote SMTP
server hostname matches the information in the remote SMTP server
are removed. The result value is executed by the Postfix SMTP
server.
.PP
-Postfix already implements a number of workarounds for malformed
-client commands.
+There is no need to use smtpd_command_filter for the following
+cases:
.IP \(bu
Use "resolve_numeric_domain = yes" to accept
"\fIuser@ipaddress\fR".
.IP \(bu
Postfix already accepts the correct form
-"\fIuser@[ipaddress]\fR".
+"\fIuser@[ipaddress]\fR". Use virtual_alias_maps or canonical_maps
+to translate these into domain names if necessary.
.IP \(bu
-Use "strict_rfc821_envelopes = no" to accept "\fIUser Name
-<user@example.com>\fR". Postfix will ignore the "User Name"
-part before delivering the mail.
+Use "strict_rfc821_envelopes = no" to accept "RCPT TO:<\fIUser
+Name <user@example.com>>\fR". Postfix will ignore the "User
+Name" part and deliver to the <user@example.com>\fR address.
.PP
-Examples:
+Examples of problems that can be solved with the smtpd_command_filter
+feature:
.PP
.nf
.na
format of message headers will also cause a disconnect.
.PP
This feature is available in Postfix 2.2 and later.
-.SH smtpd_hard_error_limit (default: normal: 20, stress: 1)
+.SH smtpd_hard_error_limit (default: normal: 20, overload: 1)
The maximal number of errors a remote SMTP client is allowed to
make without delivering mail. The Postfix SMTP server disconnects
when the limit is exceeded. Normally the default limit is 20, but
-it changes under overload to just 1 with Postfix 2.6 and later.
+it changes under overload to just 1. With Postfix 2.5 and earlier,
+the SMTP server always allows up to 20 errors by default.
.SH smtpd_helo_required (default: no)
Require that a remote SMTP client introduces itself with the HELO
or EHLO command before sending the MAIL command or other commands
.SH smtpd_history_flush_threshold (default: 100)
The maximal number of lines in the Postfix SMTP server command history
before it is flushed upon receipt of EHLO, RSET, or end of DATA.
-.SH smtpd_junk_command_limit (default: normal: 100, stress: 1)
+.SH smtpd_junk_command_limit (default: normal: 100, overload: 1)
The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote
SMTP client can send before the Postfix SMTP server starts to
increment the error counter with each junk command. The junk
command count is reset after mail is delivered. See also the
smtpd_error_sleep_time and smtpd_soft_error_limit configuration
parameters. Normally the default limit is 100, but it changes under
-overload to just 1 with Postfix 2.6 and later.
+overload to just 1. With Postfix 2.5 and earlier, the SMTP server
+always allows up to 100 junk commands by default.
.SH smtpd_milters (default: empty)
A list of Milter (mail filter) applications for new mail that
arrives via the Postfix \fBsmtpd\fR(8) server. See the MILTER_README
connections to. In a future version there may be different
classes of SMTP service.
.PP
-This feature is available in Postfix 2.7.
+This feature is available in Postfix 2.8.
.SH smtpd_soft_error_limit (default: 10)
The number of errors a remote SMTP client is allowed to make without
delivering mail before the Postfix SMTP server slows down all its
during TLS startup and shutdown handshake procedures.
.PP
This feature is available in Postfix 2.2 and later.
-.SH smtpd_timeout (default: normal: 300s, stress: 10s)
+.SH smtpd_timeout (default: normal: 300s, overload: 10s)
The time limit for sending a Postfix SMTP server response and for
receiving a remote SMTP client request. Normally the default limit
-is 300s, but it changes under overload to just 10s with Postfix 2.6
-and later.
+is 300s, but it changes under overload to just 10s. With Postfix
+2.5 and earlier, the SMTP server always uses a time limit of 300s
+by default.
.PP
Note: if you set SMTP time limits to very large values you may have
to update the global ipc_timeout parameter.
.ft R
.PP
This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH smtpd_tls_eckey_file (default: $smtpd_tls_eccert_file)
File with the Postfix SMTP server ECDSA private key in PEM format.
This file may be combined with the Postfix SMTP server ECDSA certificate
to anyone else.
.PP
This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH smtpd_tls_eecdh_grade (default: see "postconf -d" output)
The Postfix SMTP server security grade for ephemeral elliptic-curve
Diffie-Hellman (EECDH) key exchange.
users.
.PP
This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH smtpd_tls_exclude_ciphers (default: empty)
List of ciphers or cipher types to exclude from the SMTP server
cipher list at all TLS security levels. Excluding valid ciphers
latter name.
.PP
This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH tls_eecdh_ultra_curve (default: secp384r1)
The elliptic curve used by the SMTP server for maximally strong
ephemeral ECDH key exchange. This curve is used by the Postfix SMTP
classified as TOP SECRET.
.PP
This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later.
+compiled and linked with OpenSSL 1.0.0 or later.
.SH tls_export_cipherlist (default: ALL:+RC4:@STRENGTH)
The OpenSSL cipherlist for "EXPORT" or higher grade ciphers. This
defines the meaning of the "export" setting in smtpd_tls_mandatory_ciphers,
smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. This is
the cipherlist for the opportunistic ("may") TLS client security
level and is the default cipherlist for the SMTP server. You are
-strongly encouraged to not change this setting.
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases.
.PP
This feature is available in Postfix 2.3 and later.
.SH tls_high_cipherlist (default: ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH)
The OpenSSL cipherlist for "HIGH" grade ciphers. This defines
the meaning of the "high" setting in smtpd_tls_mandatory_ciphers,
smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are
-strongly encouraged to not change this setting.
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases.
.PP
This feature is available in Postfix 2.3 and later.
.SH tls_low_cipherlist (default: ALL:!EXPORT:+RC4:@STRENGTH)
The OpenSSL cipherlist for "LOW" or higher grade ciphers. This defines
the meaning of the "low" setting in smtpd_tls_mandatory_ciphers,
smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are
-strongly encouraged to not change this setting.
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases.
.PP
This feature is available in Postfix 2.3 and later.
.SH tls_medium_cipherlist (default: ALL:!EXPORT:!LOW:+RC4:@STRENGTH)
the default cipherlist for mandatory TLS encryption in the TLS
client (with anonymous ciphers disabled when verifying server
certificates). You are strongly encouraged to not change this
-setting.
+setting. With OpenSSL 1.0.0 and later the cipherlist may start with an
+"aNULL:" prefix, which restores the 0.9.8-compatible ordering of the
+aNULL ciphers to the top of the list when they are enabled. This prefix
+is not needed with previous OpenSSL releases.
.PP
This feature is available in Postfix 2.3 and later.
.SH tls_null_cipherlist (default: eNULL:!aNULL)
</blockquote>
<p> What you see are lots of "user unknown" errors with "from=<>".
-These are error reports from MAILER-DAEMONs elsewhere on the Internet.
+These are error reports from MAILER-DAEMONs elsewhere on the Internet,
+about email that was sent with a false sender address in your domain.
</p>
<h2><a name="random">How do I block backscatter mail to random
<p> Postfix does not implement SASL itself, but instead uses existing
implementations as building blocks. This means that some SASL-related
-configuration will involve files that belong to Postfix, while other
-configuration will involve files that belong to the specific SASL
+configuration files will belong to Postfix, while other
+configuration files belong to the specific SASL
implementation that Postfix will use. This document covers both the
Postfix and non-Postfix configuration. </p>
</pre>
</blockquote>
+<p> To test this over a connection that is encrypted with TLS, use
+<code>openssl s_client</code> instead of <code>telnet</code>:
+
+<blockquote>
+<pre>
+% <strong>openssl s_client -connect server.example.com:25 -starttls smtp</strong>
+...
+220 server.example.com ESMTP Postfix
+<strong>EHLO client.example.com</strong>
+...see above example for more...
+</pre>
+</blockquote>
+
<p> Instead of <code>AHRlc3QAdGVzdHBhc3M=</code>, specify the
base64-encoded form of <code>\0username\0password</code> (the \0
is a null byte). The example above is for a user named `<code>test</code>'
# .nf
# result_attribute = mailbox, maildrop
# .fi
+#
+# Don't rely on the default value ("maildrop"). Set the
+# result_attribute explicitly in all ldap table configuration
+# files. This is particularly relevant when no result_attribute
+# is applicable, e.g. cases in which leaf_result_attribute and/or
+# terminal_result_attribute are used instead. The default value
+# is harmless if "maildrop" is also listed as a leaf or terminal
+# result attribute, but it is best to not leave this to chance.
# .IP "\fBspecial_result_attribute (default: empty)\fR"
# The attribute(s) of directory entries that can contain DNs
-# or URLs. If found, a recursive subsequent search is done
-# using their values.
+# or RFC 2255 LDAP URLs. If found, a recursive search
+# is performed to retrieve the entry referenced by the DN, or
+# the entries matched by the URL query.
#
# .nf
# special_result_attribute = memberdn
#
# DN recursion retrieves the same result_attributes as the
# main query, including the special attributes for further
-# recursion. URI processing retrieves only those attributes
-# that are included in the URI definition and are *also*
-# listed in "result_attribute". If the URI lists any of the
-# map's special result attributes, these are also retrieved
-# and used recursively.
+# recursion.
+#
+# URL processing retrieves only those attributes that are included
+# in both the URL definition and as result attributes (ordinary,
+# special, leaf or terminal) in the Postfix table definition.
+# If the URL lists any of the table's special result attributes,
+# these are retrieved and used recursively. A URL that does not
+# specify any attribute selection, is equivalent (RFC 2255) to a
+# URL that selects all attributes, in which case the selected
+# attributes will be the full set of result attributes in the
+# Postfix table.
+#
+# If an LDAP URL attribute-descriptor or the corresponding Postfix
+# LDAP table result attribute (but not both) uses RFC 2255 sub-type
+# options ("attr;option"), the attribute requested from the LDAP server
+# will include the sub-type option. In all other cases, the URL
+# attribute and the table attribute must match exactly. Attributes
+# with options in both the URL and the Postfix table are requested
+# only when the options are identical. LDAP attribute-descriptor
+# options are very rarely used, most LDAP users will not
+# need to concern themselves with this level of nuanced detail.
# .IP "\fBterminal_result_attribute (default: empty)\fR"
# When one or more terminal result attributes are found in an LDAP
# entry, all other result attributes are ignored and only the terminal
# other special processing.
#
# .nf
+# result_attribute =
# terminal_result_attribute = maildrop
# .fi
#
+# When using terminal and/or leaf result attributes, the
+# result_attribute is best set to an empty value when it is not
+# used, or else explicitly set to the desired value, even if it is
+# the default value "maildrop".
+#
# This feature is available with Postfix 2.4 or later.
# .IP "\fBleaf_result_attribute (default: empty)\fR"
# When one or more special result attributes are found in a non-terminal
# leaf_result_attribute = mail
# .fi
#
+# When using terminal and/or leaf result attributes, the
+# result_attribute is best set to an empty value when it is not
+# used, or else explicitly set to the desired value, even if it is
+# the default value "maildrop".
+#
# This feature is available with Postfix 2.4 or later.
# .IP "\fBscope (default: sub)\fR"
# The LDAP search scope: \fBsub\fR, \fBbase\fR, or \fBone\fR.
<p> This feature is available in Postfix 2.7. </p>
-%PARAM address_verify_poll_count ${stress?1}${stress:3}
+%PARAM address_verify_poll_count normal: 3, overload: 1
<p>
How many times to query the verify(8) service for the completion
<p> Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself. </p>
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
%PARAM berkeley_db_create_buffer_size 16777216
<p> Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself. </p>
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
<p>
Example:
<p> Note: automatic BCC recipients are produced only for new mail.
To avoid mailer loops, automatic BCC recipients are not generated
-for mail that Postfix forwards internally, nor for mail that Postfix
-generates itself. </p>
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
<p>
Example:
</ul>
-%PARAM smtpd_hard_error_limit normal: 20, stress: 1
+%PARAM smtpd_hard_error_limit normal: 20, overload: 1
<p>
The maximal number of errors a remote SMTP client is allowed to
make without delivering mail. The Postfix SMTP server disconnects
when the limit is exceeded. Normally the default limit is 20, but
-it changes under overload to just 1 with Postfix 2.6 and later.
+it changes under overload to just 1. With Postfix 2.5 and earlier,
+the SMTP server always allows up to 20 errors by default.
+
</p>
-%PARAM smtpd_junk_command_limit normal: 100, stress: 1
+%PARAM smtpd_junk_command_limit normal: 100, overload: 1
<p>
The number of junk commands (NOOP, VRFY, ETRN or RSET) that a remote
command count is reset after mail is delivered. See also the
smtpd_error_sleep_time and smtpd_soft_error_limit configuration
parameters. Normally the default limit is 100, but it changes under
-overload to just 1 with Postfix 2.6 and later.
-</p>
+overload to just 1. With Postfix 2.5 and earlier, the SMTP server
+always allows up to 100 junk commands by default. </p>
%PARAM smtpd_recipient_overshoot_limit 1000
check_sender_access hash:/etc/postfix/access
</pre>
-%PARAM smtpd_timeout normal: 300s, stress: 10s
+%PARAM smtpd_timeout normal: 300s, overload: 10s
<p>
The time limit for sending a Postfix SMTP server response and for
receiving a remote SMTP client request. Normally the default limit
-is 300s, but it changes under overload to just 10s with Postfix 2.6
-and later.
+is 300s, but it changes under overload to just 10s. With Postfix
+2.5 and earlier, the SMTP server always uses a time limit of 300s
+by default.
</p>
<p>
<p> The OpenSSL cipherlist for "HIGH" grade ciphers. This defines
the meaning of the "high" setting in smtpd_tls_mandatory_ciphers,
smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are
-strongly encouraged to not change this setting. </p>
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases. </p>
<p> This feature is available in Postfix 2.3 and later. </p>
the default cipherlist for mandatory TLS encryption in the TLS
client (with anonymous ciphers disabled when verifying server
certificates). You are strongly encouraged to not change this
-setting. </p>
+setting. With OpenSSL 1.0.0 and later the cipherlist may start with an
+"aNULL:" prefix, which restores the 0.9.8-compatible ordering of the
+aNULL ciphers to the top of the list when they are enabled. This prefix
+is not needed with previous OpenSSL releases. </p>
<p> This feature is available in Postfix 2.3 and later. </p>
<p> The OpenSSL cipherlist for "LOW" or higher grade ciphers. This defines
the meaning of the "low" setting in smtpd_tls_mandatory_ciphers,
smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. You are
-strongly encouraged to not change this setting. </p>
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases. </p>
<p> This feature is available in Postfix 2.3 and later. </p>
smtp_tls_mandatory_ciphers and lmtp_tls_mandatory_ciphers. This is
the cipherlist for the opportunistic ("may") TLS client security
level and is the default cipherlist for the SMTP server. You are
-strongly encouraged to not change this setting. </p>
+strongly encouraged to not change this setting. With OpenSSL 1.0.0 and
+later the cipherlist may start with an "aNULL:" prefix, which restores
+the 0.9.8-compatible ordering of the aNULL ciphers to the top of the
+list when they are enabled. This prefix is not needed with previous
+OpenSSL releases. </p>
<p> This feature is available in Postfix 2.3 and later. </p>
latter name. </p>
<p> This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM tls_eecdh_ultra_curve secp384r1
classified as TOP SECRET. </p>
<p> This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM smtpd_tls_eecdh_grade see "postconf -d" output
</dl>
<p> This feature is available in Postfix 2.6 and later, when it is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM smtpd_tls_eccert_file
</pre>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM smtpd_tls_eckey_file $smtpd_tls_eccert_file
to anyone else. </p>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM smtp_tls_eccert_file
</pre>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM smtp_tls_eckey_file $smtp_tls_eccert_file
to anyone else. </p>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM lmtp_tls_eccert_file
parameter. See there for details. </p>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM lmtp_tls_eckey_file
parameter. See there for details. </p>
<p> This feature is available in Postfix 2.6 and later, when Postfix is
-compiled and linked with OpenSSL 0.9.9 or later. </p>
+compiled and linked with OpenSSL 1.0.0 or later. </p>
%PARAM smtp_header_checks
<p> Persistent storage for the postscreen(8) server decisions. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM smtpd_service smtpd
connections to. In a future version there may be different
classes of SMTP service. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_post_queue_limit $default_process_limit
real SMTP server process. When this queue is full, all clients will
receive a 421 reponse. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_pre_queue_limit $default_process_limit
process. When this queue is full, all non-whitelisted clients will
receive a 421 reponse. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_cache_ttl 1d
<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_cache_retention_time 1d
<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_cache_cleanup_interval 12h
<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_greet_wait 4s
<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
(weeks). </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_dnsbl_sites
</dl>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_greet_action continue
<p> In either case, postscreen(8) will not whitelist the SMTP client
IP address. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_hangup_action continue
</dl>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_whitelist_networks $mynetworks
the same address syntax as the mynetworks parameter. This feature
never uses the remote SMTP client hostname. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_blacklist_networks
The blacklist has higher precedence than whitelists. This feature
never uses the remote SMTP client hostname. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_greet_banner $smtpd_banner
that they speak before their turn (pre-greet). Specify an empty
value to disable this feature. </p>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM postscreen_blacklist_action continue
</dl>
-<p> This feature is available in Postfix 2.7. </p>
+<p> This feature is available in Postfix 2.8. </p>
%PARAM smtpd_command_filter
are removed. The result value is executed by the Postfix SMTP
server. </p>
-<p> Postfix already implements a number of workarounds for malformed
-client commands. </p>
+<p> There is no need to use smtpd_command_filter for the following
+cases: </p>
<ul>
"<i>user@ipaddress</i>". </p>
<li> <p> Postfix already accepts the correct form
-"<i>user@[ipaddress]</i>". </p>
+"<i>user@[ipaddress]</i>". Use virtual_alias_maps or canonical_maps
+to translate these into domain names if necessary. </p>
-<li> <p> Use "strict_rfc821_envelopes = no" to accept "<i>User Name
-<user@example.com></i>". Postfix will ignore the "User Name"
-part before delivering the mail. </p>
+<li> <p> Use "strict_rfc821_envelopes = no" to accept "RCPT TO:<<i>User
+Name <user@example.com>></i>". Postfix will ignore the "User
+Name" part and deliver to the <user@example.com></i> address.
+</p>
</ul>
-<p> Examples: </p>
+<p> Examples of problems that can be solved with the smtpd_command_filter
+feature: </p>
<pre>
/etc/postfix/main.cf:
#ifdef RESOLVE_H_NEEDS_NAMESER8_COMPAT_H
#include <nameser8_compat.h>
#endif
+#ifdef RESOLVE_H_NEEDS_NAMESER_COMPAT_H
+#include <nameser_compat.h>
+#endif
#include <resolv.h>
/*
vstring_free(keybuf);
}
+/* attr_sub_type - Is one of two attributes a sub-type of another */
+
+static int attrdesc_subtype(const char *a1, const char *a2)
+{
+
+ /*
+ * RFC 2251 section 4.1.4: LDAP attribute names are case insensitive
+ */
+ while (*a1 && TOLOWER(*a1) == TOLOWER(*a2))
+ ++a1, ++a2;
+
+ /*
+ * Names equal to end of a1, is a2 equal or a subtype?
+ */
+ if (*a1 == 0 && (*a2 == 0 || *a2 == ';'))
+ return (1);
+
+ /*
+ * Names equal to end of a2, is a1 a subtype?
+ */
+ if (*a2 == 0 && *a1 == ';')
+ return (-1);
+
+ /*
+ * Distinct attributes
+ */
+ return (0);
+}
+
+/* url_attrs - attributes we want from LDAP URL */
+
+static char **url_attrs(DICT_LDAP *dict_ldap, LDAPURLDesc * url)
+{
+ static ARGV *attrs;
+ char **a1;
+ char **a2;
+ int arel;
+
+ /*
+ * If the LDAP URI specified no attributes, all entry attributes are
+ * returned, leading to unnecessarily large LDAP results, particularly
+ * since dynamic groups are most useful for large groups.
+ *
+ * Since we only make use of the various mumble_results attributes, we ask
+ * only for these, thus making large queries much faster.
+ *
+ * In one test case, a query returning 75K users took 16 minutes when all
+ * attributes are returned, and just under 3 minutes with only the
+ * desired result attribute.
+ */
+ if (url->lud_attrs == 0 || *url->lud_attrs == 0)
+ return (dict_ldap->result_attributes->argv);
+
+ /*
+ * When the LDAP URI explicitly specifies a set of attributes, we use the
+ * interection of the URI attributes and our result attributes. This way
+ * LDAP URIs can hide certain attributes that should not be part of the
+ * query. There is no point in retrieving attributes not listed in our
+ * result set, we won't make any use of those.
+ */
+ if (attrs)
+ argv_truncate(attrs, 0);
+ else
+ attrs = argv_alloc(2);
+
+ /*
+ * Retrieve only those attributes that are of interest to us.
+ *
+ * If the URL attribute and the attribute we want differ only in the
+ * "options" part of the attribute descriptor, select the more specific
+ * attribute descriptor.
+ */
+ for (a1 = url->lud_attrs; *a1; ++a1) {
+ for (a2 = dict_ldap->result_attributes->argv; *a2; ++a2) {
+ arel = attrdesc_subtype(*a1, *a2);
+ if (arel > 0)
+ argv_add(attrs, *a2, ARGV_END);
+ else if (arel < 0)
+ argv_add(attrs, *a1, ARGV_END);
+ }
+ }
+
+ return ((attrs->argc > 0) ? attrs->argv : 0);
+}
+
/*
* dict_ldap_get_values: for each entry returned by a search, get the values
* of all its attributes. Recurses to resolve any DN or URL values found.
LDAPMessage *entry = 0;
BerElement *ber;
char *attr;
+ char **attrs;
struct berval **vals;
int valcount;
LDAPURLDesc *url;
/*
* The "result_attributes" list enumerates all the requested
- * attributes, first the ordinary result attribtutes and then the
+ * attributes, first the ordinary result attributes and then the
* special result attributes that hold DN or LDAP URL values.
*
* The number of ordinary attributes is "num_attributes".
* index on the "result_attributes" list.
*/
for (i = 0; dict_ldap->result_attributes->argv[i]; i++)
- if (strcasecmp(dict_ldap->result_attributes->argv[i],
- attr) == 0)
+ if (attrdesc_subtype(dict_ldap->result_attributes->argv[i],
+ attr) > 0)
break;
/*
|| (!is_leaf &&
i < dict_ldap->num_terminal + dict_ldap->num_leaf)) {
if (msg_verbose)
- msg_info("%s[%d]: skipping %ld value(s) of %s "
- "attribute %s", myname, recursion, i,
+ msg_info("%s[%d]: skipping %d value(s) of %s "
+ "attribute %s", myname, recursion, valcount,
is_terminal ? "non-terminal" : "leaf-only",
attr);
} else {
if (dict_errno != 0)
continue;
if (msg_verbose)
- msg_info("%s[%d]: search returned %ld value(s) for"
+ msg_info("%s[%d]: search returned %d value(s) for"
" requested result attribute %s",
- myname, recursion, i, attr);
+ myname, recursion, valcount, attr);
}
} else if (recursion < dict_ldap->recursion_limit
&& dict_ldap->result_attributes->argv[i]) {
/* Special result attribute */
for (i = 0; i < valcount; i++) {
if (ldap_is_ldap_url(vals[i]->bv_val)) {
- if (msg_verbose)
- msg_info("%s[%d]: looking up URL %s", myname,
- recursion, vals[i]->bv_val);
rc = ldap_url_parse(vals[i]->bv_val, &url);
if (rc == 0) {
- rc = search_st(dict_ldap->ld, url->lud_dn,
- url->lud_scope, url->lud_filter,
- url->lud_attrs, dict_ldap->timeout,
- &resloop);
+ if ((attrs = url_attrs(dict_ldap, url)) != 0) {
+ if (msg_verbose)
+ msg_info("%s[%d]: looking up URL %s",
+ myname, recursion,
+ vals[i]->bv_val);
+ rc = search_st(dict_ldap->ld, url->lud_dn,
+ url->lud_scope,
+ url->lud_filter,
+ attrs, dict_ldap->timeout,
+ &resloop);
+ }
ldap_free_urldesc(url);
+ if (attrs == 0) {
+ if (msg_verbose)
+ msg_info("%s[%d]: skipping URL %s: no "
+ "pertinent attributes", myname,
+ recursion, vals[i]->bv_val);
+ continue;
+ }
+ } else {
+ msg_warn("%s[%d]: malformed URL %s: %s(%d)",
+ myname, recursion, vals[i]->bv_val,
+ ldap_err2string(rc), rc);
+ dict_errno = DICT_ERR_RETRY;
+ break;
}
} else {
if (msg_verbose)
if (dict_errno != 0)
break;
}
- if (dict_errno != 0)
- continue;
- if (msg_verbose)
- msg_info("%s[%d]: search returned %ld value(s) for"
+ if (msg_verbose && dict_errno == 0)
+ msg_info("%s[%d]: search returned %d value(s) for"
" special result attribute %s",
- myname, recursion, i, attr);
+ myname, recursion, valcount, attr);
} else if (recursion >= dict_ldap->recursion_limit
&& dict_ldap->result_attributes->argv[i]) {
msg_warn("%s[%d]: %s: Recursion limit exceeded"
if (msg_verbose)
msg_info("%s: In dict_ldap_lookup", myname);
+ /*
+ * Don't frustrate future attempts to make Postfix UTF-8 transparent.
+ */
+ if (!valid_utf_8(name, strlen(name))) {
+ if (msg_verbose)
+ msg_info("%s: %s: Skipping lookup of non-UTF-8 key '%s'",
+ myname, dict_ldap->parser->name, name);
+ return (0);
+ }
+
/*
* Optionally fold the key.
*/
*/
if (db_common_check_domain(dict_ldap->ctx, name) == 0) {
if (msg_verbose)
- msg_info("%s: Skipping lookup of '%s'", myname, name);
+ msg_info("%s: %s: Skipping lookup of key '%s': domain mismatch",
+ myname, dict_ldap->parser->name, name);
return (0);
}
#define INIT_VSTR(buf, len) do { \
/*
* TLS cipherlists
*/
+#ifdef USE_TLS
+#include <openssl/opensslv.h>
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL
+#define PREFER_aNULL "aNULL:-aNULL:"
+#else
+#define PREFER_aNULL ""
+#endif
+#else
+#define PREFER_aNULL ""
+#endif
+
#define VAR_TLS_HIGH_CLIST "tls_high_cipherlist"
-#define DEF_TLS_HIGH_CLIST "ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH"
+#define DEF_TLS_HIGH_CLIST PREFER_aNULL "ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH"
extern char *var_tls_high_clist;
#define VAR_TLS_MEDIUM_CLIST "tls_medium_cipherlist"
-#define DEF_TLS_MEDIUM_CLIST "ALL:!EXPORT:!LOW:+RC4:@STRENGTH"
+#define DEF_TLS_MEDIUM_CLIST PREFER_aNULL "ALL:!EXPORT:!LOW:+RC4:@STRENGTH"
extern char *var_tls_medium_clist;
#define VAR_TLS_LOW_CLIST "tls_low_cipherlist"
-#define DEF_TLS_LOW_CLIST "ALL:!EXPORT:+RC4:@STRENGTH"
+#define DEF_TLS_LOW_CLIST PREFER_aNULL "ALL:!EXPORT:+RC4:@STRENGTH"
extern char *var_tls_low_clist;
#define VAR_TLS_EXPORT_CLIST "tls_export_cipherlist"
-#define DEF_TLS_EXPORT_CLIST "ALL:+RC4:@STRENGTH"
+#define DEF_TLS_EXPORT_CLIST PREFER_aNULL "ALL:+RC4:@STRENGTH"
extern char *var_tls_export_clist;
#define VAR_TLS_NULL_CLIST "tls_null_cipherlist"
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20100323"
+#define MAIL_RELEASE_DATE "20100601"
#define MAIL_VERSION_NUMBER "2.8"
#ifdef SNAPSHOT
/*
* Address extension management.
+ *
+ * XXX Fix 20100422, finalized 20100529: it is too error-prone to
+ * distinguish between "no extension" and "no valid extension", so we
+ * drop an invalid extension from the recipient address local-part.
*/
state.msg_attr.user = mystrdup(state.msg_attr.local);
if (*var_rcpt_delim) {
msg_warn("%s: address with illegal extension: %s",
state.msg_attr.queue_id, state.msg_attr.local);
state.msg_attr.extension = 0;
+ /* XXX Can't myfree + mystrdup, must truncate instead. */
+ state.msg_attr.local[strlen(state.msg_attr.user)] = 0;
+ /* Truncating is safe. The code below rejects null usernames. */
}
} else
state.msg_attr.extension = 0;
msg_warn("no milters");
continue;
}
- resp = milter_rcpt_event(milters, (const char **) args);
+ resp = milter_rcpt_event(milters, 0, (const char **) args);
} else if (strcmp(cmd, "unknown") == 0 && argv->argc > 0) {
if (milters == 0) {
msg_warn("no milters");
* Build the XFORWARD command. With properly sanitized
* information, the command length stays within the 512 byte
* command line length limit.
+ *
+ * XXX smtpd_xforward_preset() initializes some fields as "unknown"
+ * and some as null; historically, pickup(8) does not send any of
+ * these, and the queue manager presets absent fields to "not
+ * available" except for the rewrite context which is preset to
+ * local by way of migration aid. These definitions need to be
+ * centralized for maintainability.
*/
+#ifndef CAN_FORWARD_CLIENT_NAME
+#define _ATTR_AVAIL_AND_KNOWN_(val) \
+ (DEL_REQ_ATTR_AVAIL(val) && strcasecmp((val), "unknown"))
+#define CAN_FORWARD_CLIENT_NAME _ATTR_AVAIL_AND_KNOWN_
+#define CAN_FORWARD_CLIENT_ADDR _ATTR_AVAIL_AND_KNOWN_
+#define CAN_FORWARD_CLIENT_PORT _ATTR_AVAIL_AND_KNOWN_
+#define CAN_FORWARD_PROTO_NAME _ATTR_AVAIL_AND_KNOWN_
+#define CAN_FORWARD_HELO_NAME DEL_REQ_ATTR_AVAIL
+#define CAN_FORWARD_RWR_CONTEXT DEL_REQ_ATTR_AVAIL
+#endif
+
case SMTP_STATE_XFORWARD_NAME_ADDR:
vstring_strcpy(next_command, XFORWARD_CMD);
if ((session->features & SMTP_FEATURE_XFORWARD_NAME)
- && DEL_REQ_ATTR_AVAIL(request->client_name)) {
+ && CAN_FORWARD_CLIENT_NAME(request->client_name)) {
vstring_strcat(next_command, " " XFORWARD_NAME "=");
xtext_quote_append(next_command, request->client_name, "");
}
if ((session->features & SMTP_FEATURE_XFORWARD_ADDR)
- && DEL_REQ_ATTR_AVAIL(request->client_addr)) {
+ && CAN_FORWARD_CLIENT_ADDR(request->client_addr)) {
vstring_strcat(next_command, " " XFORWARD_ADDR "=");
xtext_quote_append(next_command, request->client_addr, "");
}
if ((session->features & SMTP_FEATURE_XFORWARD_PORT)
- && DEL_REQ_ATTR_AVAIL(request->client_port)) {
+ && CAN_FORWARD_CLIENT_PORT(request->client_port)) {
vstring_strcat(next_command, " " XFORWARD_PORT "=");
xtext_quote_append(next_command, request->client_port, "");
}
case SMTP_STATE_XFORWARD_PROTO_HELO:
vstring_strcpy(next_command, XFORWARD_CMD);
if ((session->features & SMTP_FEATURE_XFORWARD_PROTO)
- && DEL_REQ_ATTR_AVAIL(request->client_proto)) {
+ && CAN_FORWARD_PROTO_NAME(request->client_proto)) {
vstring_strcat(next_command, " " XFORWARD_PROTO "=");
xtext_quote_append(next_command, request->client_proto, "");
}
if ((session->features & SMTP_FEATURE_XFORWARD_HELO)
- && DEL_REQ_ATTR_AVAIL(request->client_helo)) {
+ && CAN_FORWARD_HELO_NAME(request->client_helo)) {
vstring_strcat(next_command, " " XFORWARD_HELO "=");
xtext_quote_append(next_command, request->client_helo, "");
}
if ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN)
- && DEL_REQ_ATTR_AVAIL(request->rewrite_context)) {
+ && CAN_FORWARD_RWR_CONTEXT(request->rewrite_context)) {
vstring_strcat(next_command, " " XFORWARD_DOMAIN "=");
xtext_quote_append(next_command,
strcmp(request->rewrite_context, MAIL_ATTR_RWR_LOCAL) ?
send_name_addr =
var_smtp_send_xforward
&& (((session->features & SMTP_FEATURE_XFORWARD_NAME)
- && DEL_REQ_ATTR_AVAIL(request->client_name))
+ && CAN_FORWARD_CLIENT_NAME(request->client_name))
|| ((session->features & SMTP_FEATURE_XFORWARD_ADDR)
- && DEL_REQ_ATTR_AVAIL(request->client_addr))
+ && CAN_FORWARD_CLIENT_ADDR(request->client_addr))
|| ((session->features & SMTP_FEATURE_XFORWARD_PORT)
- && DEL_REQ_ATTR_AVAIL(request->client_port)));
+ && CAN_FORWARD_CLIENT_PORT(request->client_port)));
session->send_proto_helo =
var_smtp_send_xforward
&& (((session->features & SMTP_FEATURE_XFORWARD_PROTO)
- && DEL_REQ_ATTR_AVAIL(request->client_proto))
+ && CAN_FORWARD_PROTO_NAME(request->client_proto))
|| ((session->features & SMTP_FEATURE_XFORWARD_HELO)
- && DEL_REQ_ATTR_AVAIL(request->client_helo))
+ && CAN_FORWARD_HELO_NAME(request->client_helo))
|| ((session->features & SMTP_FEATURE_XFORWARD_DOMAIN)
- && DEL_REQ_ATTR_AVAIL(request->rewrite_context)));
+ && CAN_FORWARD_RWR_CONTEXT(request->rewrite_context)));
if (send_name_addr)
recv_state = send_state = SMTP_STATE_XFORWARD_NAME_ADDR;
else if (session->send_proto_helo)
name);
else {
cpp += 1;
- if (strcasecmp(state->name, "unknown") != 0)
+ if (strcasecmp(state->reverse_name, "unknown") != 0)
status = reject_rbl_domain(state, *cpp, state->reverse_name,
SMTPD_NAME_REV_CLIENT);
}
/* further input from the client; this is an attempt to block
/* the client before it sends ".". Specify a zero delay value
/* to abort immediately.
+/* .IP "\fB-b \fIsoft-bounce-reply\fR"
+/* Use \fIsoft-bounce-reply\fR for soft reject responses. The
+/* default reply is "450 4.3.0 Error: command failed".
+/* .IP "\fB-B \fIhard-bounce-reply\fR"
+/* Use \fIhard-bounce-reply\fR for hard reject responses. The
+/* default reply is "500 5.3.0 Error: command failed".
/* .IP \fB-c\fR
/* Display running counters that are updated whenever an SMTP
/* session ends, a QUIT command is executed, or when "." is
#define DEF_MAX_CLIENT_COUNT 256
#endif
+#define SOFT_ERROR_RESP "450 4.3.0 Error: command failed"
+#define HARD_ERROR_RESP "500 5.3.0 Error: command failed"
+
static int var_tmout = 100;
static int var_max_line_length = 2048;
static char *var_myhostname;
+static char *soft_error_resp = SOFT_ERROR_RESP;
+static char *hard_error_resp = HARD_ERROR_RESP;
static int command_read(SINK_STATE *);
static int data_read(SINK_STATE *);
static void disconnect(SINK_STATE *);
static INET_PROTO_INFO *proto_info;
-#define SOFT_ERROR_RESP "450 4.3.0 Error: command failed"
-#define HARD_ERROR_RESP "500 5.3.0 Error: command failed"
-
#define STR(x) vstring_str(x)
/* do_stats - show counters */
static void hard_err_resp(SINK_STATE *state)
{
- smtp_printf(state->stream, HARD_ERROR_RESP);
+ smtp_printf(state->stream, hard_error_resp);
smtp_flush(state->stream);
}
static void soft_err_resp(SINK_STATE *state)
{
- smtp_printf(state->stream, SOFT_ERROR_RESP);
+ smtp_printf(state->stream, soft_error_resp);
smtp_flush(state->stream);
}
{
if (enable_lmtp) {
while (state->rcpts-- > 0) /* XXX this could block */
- smtp_printf(state->stream, HARD_ERROR_RESP);
+ smtp_printf(state->stream, hard_error_resp);
} else {
- smtp_printf(state->stream, HARD_ERROR_RESP);
+ smtp_printf(state->stream, hard_error_resp);
}
smtp_flush(state->stream);
}
{
if (enable_lmtp) {
while (state->rcpts-- > 0) /* XXX this could block */
- smtp_printf(state->stream, SOFT_ERROR_RESP);
+ smtp_printf(state->stream, soft_error_resp);
} else {
- smtp_printf(state->stream, SOFT_ERROR_RESP);
+ smtp_printf(state->stream, soft_error_resp);
}
smtp_flush(state->stream);
}
static void usage(char *myname)
{
- msg_fatal("usage: %s [-468acCeEFLpPv] [-A abort_delay] [-d dump-template] [-D dump-template] [-f commands] [-h hostname] [-m max_concurrency] [M message_quit_count] [-n quit_count] [-q commands] [-r commands] [-R root-dir] [-s commands] [-S start-string] [-u user_privs] [-w delay] [host]:port backlog", myname);
+ msg_fatal("usage: %s [-468acCeEFLpPv] [-A abort_delay] [-b soft_bounce_reply] [-B hard_bounce_reply] [-d dump-template] [-D dump-template] [-f commands] [-h hostname] [-m max_concurrency] [-M message_quit_count] [-n quit_count] [-q commands] [-r commands] [-R root-dir] [-s commands] [-S start-string] [-u user_privs] [-w delay] [host]:port backlog", myname);
}
MAIL_VERSION_STAMP_DECLARE;
/*
* Parse JCL.
*/
- while ((ch = GETOPT(argc, argv, "468aA:cCd:D:eEf:Fh:Ln:m:M:pPq:Q:r:R:s:S:t:T:u:vw:W:")) > 0) {
+ while ((ch = GETOPT(argc, argv, "468aA:b:B:cCd:D:eEf:Fh:Ln:m:M:pPq:Q:r:R:s:S:t:T:u:vw:W:")) > 0) {
switch (ch) {
case '4':
protocols = INET_PROTO_NAME_IPV4;
if (!alldig(optarg) || (abort_delay = atoi(optarg)) < 0)
usage(argv[0]);
break;
+ case 'b':
+ if (optarg[0] != '4' || strspn(optarg, "0123456789") != 3) {
+ msg_error("bad soft error reply: %s", optarg);
+ usage(argv[0]);
+ } else
+ soft_error_resp = optarg;
+ break;
+ case 'B':
+ if (optarg[0] != '5' || strspn(optarg, "0123456789") != 3) {
+ msg_error("bad hard error reply: %s", optarg);
+ usage(argv[0]);
+ } else
+ hard_error_resp = optarg;
+ break;
case 'c':
count++;
break;
return (-1); /* logged */
if (*dcert_file && !set_cert_stuff(ctx, "DSA", dcert_file, dkey_file))
return (-1); /* logged */
-#if OPENSSL_VERSION_NUMBER >= 0x00909000 && !defined(OPENSSL_NO_ECDH)
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL && !defined(OPENSSL_NO_ECDH)
if (*eccert_file && !set_cert_stuff(ctx, "ECDSA", eccert_file, eckey_file))
return (-1); /* logged */
#else
int protomask;
const char *cipher_list;
SSL_SESSION *session;
- SSL_CIPHER *cipher;
+ const SSL_CIPHER *cipher;
X509 *peercert;
TLS_SESS_STATE *TLScontext;
TLS_APPL_STATE *app_ctx = props->ctx;
int tls_set_eecdh_curve(SSL_CTX *server_ctx, const char *grade)
{
-#if OPENSSL_VERSION_NUMBER >= 0x00909000 && !defined(OPENSSL_NO_ECDH)
+#if OPENSSL_VERSION_NUMBER >= 0x1000000fL && !defined(OPENSSL_NO_ECDH)
int nid;
EC_KEY *ecdh;
const char *curve;
{
int sts;
TLS_SESS_STATE *TLScontext;
- SSL_CIPHER *cipher;
+ const SSL_CIPHER *cipher;
X509 *peer;
char buf[CCERT_BUFSIZ];
const char *cipher_list;
write_buf.c write_wait.c sane_basename.c format_tv.c allspace.c \
allascii.c load_file.c killme_after.c vstream_tweak.c upass_connect.c \
upass_listen.c upass_trigger.c edit_file.c inet_windowsize.c \
- unix_pass_fd_fix.c dict_cache.c
+ unix_pass_fd_fix.c dict_cache.c valid_utf_8.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
write_buf.o write_wait.o sane_basename.o format_tv.o allspace.o \
allascii.o load_file.o killme_after.o vstream_tweak.o upass_connect.o \
upass_listen.o upass_trigger.o edit_file.o inet_windowsize.o \
- unix_pass_fd_fix.o dict_cache.o
+ unix_pass_fd_fix.o dict_cache.o valid_utf_8.o
HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
chroot_uid.h cidr_match.h clean_env.h connect.h ctable.h dict.h \
dict_cdb.h dict_cidr.h dict_db.h dict_dbm.h dict_env.h dict_ht.h \
attr_scan0 host_port attr_scan_plain attr_print_plain htable \
unix_recv_fd unix_send_fd stream_recv_fd stream_send_fd hex_code \
myaddrinfo myaddrinfo4 inet_proto sane_basename format_tv \
- test_send_fd test_recv_fd
+ test_send_fd test_recv_fd valid_utf_8
LIB_DIR = ../../lib
INC_DIR = ../../include
$(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
mv junk $@.o
+valid_utf_8: $(LIB)
+ mv $@.o junk
+ $(CC) $(CFLAGS) -DTEST -o $@ $@.c $(LIB) $(SYSLIBS)
+ mv junk $@.o
+
tests: valid_hostname_test mac_expand_test dict_test unescape_test \
hex_quote_test ctable_test inet_addr_list_test base64_code_test \
attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \
valid_hostname.o: valid_hostname.h
valid_hostname.o: vbuf.h
valid_hostname.o: vstring.h
+valid_utf_8.o: stringops.h
+valid_utf_8.o: valid_utf_8.c
+valid_utf_8.o: vbuf.h
+valid_utf_8.o: vstring.h
vbuf.o: sys_defs.h
vbuf.o: vbuf.c
vbuf.o: vbuf.h
msg_fatal("set DB cache size %d: %m", dict_db_cache_size);
if (type == DB_HASH && db->set_h_nelem(db, DICT_DB_NELM) != 0)
msg_fatal("set DB hash element count %d: %m", DICT_DB_NELM);
-#if (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0)
+#if DB_VERSION_MAJOR == 5 || (DB_VERSION_MAJOR == 4 && DB_VERSION_MINOR > 0)
if ((errno = db->open(db, 0, db_path, 0, type, db_flags, 0644)) != 0)
msg_fatal("open database %s: %m", db_path);
#elif (DB_VERSION_MAJOR == 3 || DB_VERSION_MAJOR == 4)
* prepend the negation operator to each item from the file.
*/
while ((start = mystrtok(&bp, delim)) != 0) {
+ if (*start == '#') {
+ msg_warn("%s: comment at end of line is not supported: %s %s",
+ myname, start, bp);
+ break;
+ }
for (match = init_match, item = start; *item == '!'; item++)
match = !match;
if (*item == 0)
extern int allspace(const char *);
extern int allascii(const char *);
extern const char *split_nameval(char *, char **, char **);
+extern int valid_utf_8(const char *, ssize_t);
/* LICENSE
/* .ad
#define DEF_DB_TYPE "hash"
#define ALIAS_DB_MAP "hash:/etc/aliases"
#define GETTIMEOFDAY(t) gettimeofday(t,(struct timezone *) 0)
-#define RESOLVE_H_NEEDS_NAMESER8_COMPAT_H
#define ROOT_PATH "/bin:/usr/bin:/sbin:/usr/sbin"
#define USE_STATFS
#define STATFS_IN_SYS_MOUNT_H
#else
#define PRINTFPTRLIKE(x,y)
#endif
+#endif
+
+ /*
+ * Compiler optimization hint. This makes sense only for code in a
+ * performance-critical loop.
+ */
+#ifndef EXPECTED
+#if defined(__GNUC__) && (__GNUC__ > 2)
+#define EXPECTED(x) __builtin_expect(!!(x), 1)
+#define UNEXPECTED(x) __builtin_expect(!!(x), 0)
+#else
+#define EXPECTED(x) (x)
+#define UNEXPECTED(x) (x)
+#endif
#endif
/*
--- /dev/null
+/*++
+/* NAME
+/* valid_utf_8 3
+/* SUMMARY
+/* predicate if string is valid UTF-8
+/* SYNOPSIS
+/* #include <stringops.h>
+/*
+/* int valid_utf_8(str, len)
+/* const char *str;
+/* ssize_t len;
+/* DESCRIPTION
+/* valid_utf_8() determines if a string satisfies the UTF-8
+/* definition in RFC 3629. That is, it contains proper encodings
+/* of code points U+0000..U+10FFFF, excluding over-long encodings
+/* and excluding U+D800..U+DFFF surrogates.
+/*
+/* A zero-length string is considered valid.
+/* DIAGNOSTICS
+/* The result value is zero when the caller specifies a negative
+/* length, or a string that violates RFC 3629, for example a
+/* string that is truncated in the middle of a multi-byte
+/* sequence.
+/* BUGS
+/* But wait, there is more. Code points in the range U+FDD0..U+FDEF
+/* and ending in FFFE or FFFF are non-characters in UNICODE. This
+/* function does not block these.
+/* SEE ALSO
+/* RFC 3629
+/* 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 <sys_defs.h>
+
+/* Utility library. */
+
+#include <stringops.h>
+
+/* valid_utf_8 - validate string according to RFC 3629 */
+
+int valid_utf_8(const char *str, ssize_t len)
+{
+ const unsigned char *end = (const unsigned char *) str + len;
+ const unsigned char *cp;
+ unsigned char c0, ch;
+
+ if (len < 0)
+ return (0);
+ if (len <= 0)
+ return (1);
+
+ /*
+ * Optimized for correct input, time, space, and for CPUs that have a
+ * decent number of registers.
+ */
+ for (cp = (const unsigned char *) str; cp < end; cp++) {
+ /* Single-byte encodings. */
+ if (EXPECTED((c0 = *cp) <= 0x7f) /* we know that c0 >= 0x0 */ ) {
+ /* void */ ;
+ }
+ /* Two-byte encodings. */
+ else if (EXPECTED(c0 <= 0xdf) /* we know that c0 >= 0x80 */ ) {
+ /* Exclude over-long encodings. */
+ if (UNEXPECTED(c0 < 0xc2)
+ || UNEXPECTED(cp + 1 >= end)
+ /* Require UTF-8 tail byte. */
+ || UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+ return (0);
+ }
+ /* Three-byte encodings. */
+ else if (EXPECTED(c0 <= 0xef) /* we know that c0 >= 0xe0 */ ) {
+ if (UNEXPECTED(cp + 2 >= end)
+ /* Exclude over-long encodings. */
+ || UNEXPECTED((ch = *++cp) < (c0 == 0xe0 ? 0xa0 : 0x80))
+ /* Exclude U+D800..U+DFFF. */
+ || UNEXPECTED(ch > (c0 == 0xed ? 0x9f : 0xbf))
+ /* Require UTF-8 tail byte. */
+ || UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+ return (0);
+ }
+ /* Four-byte encodings. */
+ else if (EXPECTED(c0 <= 0xf4) /* we know that c0 >= 0xf0 */ ) {
+ if (UNEXPECTED(cp + 3 >= end)
+ /* Exclude over-long encodings. */
+ || UNEXPECTED((ch = *++cp) < (c0 == 0xf0 ? 0x90 : 0x80))
+ /* Exclude code points above U+10FFFF. */
+ || UNEXPECTED(ch > (c0 == 0xf4 ? 0x8f : 0xbf))
+ /* Require UTF-8 tail byte. */
+ || UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf)
+ /* Require UTF-8 tail byte. */
+ || UNEXPECTED((ch = *++cp) < 0x80) || UNEXPECTED(ch > 0xbf))
+ return (0);
+ }
+ /* Invalid: c0 >= 0xf5 */
+ else {
+ return (0);
+ }
+ }
+ return (1);
+}
+
+ /*
+ * Stand-alone test program. Each string is a line without line terminator.
+ */
+#ifdef TEST
+#include <stdlib.h>
+#include <vstream.h>
+#include <vstring.h>
+#include <vstring_vstream.h>
+
+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
+int main(void)
+{
+ VSTRING *buf = vstring_alloc(1);
+
+ while (vstring_get_nonl(buf, VSTREAM_IN) != VSTREAM_EOF) {
+ vstream_printf("%c", (LEN(buf) && !valid_utf_8(STR(buf), LEN(buf))) ?
+ '!' : ' ');
+ vstream_fwrite(VSTREAM_OUT, STR(buf), LEN(buf));
+ vstream_printf("\n");
+ }
+ vstream_fflush(VSTREAM_OUT);
+ vstring_free(buf);
+ exit(0);
+}
+
+#endif