-TSMTP_ADDR
-TSMTP_CMD
-TSMTP_RESP
+-TSMTP_SASL_AUTH_CACHE
-TSMTP_SESSION
-TSMTP_STATE
-TSMTP_TLS_SITE_POLICY
Cleanup: more read-only data. Files: everything that passes
around a HEADER_OPTS pointer.
+
+20080112
+
+ Safety: optional lookup table to prevent the Postfix SMTP
+ client from making repeated SASL login failures with the
+ same hostname, username and password. This introduces new
+ parameters: smtp_sasl_auth_cache_name, smtp_sasl_auth_cache_time.
+ Based on code by Keean Schupke. Files: smtp/smtp_sasl_glue.c,
+ smtp/smtp_sasl_auth_cache.c.
+
+ Safety: the Postfix SMTP client now by default defers mail
+ after the server rejects a SASL login attempt with a 535
+ status code. Specify "smtp_sasl_auth_soft_bounce = no" to
+ get the earlier behavior. Based on code by Keean Schupke.
+ Files: smtp/smtp_sasl_glue.c.
+
+20080114
+
+ Safety: the smtpd_client_new_tls_session_rate_limit setting
+ now also limits the number of failed TLS handshakes. This
+ limits the impact of broken configurations. File: smtpd/smtpd.c.
CDB support is available with Postfix 2.2 and later releases. This document
describes how to build Postfix with CDB support.
-B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh C\bCD\bDB\bB
+B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh C\bCD\bDB\bB s\bsu\bup\bpp\bpo\bor\brt\bt
+
+These instructions assume that you build Postfix from source code as described
+in the INSTALL document. Some modification may be required if you build Postfix
+from a vendor-specific source package.
Postfix is compatible with two CDB implementations:
B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh L\bLD\bDA\bAP\bP s\bsu\bup\bpp\bpo\bor\brt\bt
+These instructions assume that you build Postfix from source code as described
+in the INSTALL document. Some modification may be required if you build Postfix
+from a vendor-specific source package.
+
Note 1: Postfix no longer supports the LDAP version 1 interface.
Note 2: to use LDAP with Debian GNU/Linux's Postfix, all you need is to install
|{client_name} |Always |when lookup or |
| | |verification fails |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
- |{client_port} |Always |Client TCP port |
- | |(Postfix >=2.5) | |
+ |{client_port} |Always (Postfix >=2.5) |Client TCP port |
|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b|_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b |
| | |Client name from reverse |
|{client_ptr} |CONNECT, HELO, MAIL, DATA|lookup, "unknown" when |
Postfix sends specific sets of macros at different SMTP protocol stages. The
sets are configured with the parameters as described in the table (EOH = end of
-headers; EOM = end of message).
+headers; EOM = end of message). The protocol version is a number that Postfix
+sends at the beginning of the Milter protocol handshake.
_\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b _\b
|P\bPa\bar\bra\bam\bme\bet\bte\ber\br n\bna\bam\bme\be |P\bPr\bro\bot\bto\boc\bco\bol\bl v\bve\ber\brs\bsi\bio\bon\bn|P\bPr\bro\bot\bto\boc\bco\bol\bl s\bst\bta\bag\bge\be |
B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh M\bMy\byS\bSQ\bQL\bL s\bsu\bup\bpp\bpo\bor\brt\bt
+These instructions assume that you build Postfix from source code as described
+in the INSTALL document. Some modification may be required if you build Postfix
+from a vendor-specific source package.
+
Note: to use mysql with Debian GNU/Linux's Postfix, all you need is to install
the postfix-mysql package and you're done. There is no need to recompile
Postfix.
B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh P\bPC\bCR\bRE\bE s\bsu\bup\bpp\bpo\bor\brt\bt
+These instructions assume that you build Postfix from source code as described
+in the INSTALL document. Some modification may be required if you build Postfix
+from a vendor-specific source package.
+
Note: to use pcre with Debian GNU/Linux's Postfix, all you need is to install
the postfix-pcre package and you're done. There is no need to recompile
Postfix.
B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh P\bPo\bos\bst\btg\bgr\bre\beS\bSQ\bQL\bL s\bsu\bup\bpp\bpo\bor\brt\bt
+These instructions assume that you build Postfix from source code as described
+in the INSTALL document. Some modification may be required if you build Postfix
+from a vendor-specific source package.
+
Note: to use pgsql with Debian GNU/Linux's Postfix, all you need to do is to
install the postfix-pgsql package and you're done. There is no need to
recompile Postfix.
B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh D\bDo\bov\bve\bec\bco\bot\bt S\bSA\bAS\bSL\bL s\bsu\bup\bpp\bpo\bor\brt\bt
+These instructions assume that you build Postfix from source code as described
+in the INSTALL document. Some modification may be required if you build Postfix
+from a vendor-specific source package.
+
Support for the Dovecot version 1 SASL protocol is available in Postfix 2.3 and
later. At the time of writing, only server-side SASL support is available, so
you can't use it to authenticate to your network provider's server. Dovecot
B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh C\bCy\byr\bru\bus\bs S\bSA\bAS\bSL\bL s\bsu\bup\bpp\bpo\bor\brt\bt
+These instructions assume that you build Postfix from source code as described
+in the INSTALL document. Some modification may be required if you build Postfix
+from a vendor-specific source package.
+
The following assumes that the Cyrus SASL include files are in /usr/local/
include, and that the Cyrus SASL libraries are in /usr/local/lib.
that seeds the TLS engines in the smtpd(8) server and smtp(8) client
processes, and maintains the TLS session key cache files.
- <---seed--- ---seed--->
+ <---seed---- ----seed--->
Network-> smtpd(8) tlsmgr(8) smtp(8) ->Network
- <-session-> <-session->
+ <-key/cert-> <-key/cert->
/ | \
|
B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh T\bTL\bLS\bS s\bsu\bup\bpp\bpo\bor\brt\bt
+These instructions assume that you build Postfix from source code as described
+in the INSTALL document. Some modification may be required if you build Postfix
+from a vendor-specific source package.
+
To build Postfix with TLS support, first we need to generate the make(1) files
with the necessary definitions. This is done by invoking the command "make
makefiles" in the Postfix top-level directory and with arguments as shown next.
writing new private key to './demoCA/private/cakey.pem'
Enter PEM pass phrase:w\bwh\bha\bat\bte\bev\bve\ber\br
- * Create an unpassworded private key for host FOO and create an unsigned
- public key certificate.
+ * Create an unpassworded private key for host foo.porcupine.org and create an
+ unsigned public key certificate.
- % o\bop\bpe\ben\bns\bss\bsl\bl r\bre\beq\bq -\b-n\bne\bew\bw -\b-n\bno\bod\bde\bes\bs -\b-k\bke\bey\byo\bou\but\bt F\bFO\bOO\bO-\b-k\bke\bey\by.\b.p\bpe\bem\bm -\b-o\bou\but\bt F\bFO\bOO\bO-\b-r\bre\beq\bq.\b.p\bpe\bem\bm -\b-d\bda\bay\bys\bs
+ % o\bop\bpe\ben\bns\bss\bsl\bl r\bre\beq\bq -\b-n\bne\bew\bw -\b-n\bno\bod\bde\bes\bs -\b-k\bke\bey\byo\bou\but\bt f\bfo\boo\bo-\b-k\bke\bey\by.\b.p\bpe\bem\bm -\b-o\bou\but\bt f\bfo\boo\bo-\b-r\bre\beq\bq.\b.p\bpe\bem\bm -\b-d\bda\bay\bys\bs
3\b36\b65\b5
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
........................................++++++
....++++++
- writing new private key to 'FOO-key.pem'
+ writing new private key to 'foo-key.pem'
-----
You are about to be asked to enter information that will be
incorporated
Locality Name (eg, city) []:W\bWe\bes\bst\btc\bch\bhe\bes\bst\bte\ber\br
Organization Name (eg, company) [Internet Widgits Pty Ltd]:P\bPo\bor\brc\bcu\bup\bpi\bin\bne\be
Organizational Unit Name (eg, section) []:
- Common Name (eg, YOUR name) []:F\bFO\bOO\bO
+ Common Name (eg, YOUR name) []:f\bfo\boo\bo.\b.p\bpo\bor\brc\bcu\bup\bpi\bin\bne\be.\b.o\bor\brg\bg
Email Address []:w\bwi\bie\bet\bts\bse\be@\b@p\bpo\bor\brc\bcu\bup\bpi\bin\bne\be.\b.o\bor\brg\bg
Please enter the following 'extra' attributes
A challenge password []:w\bwh\bha\bat\bte\bev\bve\ber\br
An optional company name []:
- * Sign the public key certificate for host FOO with the Certification
- Authority private key that we created a few steps ago.
+ * Sign the public key certificate for host foo.porcupine.org with the
+ Certification Authority private key that we created a few steps ago.
- % o\bop\bpe\ben\bns\bss\bsl\bl c\bca\ba -\b-o\bou\but\bt F\bFO\bOO\bO-\b-c\bce\ber\brt\bt.\b.p\bpe\bem\bm -\b-i\bin\bnf\bfi\bil\ble\bes\bs F\bFO\bOO\bO-\b-r\bre\beq\bq.\b.p\bpe\bem\bm
+ % o\bop\bpe\ben\bns\bss\bsl\bl c\bca\ba -\b-o\bou\but\bt f\bfo\boo\bo-\b-c\bce\ber\brt\bt.\b.p\bpe\bem\bm -\b-i\bin\bnf\bfi\bil\ble\bes\bs f\bfo\boo\bo-\b-r\bre\beq\bq.\b.p\bpe\bem\bm
Using configuration from /etc/ssl/openssl.cnf
Enter PEM pass phrase:w\bwh\bha\bat\bte\bev\bve\ber\br
Check that the request matches the signature
stateOrProvinceName :PRINTABLE:'New York'
localityName :PRINTABLE:'Westchester'
organizationName :PRINTABLE:'Porcupine'
- commonName :PRINTABLE:'FOO'
+ commonName :PRINTABLE:'foo.porcupine.org'
emailAddress :IA5STRING:'wietse@porcupine.org'
Certificate is to be certified until Nov 21 19:40:56 2005 GMT (365
days)
Certification Authority certificate files. This requires super-user
privileges.
- # c\bcp\bp d\bde\bem\bmo\boC\bCA\bA/\b/c\bca\bac\bce\ber\brt\bt.\b.p\bpe\bem\bm F\bFO\bOO\bO-\b-k\bke\bey\by.\b.p\bpe\bem\bm F\bFO\bOO\bO-\b-c\bce\ber\brt\bt.\b.p\bpe\bem\bm /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx
- # c\bch\bhm\bmo\bod\bd 6\b64\b44\b4 /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/F\bFO\bOO\bO-\b-c\bce\ber\brt\bt.\b.p\bpe\bem\bm /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bca\bac\bce\ber\brt\bt.\b.p\bpe\bem\bm
- # c\bch\bhm\bmo\bod\bd 4\b40\b00\b0 /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/F\bFO\bOO\bO-\b-k\bke\bey\by.\b.p\bpe\bem\bm
+ # c\bcp\bp d\bde\bem\bmo\boC\bCA\bA/\b/c\bca\bac\bce\ber\brt\bt.\b.p\bpe\bem\bm f\bfo\boo\bo-\b-k\bke\bey\by.\b.p\bpe\bem\bm f\bfo\boo\bo-\b-c\bce\ber\brt\bt.\b.p\bpe\bem\bm /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx
+ # c\bch\bhm\bmo\bod\bd 6\b64\b44\b4 /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/f\bfo\boo\bo-\b-c\bce\ber\brt\bt.\b.p\bpe\bem\bm /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/c\bca\bac\bce\ber\brt\bt.\b.p\bpe\bem\bm
+ # c\bch\bhm\bmo\bod\bd 4\b40\b00\b0 /\b/e\bet\btc\bc/\b/p\bpo\bos\bst\btf\bfi\bix\bx/\b/f\bfo\boo\bo-\b-k\bke\bey\by.\b.p\bpe\bem\bm
* Configure Postfix, by adding the following to /etc/postfix/main.cf. It is
generally best to not configure client certificates, unless there are
btree:/var/lib/postfix/smtp_tls_session_cache
smtp_tls_security_level = may
smtpd_tls_CAfile = /etc/postfix/cacert.pem
- smtpd_tls_cert_file = /etc/postfix/FOO-cert.pem
- smtpd_tls_key_file = /etc/postfix/FOO-key.pem
+ smtpd_tls_cert_file = /etc/postfix/foo-cert.pem
+ smtpd_tls_key_file = /etc/postfix/foo-key.pem
smtpd_tls_received_header = yes
smtpd_tls_session_cache_database =
btree:/var/lib/postfix/smtpd_tls_session_cache
The mail_release_date configuration parameter (format: yyyymmdd)
specifies the release date of a stable release or snapshot release.
+Incompatibility with Postfix 2.3 and earlier
+============================================
+
+If you upgrade from Postfix 2.3 or earlier, read RELEASE_NOTES-2.4
+before proceeding.
+
+Incompatibility with Postfix snapshot 20080114
+==============================================
+
+The Postfix SMTP client now by default defers mail after a remote
+SMTP server rejects a SASL authentication attempt. Specify
+"smtp_sasl_auth_soft_bounce = no" for the old behavior.
+
+Major changes with Postfix snapshot 20080114
+============================================
+
+The Postfix SMTP client can now avoid making repeated SASL login
+failures with the same server, username and password. To enable
+this safety feature, specify for example "smtp_sasl_auth_cache_name
+= proxy:btree:/var/lib/postfix/sasl_auth_cache" (access through the
+proxy service is required). Instead of trying to SASL authenticate,
+the Postfix SMTP client defers or bounces mail as controlled with
+the new smtp_sasl_auth_soft_bounce configuration parameter.
+
Incompatibility with Postfix snapshot 20080109
==============================================
Sendmail's documentation does not specify what ESMTP options are
supported, but only discusses examples of things that don't work.
-Incompatibility with Postfix 2.3 and earlier
-============================================
-
-If you upgrade from Postfix 2.3 or earlier, read RELEASE_NOTES-2.4
-before proceeding.
-
Incompatibility with Postfix snapshot 20071216
==============================================
Wish list:
+ See if "pickup =o content_filter=smtp:127.0.0.1" can be
+ made a viable alternative to the use of non_smtpd_milters.
+
Consolidate duplicated code *_server_accept_{pass,inet}().
Consolidate duplicated code in {inet,unix,upass}_trigger.c.
handlers unchanged, and have the smtp_loop() reader loop
bail out with smtp_site_fail("server disconnected after
%s", where), but only in the case that it isn't already in
- the final state. Handle 421 replies in HELO/EHLO with custom
- code to prevent EHLO->HELO fall-back.
+ the final state. But first we need to clean up the handling
+ of do/don't cache, expired, bad and dead sessions.
Make event_drain() a proper event loop; update the zero mask,
and don't ignore a non-empty timer queue.
settings?
Remove defer(8) and trace(8) references and man pages. These
- are services not program names.
+ are services not program names. On the other hand we have
+ man pages for lmtp(8) and smtp(8), but not for relay(8).
+ Likewise, retry(8) does not have a man page.
Bind all deliveries to the same local delivery process,
making Postfix perform as poorly as monolithic mailers, but
Need scache size limit.
- Update BACKSCATTER_README to use PCRE because that's what I
- am using now.
-
Make postcat header/body aware so people can grep headers.
+ What headers? primary, mime, nested? What body? Does it
+ include the mime and attached headers?
Make postmap header/body aware so people can test multi-line
- header checks.
+ header checks. What headers? primary, mime, nested? What
+ body? Does it include the mime and attached headers?
REDIRECT should override original recipient info, and
probably override DSN as well.
Med: separate ulimit for delivery to command?
- Med: option to open queue file early, after MAIL FROM. This
- would allow correlation of rejected RCPT TO requests with
- accepted requests for the same mail transaction.
-
Med: postsuper -r should do something with recipients in
bounce logfiles, to make sure the sender will be notified.
To be perfectly safe, no process other than the queue manager
smtp unix - - n - - smtp
# When relaying mail as backup MX, disable fallback_relay to avoid MX loops
relay unix - - n - - smtp
- -o fallback_relay=
+ -o smtp_fallback_relay=
# -o smtp_helo_timeout=5 -o smtp_connect_timeout=5
showq unix n - n - - showq
error unix - - n - - error
virtual unix - n n - - virtual
lmtp unix - - n - - lmtp
anvil unix - - n - 1 anvil
-scache unix - - n - 1 scache
+scache unix - - n - 1 scache
#
# ====================================================================
# Interfaces to non-Postfix software. Be sure to examine the manual
<p> CDB support is available with Postfix 2.2 and later releases.
This document describes how to build Postfix with CDB support. </p>
-<h2>Building Postfix with CDB</h2>
+<h2>Building Postfix with CDB support</h2>
+
+<p> These instructions assume that you build Postfix from source
+code as described in the <a href="INSTALL.html">INSTALL</a> document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
<p> Postfix is compatible with two CDB implementations: </p>
<h2><a name="build">Building Postfix with LDAP support</a></h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the <a href="INSTALL.html">INSTALL</a> document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Note 1: Postfix no longer supports the LDAP version 1 interface.
</p>
search for any directory entries whose mailacceptinggeneralid
attribute is "ldapuser", read the "maildrop" attributes of those
found, and build a list of their maildrops, which will be treated
-as <a href="http://www.faqs.org/rfcs/rfc822.html">RFC822</a> addresses to which the message will be delivered. </p>
+as <a href="http://tools.ietf.org/html/rfc822">RFC822</a> addresses to which the message will be delivered. </p>
<h2><a name="example_virtual">Example: virtual domains/addresses</a></h2>
<li>Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching.
-<li>Keith Stevenson: <a href="http://www.faqs.org/rfcs/rfc2254.html">RFC 2254</a> escaping in queries.
+<li>Keith Stevenson: <a href="http://tools.ietf.org/html/rfc2254">RFC 2254</a> escaping in queries.
<li>Samuel Tardieu: Noticed that searches could include wildcards, prompting
- the work on <a href="http://www.faqs.org/rfcs/rfc2254.html">RFC 2254</a> escaping in queries. Spotted a bug
+ the work on <a href="http://tools.ietf.org/html/rfc2254">RFC 2254</a> escaping in queries. Spotted a bug
in binding.
<li>Sami Haahtinen: Referral chasing and v3 support.
<tr> <td> {client_name} </td> <td> Always </td> <td> Client hostname,
"unknown" when lookup or verification fails </td> </tr>
-<tr> <td> {client_port} </td> <td> Always <br> (Postfix ≥2.5) </td>
+<tr> <td> {client_port} </td> <td> Always (Postfix ≥2.5) </td>
<td> Client TCP port </td> </tr>
<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
<p> Postfix sends specific sets of macros at different SMTP protocol
stages. The sets are configured with the parameters as described
-in the table (EOH = end of headers; EOM = end of message). </p>
+in the table (EOH = end of headers; EOM = end of message). The
+protocol version is a number that Postfix sends at the beginning
+of the Milter protocol handshake. </p>
<blockquote>
<h2>Building Postfix with MySQL support</h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the <a href="INSTALL.html">INSTALL</a> document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Note: to use mysql with Debian GNU/Linux's Postfix, all you
need is to install the postfix-mysql package and you're done.
There is no need to recompile Postfix. </p>
<h2>Building Postfix with PCRE support</h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the <a href="INSTALL.html">INSTALL</a> document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Note: to use pcre with Debian GNU/Linux's Postfix, all you
need is to install the postfix-pcre package and you're done. There
is no need to recompile Postfix. </p>
<h2>Building Postfix with PostgreSQL support</h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the <a href="INSTALL.html">INSTALL</a> document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Note: to use pgsql with Debian GNU/Linux's Postfix, all you
need to do is to install the postfix-pgsql package and you're done.
There is no need to recompile Postfix. </p>
<h2><a name="build_dovecot">Building Postfix with Dovecot SASL
support</a></h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the <a href="INSTALL.html">INSTALL</a> document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Support for the Dovecot version 1 SASL protocol is available
in Postfix 2.3 and later. At the time
of writing, only server-side SASL support is available, so you can't
<h2><a name="build_postfix">Building Postfix with Cyrus SASL support</a></h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the <a href="INSTALL.html">INSTALL</a> document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> The following
assumes that the Cyrus SASL include files are in /usr/local/include,
and that the Cyrus SASL libraries are in /usr/local/lib. </p>
<tr> <td>Network<tt>-> </tt> </td> <td align="center"
bgcolor="#f0f0ff"> <br> <a href="smtpd.8.html">smtpd(8)</a> <br> </td> <td colspan="2">
-<tt> <---seed---<br><br><-session-> </tt> </td> <td
+<tt> <---seed----<br><br><-key/cert-> </tt> </td> <td
align="center" bgcolor="#f0f0ff"> <br> <a href="tlsmgr.8.html">tlsmgr(8)</a> <br> </td>
-<td colspan="3"> <tt> ---seed---><br> <br><-session->
+<td colspan="3"> <tt> ----seed---><br> <br><-key/cert->
</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> <a href="smtp.8.html">smtp(8)</a> <br>
</td> <td> <tt> -></tt>Network </td> </tr>
<h2><a name="build_tls">Building Postfix with TLS support</a></h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the <a href="INSTALL.html">INSTALL</a> document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> To build Postfix with TLS support, first we need to generate
the <tt>make(1)</tt> files with the necessary definitions. This is
done by invoking the command "<tt>make makefiles</tt>" in the Postfix
</pre>
</blockquote>
-<li> <p> Create an unpassworded private key for host FOO and create
+<li> <p> Create an unpassworded private key for host foo.porcupine.org and create
an unsigned public key certificate. </p>
<blockquote>
<pre>
-% <b>openssl req -new -nodes -keyout FOO-key.pem -out FOO-req.pem -days 365</b>
+% <b>openssl req -new -nodes -keyout foo-key.pem -out foo-req.pem -days 365</b>
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
........................................++++++
....++++++
-writing new private key to 'FOO-key.pem'
+writing new private key to 'foo-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
Locality Name (eg, city) []:<b>Westchester</b>
Organization Name (eg, company) [Internet Widgits Pty Ltd]:<b>Porcupine</b>
Organizational Unit Name (eg, section) []:
-Common Name (eg, YOUR name) []:<b>FOO</b>
+Common Name (eg, YOUR name) []:<b>foo.porcupine.org</b>
Email Address []:<b>wietse@porcupine.org</b>
Please enter the following 'extra' attributes
</pre>
</blockquote>
-<li> <p> Sign the public key certificate for host FOO with the
+<li> <p> Sign the public key certificate for host foo.porcupine.org with the
Certification Authority private key that we created a few
steps ago. </p>
<blockquote>
<pre>
-% <b>openssl ca -out FOO-cert.pem -infiles FOO-req.pem</b>
+% <b>openssl ca -out foo-cert.pem -infiles foo-req.pem</b>
Using configuration from /etc/ssl/openssl.cnf
Enter PEM pass phrase:<b>whatever</b>
Check that the request matches the signature
stateOrProvinceName :PRINTABLE:'New York'
localityName :PRINTABLE:'Westchester'
organizationName :PRINTABLE:'Porcupine'
-commonName :PRINTABLE:'FOO'
+commonName :PRINTABLE:'foo.porcupine.org'
emailAddress :IA5STRING:'wietse@porcupine.org'
Certificate is to be certified until Nov 21 19:40:56 2005 GMT (365 days)
Sign the certificate? [y/n]:<b>y</b>
<blockquote>
<pre>
-# <b>cp demoCA/cacert.pem FOO-key.pem FOO-cert.pem /etc/postfix</b>
-# <b>chmod 644 /etc/postfix/FOO-cert.pem /etc/postfix/cacert.pem</b>
-# <b>chmod 400 /etc/postfix/FOO-key.pem</b>
+# <b>cp demoCA/cacert.pem foo-key.pem foo-cert.pem /etc/postfix</b>
+# <b>chmod 644 /etc/postfix/foo-cert.pem /etc/postfix/cacert.pem</b>
+# <b>chmod 400 /etc/postfix/foo-key.pem</b>
</pre>
</blockquote>
btree:/var/lib/postfix/smtp_tls_session_cache
<a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> = may
<a href="postconf.5.html#smtpd_tls_CAfile">smtpd_tls_CAfile</a> = /etc/postfix/cacert.pem
- <a href="postconf.5.html#smtpd_tls_cert_file">smtpd_tls_cert_file</a> = /etc/postfix/FOO-cert.pem
- <a href="postconf.5.html#smtpd_tls_key_file">smtpd_tls_key_file</a> = /etc/postfix/FOO-key.pem
+ <a href="postconf.5.html#smtpd_tls_cert_file">smtpd_tls_cert_file</a> = /etc/postfix/foo-cert.pem
+ <a href="postconf.5.html#smtpd_tls_key_file">smtpd_tls_key_file</a> = /etc/postfix/foo-key.pem
<a href="postconf.5.html#smtpd_tls_received_header">smtpd_tls_received_header</a> = yes
<a href="postconf.5.html#smtpd_tls_session_cache_database">smtpd_tls_session_cache_database</a> =
btree:/var/lib/postfix/smtpd_tls_session_cache
The SASL plug-in type that the Postfix SMTP client
should use for authentication.
+ Available in Postfix version 2.5 and later:
+
+ <b><a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> (empty)</b>
+ An optional table to prevent repeated SASL authen-
+ tication failures with the same remote SMTP server
+ hostname, username and password.
+
+ <b><a href="postconf.5.html#smtp_sasl_auth_cache_time">smtp_sasl_auth_cache_time</a> (90d)</b>
+ The maximal age of an <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a>
+ entry before it is removed.
+
+ <b><a href="postconf.5.html#smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a> (yes)</b>
+ When a remote SMTP server rejects a SASL authenti-
+ cation request with a 535 reply code, defer mail
+ delivery instead of returning mail as undeliver-
+ able.
+
<b>STARTTLS SUPPORT CONTROLS</b>
Detailed information about STARTTLS configuration may be
found in the <a href="TLS_README.html">TLS_README</a> document.
</p>
+</DD>
+
+<DT><b><a name="lmtp_sasl_auth_cache_name">lmtp_sasl_auth_cache_name</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a>
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="lmtp_sasl_auth_cache_time">lmtp_sasl_auth_cache_time</a>
+(default: 90d)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_sasl_auth_cache_time">smtp_sasl_auth_cache_time</a>
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+
</DD>
<DT><b><a name="lmtp_sasl_auth_enable">lmtp_sasl_auth_enable</a>
</p>
+</DD>
+
+<DT><b><a name="lmtp_sasl_auth_soft_bounce">lmtp_sasl_auth_soft_bounce</a>
+(default: yes)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a>
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+
</DD>
<DT><b><a name="lmtp_sasl_mechanism_filter">lmtp_sasl_mechanism_filter</a>
destinations, Postfix will try them in the specified order. </p>
<p> To prevent mailer loops between MX hosts and fall-back hosts,
-Postfix version 2.3 and later will not use the <a href="postconf.5.html#smtp_fallback_relay">smtp_fallback_relay</a>
-feature for destinations that it is MX host for. </p>
+Postfix version 2.2 and later will not use the fallback relays for
+destinations that it is MX host for (and DSN lookup is turned on).
+</p>
</DD>
<p> This feature is available in Postfix 2.1 and later. </p>
+</DD>
+
+<DT><b><a name="smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a>
+(default: empty)</b></DT><DD>
+
+<p> An optional table to prevent repeated SASL authentication
+failures with the same remote SMTP server hostname, username and
+password. Each table (key, value) pair contains a server name, a
+username and password, and the full server response. This information
+is stored when a remote SMTP server rejects an authentication attempt
+with a 535 reply code. As long as the <a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a>
+information does no change, and as long as the <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a>
+information does not expire (see <a href="postconf.5.html#smtp_sasl_auth_cache_time">smtp_sasl_auth_cache_time</a>) the
+Postfix SMTP client avoids SASL authentication attempts with the
+same server, username and password, and instead bounces or defers
+mail as controlled with the <a href="postconf.5.html#smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a> configuration
+parameter. </p>
+
+<p> The table must be accessed via the proxywrite service, i.e. the
+map name must start with "<a href="proxymap.8.html">proxy</a>:". The table should be stored under
+the directory specified with the <a href="postconf.5.html#data_directory">data_directory</a> parameter. </p>
+
+<p> This feature uses cryptographic hashing to protect plain-text
+passwords, and requires that Postfix is compiled with TLS support.
+</p>
+
+<p> Example: </p>
+
+<pre>
+<a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> = <a href="proxymap.8.html">proxy</a>:btree:/var/lib/postfix/sasl_auth_cache
+</pre>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+
+</DD>
+
+<DT><b><a name="smtp_sasl_auth_cache_time">smtp_sasl_auth_cache_time</a>
+(default: 90d)</b></DT><DD>
+
+<p> The maximal age of an <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> entry before it
+is removed. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+
</DD>
<DT><b><a name="smtp_sasl_auth_enable">smtp_sasl_auth_enable</a>
</pre>
+</DD>
+
+<DT><b><a name="smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a>
+(default: yes)</b></DT><DD>
+
+<p> When a remote SMTP server rejects a SASL authentication request
+with a 535 reply code, defer mail delivery instead of returning
+mail as undeliverable. The latter behavior was hard-coded prior to
+Postfix version 2.5. </p>
+
+<p> Note: the setting "yes" overrides the global <a href="postconf.5.html#soft_bounce">soft_bounce</a>
+parameter, but the setting "no" does not. </p>
+
+<p> Example: </p>
+
+<pre>
+# Default as of Postfix 2.5
+<a href="postconf.5.html#smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a> = yes
+# The old hard-coded default
+<a href="postconf.5.html#smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a> = no
+</pre>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+
</DD>
<DT><b><a name="smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a>
<a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> = hash:/etc/postfix/tls_policy
<a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> = md5
</pre>
+</blockquote>
+
+<blockquote>
<pre>
/etc/postfix/tls_policy:
example.com fingerprint
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
<a href="master.5.html">master.cf</a> configuration files.
+ <b><a href="postconf.5.html#data_directory">data_directory</a> (see 'postconf -d' output)</b>
+ The directory with Postfix-writable data files (for
+ example: caches, pseudo-random numbers).
+
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to
- handle a 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.
<b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
over an internal communication channel.
<b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
- 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.
<b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
- 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.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
- The process ID of a Postfix command or daemon
+ The process ID of a Postfix command or daemon
process.
<b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
<b><a href="postconf.5.html#proxy_read_maps">proxy_read_maps</a> (see 'postconf -d' output)</b>
- The lookup tables that the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server is
+ The lookup tables that the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server is
allowed to access for the read-only service.
Available in Postfix 2.5 and later:
example: caches, pseudo-random numbers).
<b><a href="postconf.5.html#proxy_write_maps">proxy_write_maps</a> (see 'postconf -d' output)</b>
- The lookup tables that the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server is
+ The lookup tables that the <a href="proxymap.8.html"><b>proxymap</b>(8)</a> server is
allowed to access for the read-write service.
<b>SEE ALSO</b>
<a href="DATABASE_README.html">DATABASE_README</a>, Postfix lookup table overview
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>HISTORY</b>
The SASL plug-in type that the Postfix SMTP client
should use for authentication.
+ Available in Postfix version 2.5 and later:
+
+ <b><a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> (empty)</b>
+ An optional table to prevent repeated SASL authen-
+ tication failures with the same remote SMTP server
+ hostname, username and password.
+
+ <b><a href="postconf.5.html#smtp_sasl_auth_cache_time">smtp_sasl_auth_cache_time</a> (90d)</b>
+ The maximal age of an <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a>
+ entry before it is removed.
+
+ <b><a href="postconf.5.html#smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a> (yes)</b>
+ When a remote SMTP server rejects a SASL authenti-
+ cation request with a 535 reply code, defer mail
+ delivery instead of returning mail as undeliver-
+ able.
+
<b>STARTTLS SUPPORT CONTROLS</b>
Detailed information about STARTTLS configuration may be
found in the <a href="TLS_README.html">TLS_README</a> document.
The default location of the Postfix <a href="postconf.5.html">main.cf</a> and
<a href="master.5.html">master.cf</a> configuration files.
+ <b><a href="postconf.5.html#data_directory">data_directory</a> (see 'postconf -d' output)</b>
+ The directory with Postfix-writable data files (for
+ example: caches, pseudo-random numbers).
+
<b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
- How much time a Postfix daemon process may take to
- handle a 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.
<b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
- The process ID of a Postfix command or daemon
+ The process ID of a Postfix command or daemon
process.
<b><a href="postconf.5.html#process_name">process_name</a> (read-only)</b>
- The process name of a Postfix command or daemon
+ The process name of a Postfix command or daemon
process.
<b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
The syslog facility of Postfix logging.
<b><a href="postconf.5.html#syslog_name">syslog_name</a> (postfix)</b>
- 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".
<b>SEE ALSO</b>
<a href="TLS_README.html">TLS_README</a>, Postfix TLS configuration and operation
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
.PP
Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
The default time unit is s (seconds).
+.SH lmtp_sasl_auth_cache_name (default: empty)
+The LMTP-specific version of the smtp_sasl_auth_cache_name
+configuration parameter. See there for details.
+.PP
+This feature is available in Postfix 2.5 and later.
+.SH lmtp_sasl_auth_cache_time (default: 90d)
+The LMTP-specific version of the smtp_sasl_auth_cache_time
+configuration parameter. See there for details.
+.PP
+This feature is available in Postfix 2.5 and later.
.SH lmtp_sasl_auth_enable (default: no)
Enable SASL authentication in the Postfix LMTP client.
+.SH lmtp_sasl_auth_soft_bounce (default: yes)
+The LMTP-specific version of the smtp_sasl_auth_soft_bounce
+configuration parameter. See there for details.
+.PP
+This feature is available in Postfix 2.5 and later.
.SH lmtp_sasl_mechanism_filter (default: empty)
The LMTP-specific version of the smtp_sasl_mechanism_filter
configuration parameter. See there for details.
destinations, Postfix will try them in the specified order.
.PP
To prevent mailer loops between MX hosts and fall-back hosts,
-Postfix version 2.3 and later will not use the smtp_fallback_relay
-feature for destinations that it is MX host for.
+Postfix version 2.2 and later will not use the fallback relays for
+destinations that it is MX host for (and DSN lookup is turned on).
.SH smtp_generic_maps (default: empty)
Optional lookup tables that perform address rewriting in the
SMTP client, typically to transform a locally valid address into
cached session is still usable.
.PP
This feature is available in Postfix 2.1 and later.
+.SH smtp_sasl_auth_cache_name (default: empty)
+An optional table to prevent repeated SASL authentication
+failures with the same remote SMTP server hostname, username and
+password. Each table (key, value) pair contains a server name, a
+username and password, and the full server response. This information
+is stored when a remote SMTP server rejects an authentication attempt
+with a 535 reply code. As long as the smtp_sasl_password_maps
+information does no change, and as long as the smtp_sasl_auth_cache_name
+information does not expire (see smtp_sasl_auth_cache_time) the
+Postfix SMTP client avoids SASL authentication attempts with the
+same server, username and password, and instead bounces or defers
+mail as controlled with the smtp_sasl_auth_soft_bounce configuration
+parameter.
+.PP
+The table must be accessed via the proxywrite service, i.e. the
+map name must start with "proxy:". The table should be stored under
+the directory specified with the data_directory parameter.
+.PP
+This feature uses cryptographic hashing to protect plain-text
+passwords, and requires that Postfix is compiled with TLS support.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+smtp_sasl_auth_cache_name = proxy:btree:/var/lib/postfix/sasl_auth_cache
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 2.5 and later.
+.SH smtp_sasl_auth_cache_time (default: 90d)
+The maximal age of an smtp_sasl_auth_cache_name entry before it
+is removed.
+.PP
+This feature is available in Postfix 2.5 and later.
.SH smtp_sasl_auth_enable (default: no)
Enable SASL authentication in the Postfix SMTP client. By default,
the Postfix SMTP client uses no authentication.
.fi
.ad
.ft R
+.SH smtp_sasl_auth_soft_bounce (default: yes)
+When a remote SMTP server rejects a SASL authentication request
+with a 535 reply code, defer mail delivery instead of returning
+mail as undeliverable. The latter behavior was hard-coded prior to
+Postfix version 2.5.
+.PP
+Note: the setting "yes" overrides the global soft_bounce
+parameter, but the setting "no" does not.
+.PP
+Example:
+.PP
+.nf
+.na
+.ft C
+# Default as of Postfix 2.5
+smtp_sasl_auth_soft_bounce = yes
+# The old hard-coded default
+smtp_sasl_auth_soft_bounce = no
+.fi
+.ad
+.ft R
+.PP
+This feature is available in Postfix 2.5 and later.
.SH smtp_sasl_mechanism_filter (default: empty)
If non-empty, a Postfix SMTP client filter for the remote SMTP
server's list of offered SASL mechanisms. Different client and
.fi
.ad
.ft R
+.in -4
+.sp
+.in +4
.nf
.na
.ft C
.IP "\fBconfig_directory (see 'postconf -d' output)\fR"
The default location of the Postfix main.cf and master.cf
configuration files.
+.IP "\fBdata_directory (see 'postconf -d' output)\fR"
+The directory with Postfix-writable data files (for example:
+caches, pseudo-random numbers).
.IP "\fBdaemon_timeout (18000s)\fR"
How much time a Postfix daemon process may take to handle a
request before it is terminated by a built-in watchdog timer.
.IP "\fBsmtp_sasl_type (cyrus)\fR"
The SASL plug-in type that the Postfix SMTP client should use
for authentication.
+.PP
+Available in Postfix version 2.5 and later:
+.IP "\fBsmtp_sasl_auth_cache_name (empty)\fR"
+An optional table to prevent repeated SASL authentication
+failures with the same remote SMTP server hostname, username and
+password.
+.IP "\fBsmtp_sasl_auth_cache_time (90d)\fR"
+The maximal age of an smtp_sasl_auth_cache_name entry before it
+is removed.
+.IP "\fBsmtp_sasl_auth_soft_bounce (yes)\fR"
+When a remote SMTP server rejects a SASL authentication request
+with a 535 reply code, defer mail delivery instead of returning
+mail as undeliverable.
.SH "STARTTLS SUPPORT CONTROLS"
.na
.nf
.IP "\fBconfig_directory (see 'postconf -d' output)\fR"
The default location of the Postfix main.cf and master.cf
configuration files.
+.IP "\fBdata_directory (see 'postconf -d' output)\fR"
+The directory with Postfix-writable data files (for example:
+caches, pseudo-random numbers).
.IP "\fBdaemon_timeout (18000s)\fR"
How much time a Postfix daemon process may take to handle a
request before it is terminated by a built-in watchdog timer.
s;\blmtp_quit_timeout\b;<a href="postconf.5.html#lmtp_quit_timeout">$&</a>;g;
s;\blmtp_rcpt_timeout\b;<a href="postconf.5.html#lmtp_rcpt_timeout">$&</a>;g;
s;\blmtp_rset_timeout\b;<a href="postconf.5.html#lmtp_rset_timeout">$&</a>;g;
+ s;\blmtp_sasl_auth_cache_name\b;<a href="postconf.5.html#lmtp_sasl_auth_cache_name">$&</a>;g;
+ s;\blmtp_sasl_auth_cache_time\b;<a href="postconf.5.html#lmtp_sasl_auth_cache_time">$&</a>;g;
s;\blmtp_sasl_auth_enable\b;<a href="postconf.5.html#lmtp_sasl_auth_enable">$&</a>;g;
+ s;\blmtp_sasl_auth_soft_bounce\b;<a href="postconf.5.html#lmtp_sasl_auth_soft_bounce">$&</a>;g;
s;\blmtp_sasl_password_maps\b;<a href="postconf.5.html#lmtp_sasl_password_maps">$&</a>;g;
s;\blmtp_sasl_security_options\b;<a href="postconf.5.html#lmtp_sasl_security_options">$&</a>;g;
s;\blmtp_sasl_type\b;<a href="postconf.5.html#lmtp_sasl_type">$&</a>;g;
s;\bsmtp_randomize_addresses\b;<a href="postconf.5.html#smtp_randomize_addresses">$&</a>;g;
s;\bsmtp_rcpt_timeout\b;<a href="postconf.5.html#smtp_rcpt_timeout">$&</a>;g;
s;\bsmtp_rset_timeout\b;<a href="postconf.5.html#smtp_rset_timeout">$&</a>;g;
+ s;\bsmtp_sasl_auth_cache_name\b;<a href="postconf.5.html#smtp_sasl_auth_cache_name">$&</a>;g;
+ s;\bsmtp_sasl_auth_cache_time\b;<a href="postconf.5.html#smtp_sasl_auth_cache_time">$&</a>;g;
s;\bsmtp_sasl_auth_enable\b;<a href="postconf.5.html#smtp_sasl_auth_enable">$&</a>;g;
+ s;\bsmtp_sasl_auth_soft_bounce\b;<a href="postconf.5.html#smtp_sasl_auth_soft_bounce">$&</a>;g;
s;\bsmtp_sasl_mechanism_filter\b;<a href="postconf.5.html#smtp_sasl_mechanism_filter">$&</a>;g;
s;\bsmtp_sasl_pass[-</Bb>]*\n* *[<Bb>]*word_maps\b;<a href="postconf.5.html#smtp_sasl_password_maps">$&</a>;g;
s;\bsmtp_sasl_path\b;<a href="postconf.5.html#smtp_sasl_path">$&</a>;g;
<p> CDB support is available with Postfix 2.2 and later releases.
This document describes how to build Postfix with CDB support. </p>
-<h2>Building Postfix with CDB</h2>
+<h2>Building Postfix with CDB support</h2>
+
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
<p> Postfix is compatible with two CDB implementations: </p>
<h2><a name="build">Building Postfix with LDAP support</a></h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Note 1: Postfix no longer supports the LDAP version 1 interface.
</p>
<tr> <td> {client_name} </td> <td> Always </td> <td> Client hostname,
"unknown" when lookup or verification fails </td> </tr>
-<tr> <td> {client_port} </td> <td> Always <br> (Postfix ≥2.5) </td>
+<tr> <td> {client_port} </td> <td> Always (Postfix ≥2.5) </td>
<td> Client TCP port </td> </tr>
<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
<p> Postfix sends specific sets of macros at different SMTP protocol
stages. The sets are configured with the parameters as described
-in the table (EOH = end of headers; EOM = end of message). </p>
+in the table (EOH = end of headers; EOM = end of message). The
+protocol version is a number that Postfix sends at the beginning
+of the Milter protocol handshake. </p>
<blockquote>
<h2>Building Postfix with MySQL support</h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Note: to use mysql with Debian GNU/Linux's Postfix, all you
need is to install the postfix-mysql package and you're done.
There is no need to recompile Postfix. </p>
<h2>Building Postfix with PCRE support</h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Note: to use pcre with Debian GNU/Linux's Postfix, all you
need is to install the postfix-pcre package and you're done. There
is no need to recompile Postfix. </p>
<h2>Building Postfix with PostgreSQL support</h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Note: to use pgsql with Debian GNU/Linux's Postfix, all you
need to do is to install the postfix-pgsql package and you're done.
There is no need to recompile Postfix. </p>
<h2><a name="build_dovecot">Building Postfix with Dovecot SASL
support</a></h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> Support for the Dovecot version 1 SASL protocol is available
in Postfix 2.3 and later. At the time
of writing, only server-side SASL support is available, so you can't
<h2><a name="build_postfix">Building Postfix with Cyrus SASL support</a></h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> The following
assumes that the Cyrus SASL include files are in /usr/local/include,
and that the Cyrus SASL libraries are in /usr/local/lib. </p>
<tr> <td>Network<tt>-> </tt> </td> <td align="center"
bgcolor="#f0f0ff"> <br> <a href="smtpd.8.html">smtpd(8)</a> <br> </td> <td colspan="2">
-<tt> <---seed---<br><br><-session-> </tt> </td> <td
+<tt> <---seed----<br><br><-key/cert-> </tt> </td> <td
align="center" bgcolor="#f0f0ff"> <br> <a href="tlsmgr.8.html">tlsmgr(8)</a> <br> </td>
-<td colspan="3"> <tt> ---seed---><br> <br><-session->
+<td colspan="3"> <tt> ----seed---><br> <br><-key/cert->
</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> <a href="smtp.8.html">smtp(8)</a> <br>
</td> <td> <tt> -></tt>Network </td> </tr>
<h2><a name="build_tls">Building Postfix with TLS support</a></h2>
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. Some modification may
+be required if you build Postfix from a vendor-specific source
+package. </p>
+
<p> To build Postfix with TLS support, first we need to generate
the <tt>make(1)</tt> files with the necessary definitions. This is
done by invoking the command "<tt>make makefiles</tt>" in the Postfix
</pre>
</blockquote>
-<li> <p> Create an unpassworded private key for host FOO and create
+<li> <p> Create an unpassworded private key for host foo.porcupine.org and create
an unsigned public key certificate. </p>
<blockquote>
<pre>
-% <b>openssl req -new -nodes -keyout FOO-key.pem -out FOO-req.pem -days 365</b>
+% <b>openssl req -new -nodes -keyout foo-key.pem -out foo-req.pem -days 365</b>
Using configuration from /etc/ssl/openssl.cnf
Generating a 1024 bit RSA private key
........................................++++++
....++++++
-writing new private key to 'FOO-key.pem'
+writing new private key to 'foo-key.pem'
-----
You are about to be asked to enter information that will be incorporated
into your certificate request.
Locality Name (eg, city) []:<b>Westchester</b>
Organization Name (eg, company) [Internet Widgits Pty Ltd]:<b>Porcupine</b>
Organizational Unit Name (eg, section) []:
-Common Name (eg, YOUR name) []:<b>FOO</b>
+Common Name (eg, YOUR name) []:<b>foo.porcupine.org</b>
Email Address []:<b>wietse@porcupine.org</b>
Please enter the following 'extra' attributes
</pre>
</blockquote>
-<li> <p> Sign the public key certificate for host FOO with the
+<li> <p> Sign the public key certificate for host foo.porcupine.org with the
Certification Authority private key that we created a few
steps ago. </p>
<blockquote>
<pre>
-% <b>openssl ca -out FOO-cert.pem -infiles FOO-req.pem</b>
+% <b>openssl ca -out foo-cert.pem -infiles foo-req.pem</b>
Using configuration from /etc/ssl/openssl.cnf
Enter PEM pass phrase:<b>whatever</b>
Check that the request matches the signature
stateOrProvinceName :PRINTABLE:'New York'
localityName :PRINTABLE:'Westchester'
organizationName :PRINTABLE:'Porcupine'
-commonName :PRINTABLE:'FOO'
+commonName :PRINTABLE:'foo.porcupine.org'
emailAddress :IA5STRING:'wietse@porcupine.org'
Certificate is to be certified until Nov 21 19:40:56 2005 GMT (365 days)
Sign the certificate? [y/n]:<b>y</b>
<blockquote>
<pre>
-# <b>cp demoCA/cacert.pem FOO-key.pem FOO-cert.pem /etc/postfix</b>
-# <b>chmod 644 /etc/postfix/FOO-cert.pem /etc/postfix/cacert.pem</b>
-# <b>chmod 400 /etc/postfix/FOO-key.pem</b>
+# <b>cp demoCA/cacert.pem foo-key.pem foo-cert.pem /etc/postfix</b>
+# <b>chmod 644 /etc/postfix/foo-cert.pem /etc/postfix/cacert.pem</b>
+# <b>chmod 400 /etc/postfix/foo-key.pem</b>
</pre>
</blockquote>
btree:/var/lib/postfix/smtp_tls_session_cache
smtp_tls_security_level = may
smtpd_tls_CAfile = /etc/postfix/cacert.pem
- smtpd_tls_cert_file = /etc/postfix/FOO-cert.pem
- smtpd_tls_key_file = /etc/postfix/FOO-key.pem
+ smtpd_tls_cert_file = /etc/postfix/foo-cert.pem
+ smtpd_tls_key_file = /etc/postfix/foo-key.pem
smtpd_tls_received_header = yes
smtpd_tls_session_cache_database =
btree:/var/lib/postfix/smtpd_tls_session_cache
# tool:
#
# * Supported HTML elements are: blockquote, ul, li, dl, dt, dd,
-# p, pre, b, i, h, and the escapes for < and >. Sorry, no tables.
+# p, pre, b, i, h, and the escapes for < <= >= >. Sorry, no
+# tables.
#
# * HTML elements must be specified in lower case.
#
# * Text between <!-- and --> is stripped out. The <!-- and -->
# must appear on separate lines.
#
+# * Blank lines are special for postconf2man: it replaces them by
+# a "new paragraph" command. Don't put any blank lines inside
+# <blockquote> text. Instead, put those blank lines between
+# </blockquote> and <blockquote>.
+#
# * Text after a blank line must start with an HTML element.
#
# Also:
destinations, Postfix will try them in the specified order. </p>
<p> To prevent mailer loops between MX hosts and fall-back hosts,
-Postfix version 2.3 and later will not use the smtp_fallback_relay
-feature for destinations that it is MX host for. </p>
+Postfix version 2.2 and later will not use the fallback relays for
+destinations that it is MX host for (and DSN lookup is turned on).
+</p>
%PARAM fallback_relay
smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
smtp_tls_fingerprint_digest = md5
</pre>
+</blockquote>
+
+<blockquote>
<pre>
/etc/postfix/tls_policy:
example.com fingerprint
<p> This feature is available in Postfix 2.5 and later. </p>
+%PARAM smtp_sasl_auth_soft_bounce yes
+
+<p> When a remote SMTP server rejects a SASL authentication request
+with a 535 reply code, defer mail delivery instead of returning
+mail as undeliverable. The latter behavior was hard-coded prior to
+Postfix version 2.5. </p>
+
+<p> Note: the setting "yes" overrides the global soft_bounce
+parameter, but the setting "no" does not. </p>
+
+<p> Example: </p>
+
+<pre>
+# Default as of Postfix 2.5
+smtp_sasl_auth_soft_bounce = yes
+# The old hard-coded default
+smtp_sasl_auth_soft_bounce = no
+</pre>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM smtp_sasl_auth_cache_name
+
+<p> An optional table to prevent repeated SASL authentication
+failures with the same remote SMTP server hostname, username and
+password. Each table (key, value) pair contains a server name, a
+username and password, and the full server response. This information
+is stored when a remote SMTP server rejects an authentication attempt
+with a 535 reply code. As long as the smtp_sasl_password_maps
+information does no change, and as long as the smtp_sasl_auth_cache_name
+information does not expire (see smtp_sasl_auth_cache_time) the
+Postfix SMTP client avoids SASL authentication attempts with the
+same server, username and password, and instead bounces or defers
+mail as controlled with the smtp_sasl_auth_soft_bounce configuration
+parameter. </p>
+
+<p> The table must be accessed via the proxywrite service, i.e. the
+map name must start with "proxy:". The table should be stored under
+the directory specified with the data_directory parameter. </p>
+
+<p> This feature uses cryptographic hashing to protect plain-text
+passwords, and requires that Postfix is compiled with TLS support.
+</p>
+
+<p> Example: </p>
+
+<pre>
+smtp_sasl_auth_cache_name = proxy:btree:/var/lib/postfix/sasl_auth_cache
+</pre>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM smtp_sasl_auth_cache_time 90d
+
+<p> The maximal age of an smtp_sasl_auth_cache_name entry before it
+is removed. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_sasl_auth_soft_bounce yes
+
+<p> The LMTP-specific version of the smtp_sasl_auth_soft_bounce
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_sasl_auth_cache_name
+
+<p> The LMTP-specific version of the smtp_sasl_auth_cache_name
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_sasl_auth_cache_time 90d
+
+<p> The LMTP-specific version of the smtp_sasl_auth_cache_time
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
#define DEF_CYRUS_SASL_AUTHZID 0
extern int var_cyrus_sasl_authzid;
+ /*
+ * Special handling of AUTH 535 failures.
+ */
+#define VAR_SMTP_SASL_AUTH_SOFT_BOUNCE "smtp_sasl_auth_soft_bounce"
+#define DEF_SMTP_SASL_AUTH_SOFT_BOUNCE 1
+#define VAR_LMTP_SASL_AUTH_SOFT_BOUNCE "lmtp_sasl_auth_soft_bounce"
+#define DEF_LMTP_SASL_AUTH_SOFT_BOUNCE 1
+extern bool var_smtp_sasl_auth_soft_bounce;
+
+#define VAR_SMTP_SASL_AUTH_CACHE_NAME "smtp_sasl_auth_cache_name"
+#define DEF_SMTP_SASL_AUTH_CACHE_NAME ""
+#define VAR_LMTP_SASL_AUTH_CACHE_NAME "lmtp_sasl_auth_cache_name"
+#define DEF_LMTP_SASL_AUTH_CACHE_NAME ""
+extern char *var_smtp_sasl_auth_cache_name;
+
+#define VAR_SMTP_SASL_AUTH_CACHE_TIME "smtp_sasl_auth_cache_time"
+#define DEF_SMTP_SASL_AUTH_CACHE_TIME "90d"
+#define VAR_LMTP_SASL_AUTH_CACHE_TIME "lmtp_sasl_auth_cache_time"
+#define DEF_LMTP_SASL_AUTH_CACHE_TIME "90d"
+extern int var_smtp_sasl_auth_cache_time;
+
/*
* LMTP client. Timeouts inspired by RFC 1123. The LMTP recipient limit
* determines how many recipient addresses the LMTP client sends along with
extern char *var_proxy_read_maps;
#define VAR_PROXY_WRITE_MAPS "proxy_write_maps"
-#define DEF_PROXY_WRITE_MAPS "" /* Add here: "$" VAR_AUTH_FAIL_MAP */
+#define DEF_PROXY_WRITE_MAPS "$" VAR_SMTP_SASL_AUTH_CACHE_NAME \
+ " $" VAR_LMTP_SASL_AUTH_CACHE_NAME
extern char *var_proxy_write_maps;
/*
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20080109"
+#define MAIL_RELEASE_DATE "20080114"
#define MAIL_VERSION_NUMBER "2.5"
#ifdef SNAPSHOT
#define SMFIA_INET6 '6' /* inet6 */
/*
- * External macro set numbers, to identify the optional macro name lists
+ * External macro class numbers, to identify the optional macro name lists
* that may be sent after the initial negotiation header.
*/
#define SMFIM_CONNECT 0 /* macros for connect */
};
/*
- * Mapping from external macro set numbers to our internal MILTER_MACROS
+ * Mapping from external macro class numbers to our internal MILTER_MACROS
* structure members, without using a switch statement.
*/
static const size_t milter8_macro_offsets[] = {
offsetof(MILTER_MACROS, eoh_macros),/* Note: SMFIM_EOH > SMFIM_EOM */
};
-#define MILTER8_MACRO_PTR(__macros, __type) \
- ((char **) (((char *) (__macros)) + milter8_macro_offsets[(__type)]))
+#define MILTER8_MACRO_PTR(__macros, __class) \
+ ((char **) (((char *) (__macros)) + milter8_macro_offsets[(__class)]))
/*
* How much buffer space is available for sending body content.
/*
* null_sender=string
*/
- else if (strncasecmp("null_sender=", *argv, sizeof("eol=") - 1) == 0) {
+ else if (strncasecmp("null_sender=", *argv, sizeof("null_sender=") - 1) == 0) {
vstring_strcpy(attr->null_sender, *argv + sizeof("null_sender=") - 1);
}
/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
/* The default location of the Postfix main.cf and master.cf
/* configuration files.
+/* .IP "\fBdata_directory (see 'postconf -d' output)\fR"
+/* The directory with Postfix-writable data files (for example:
+/* caches, pseudo-random numbers).
/* .IP "\fBdaemon_timeout (18000s)\fR"
/* How much time a Postfix daemon process may take to handle a
/* request before it is terminated by a built-in watchdog timer.
SHELL = /bin/sh
SRCS = smtp.c smtp_connect.c smtp_proto.c smtp_chat.c smtp_session.c \
smtp_addr.c smtp_trouble.c smtp_state.c smtp_rcpt.c \
- smtp_sasl_proto.c smtp_sasl_glue.c smtp_reuse.c smtp_map11.c
+ smtp_sasl_proto.c smtp_sasl_glue.c smtp_reuse.c smtp_map11.c \
+ smtp_sasl_auth_cache.c
OBJS = smtp.o smtp_connect.o smtp_proto.o smtp_chat.o smtp_session.o \
smtp_addr.o smtp_trouble.o smtp_state.o smtp_rcpt.o \
- smtp_sasl_proto.o smtp_sasl_glue.o smtp_reuse.o smtp_map11.o
-HDRS = smtp.h smtp_sasl.h smtp_addr.h smtp_reuse.h
+ smtp_sasl_proto.o smtp_sasl_glue.o smtp_reuse.o smtp_map11.o \
+ smtp_sasl_auth_cache.o
+HDRS = smtp.h smtp_sasl.h smtp_addr.h smtp_reuse.h smtp_sasl_auth_cache.h
TESTSRC =
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
smtp_addr.o: ../../include/myaddrinfo.h
smtp_addr.o: ../../include/mymalloc.h
smtp_addr.o: ../../include/name_code.h
-smtp_addr.o: ../../include/name_mask.h
smtp_addr.o: ../../include/own_inet_addr.h
smtp_addr.o: ../../include/recipient_list.h
smtp_addr.o: ../../include/resolve_clnt.h
smtp_map11.o: ../../include/msg.h
smtp_map11.o: ../../include/msg_stats.h
smtp_map11.o: ../../include/name_code.h
-smtp_map11.o: ../../include/name_mask.h
smtp_map11.o: ../../include/quote_822_local.h
smtp_map11.o: ../../include/quote_flags.h
smtp_map11.o: ../../include/recipient_list.h
smtp_rcpt.o: ../../include/msg_stats.h
smtp_rcpt.o: ../../include/mymalloc.h
smtp_rcpt.o: ../../include/name_code.h
-smtp_rcpt.o: ../../include/name_mask.h
smtp_rcpt.o: ../../include/recipient_list.h
smtp_rcpt.o: ../../include/resolve_clnt.h
smtp_rcpt.o: ../../include/scache.h
smtp_reuse.o: ../../include/msg_stats.h
smtp_reuse.o: ../../include/mymalloc.h
smtp_reuse.o: ../../include/name_code.h
-smtp_reuse.o: ../../include/name_mask.h
smtp_reuse.o: ../../include/recipient_list.h
smtp_reuse.o: ../../include/resolve_clnt.h
smtp_reuse.o: ../../include/scache.h
smtp_reuse.o: smtp.h
smtp_reuse.o: smtp_reuse.c
smtp_reuse.o: smtp_reuse.h
+smtp_sasl_auth_cache.o: ../../include/argv.h
+smtp_sasl_auth_cache.o: ../../include/attr.h
+smtp_sasl_auth_cache.o: ../../include/base64_code.h
+smtp_sasl_auth_cache.o: ../../include/deliver_request.h
+smtp_sasl_auth_cache.o: ../../include/dict.h
+smtp_sasl_auth_cache.o: ../../include/dict_proxy.h
+smtp_sasl_auth_cache.o: ../../include/dsn.h
+smtp_sasl_auth_cache.o: ../../include/dsn_buf.h
+smtp_sasl_auth_cache.o: ../../include/dsn_util.h
+smtp_sasl_auth_cache.o: ../../include/header_body_checks.h
+smtp_sasl_auth_cache.o: ../../include/header_opts.h
+smtp_sasl_auth_cache.o: ../../include/htable.h
+smtp_sasl_auth_cache.o: ../../include/maps.h
+smtp_sasl_auth_cache.o: ../../include/match_list.h
+smtp_sasl_auth_cache.o: ../../include/match_ops.h
+smtp_sasl_auth_cache.o: ../../include/mime_state.h
+smtp_sasl_auth_cache.o: ../../include/msg.h
+smtp_sasl_auth_cache.o: ../../include/msg_stats.h
+smtp_sasl_auth_cache.o: ../../include/mymalloc.h
+smtp_sasl_auth_cache.o: ../../include/name_code.h
+smtp_sasl_auth_cache.o: ../../include/recipient_list.h
+smtp_sasl_auth_cache.o: ../../include/resolve_clnt.h
+smtp_sasl_auth_cache.o: ../../include/scache.h
+smtp_sasl_auth_cache.o: ../../include/string_list.h
+smtp_sasl_auth_cache.o: ../../include/stringops.h
+smtp_sasl_auth_cache.o: ../../include/sys_defs.h
+smtp_sasl_auth_cache.o: ../../include/tls.h
+smtp_sasl_auth_cache.o: ../../include/tok822.h
+smtp_sasl_auth_cache.o: ../../include/vbuf.h
+smtp_sasl_auth_cache.o: ../../include/vstream.h
+smtp_sasl_auth_cache.o: ../../include/vstring.h
+smtp_sasl_auth_cache.o: smtp.h
+smtp_sasl_auth_cache.o: smtp_sasl_auth_cache.c
+smtp_sasl_auth_cache.o: smtp_sasl_auth_cache.h
smtp_sasl_glue.o: ../../include/argv.h
smtp_sasl_glue.o: ../../include/attr.h
smtp_sasl_glue.o: ../../include/deliver_request.h
smtp_sasl_glue.o: ../../include/msg_stats.h
smtp_sasl_glue.o: ../../include/mymalloc.h
smtp_sasl_glue.o: ../../include/name_code.h
-smtp_sasl_glue.o: ../../include/name_mask.h
smtp_sasl_glue.o: ../../include/recipient_list.h
smtp_sasl_glue.o: ../../include/resolve_clnt.h
smtp_sasl_glue.o: ../../include/scache.h
smtp_sasl_glue.o: ../../include/xsasl.h
smtp_sasl_glue.o: smtp.h
smtp_sasl_glue.o: smtp_sasl.h
+smtp_sasl_glue.o: smtp_sasl_auth_cache.h
smtp_sasl_glue.o: smtp_sasl_glue.c
smtp_sasl_proto.o: ../../include/argv.h
smtp_sasl_proto.o: ../../include/attr.h
smtp_sasl_proto.o: ../../include/msg_stats.h
smtp_sasl_proto.o: ../../include/mymalloc.h
smtp_sasl_proto.o: ../../include/name_code.h
-smtp_sasl_proto.o: ../../include/name_mask.h
smtp_sasl_proto.o: ../../include/recipient_list.h
smtp_sasl_proto.o: ../../include/resolve_clnt.h
smtp_sasl_proto.o: ../../include/scache.h
smtp_session.o: ../../include/msg_stats.h
smtp_session.o: ../../include/mymalloc.h
smtp_session.o: ../../include/name_code.h
-smtp_session.o: ../../include/name_mask.h
smtp_session.o: ../../include/recipient_list.h
smtp_session.o: ../../include/resolve_clnt.h
smtp_session.o: ../../include/scache.h
smtp_state.o: ../../include/msg_stats.h
smtp_state.o: ../../include/mymalloc.h
smtp_state.o: ../../include/name_code.h
-smtp_state.o: ../../include/name_mask.h
smtp_state.o: ../../include/recipient_list.h
smtp_state.o: ../../include/resolve_clnt.h
smtp_state.o: ../../include/scache.h
smtp_unalias.o: ../../include/msg_stats.h
smtp_unalias.o: ../../include/myaddrinfo.h
smtp_unalias.o: ../../include/name_code.h
-smtp_unalias.o: ../../include/name_mask.h
smtp_unalias.o: ../../include/recipient_list.h
smtp_unalias.o: ../../include/resolve_clnt.h
smtp_unalias.o: ../../include/scache.h
VAR_LMTP_TCP_PORT, DEF_LMTP_TCP_PORT, &var_lmtp_tcp_port, 0, 0,
VAR_LMTP_PIX_BUG_WORDS, DEF_LMTP_PIX_BUG_WORDS, &var_smtp_pix_bug_words, 0, 0,
VAR_LMTP_PIX_BUG_MAPS, DEF_LMTP_PIX_BUG_MAPS, &var_smtp_pix_bug_maps, 0, 0,
+ VAR_LMTP_SASL_AUTH_CACHE_NAME, DEF_LMTP_SASL_AUTH_CACHE_NAME, &var_smtp_sasl_auth_cache_name, 0, 0,
VAR_CYRUS_CONF_PATH, DEF_CYRUS_CONF_PATH, &var_cyrus_conf_path, 0, 0,
VAR_LMTP_HEAD_CHKS, DEF_LMTP_HEAD_CHKS, &var_smtp_head_chks, 0, 0,
VAR_LMTP_MIME_CHKS, DEF_LMTP_MIME_CHKS, &var_smtp_mime_chks, 0, 0,
VAR_LMTP_STARTTLS_TMOUT, DEF_LMTP_STARTTLS_TMOUT, &var_smtp_starttls_tmout, 1, 0,
#endif
VAR_SCACHE_PROTO_TMOUT, DEF_SCACHE_PROTO_TMOUT, &var_scache_proto_tmout, 1, 0,
+ VAR_LMTP_SASL_AUTH_CACHE_TIME, DEF_LMTP_SASL_AUTH_CACHE_TIME, &var_smtp_sasl_auth_cache_time, 0, 0,
0,
};
static const CONFIG_INT_TABLE lmtp_int_table[] = {
#endif
VAR_LMTP_SENDER_AUTH, DEF_LMTP_SENDER_AUTH, &var_smtp_sender_auth,
VAR_LMTP_CNAME_OVERR, DEF_LMTP_CNAME_OVERR, &var_smtp_cname_overr,
+ VAR_LMTP_SASL_AUTH_SOFT_BOUNCE, DEF_LMTP_SASL_AUTH_SOFT_BOUNCE, &var_smtp_sasl_auth_soft_bounce,
0,
};
/* .IP "\fBsmtp_sasl_type (cyrus)\fR"
/* The SASL plug-in type that the Postfix SMTP client should use
/* for authentication.
+/* .PP
+/* Available in Postfix version 2.5 and later:
+/* .IP "\fBsmtp_sasl_auth_cache_name (empty)\fR"
+/* An optional table to prevent repeated SASL authentication
+/* failures with the same remote SMTP server hostname, username and
+/* password.
+/* .IP "\fBsmtp_sasl_auth_cache_time (90d)\fR"
+/* The maximal age of an smtp_sasl_auth_cache_name entry before it
+/* is removed.
+/* .IP "\fBsmtp_sasl_auth_soft_bounce (yes)\fR"
+/* When a remote SMTP server rejects a SASL authentication request
+/* with a 535 reply code, defer mail delivery instead of returning
+/* mail as undeliverable.
/* STARTTLS SUPPORT CONTROLS
/* .ad
/* .fi
char *var_smtp_nest_chks;
char *var_smtp_body_chks;
+ /* Special handling of 535 AUTH errors. */
+char *var_smtp_sasl_auth_cache_name;
+int var_smtp_sasl_auth_cache_time;
+bool var_smtp_sasl_auth_soft_bounce;
+
/*
* Global variables.
*/
VAR_LMTP_TCP_PORT, DEF_LMTP_TCP_PORT, &var_lmtp_tcp_port, 0, 0,
VAR_SMTP_PIX_BUG_WORDS, DEF_SMTP_PIX_BUG_WORDS, &var_smtp_pix_bug_words, 0, 0,
VAR_SMTP_PIX_BUG_MAPS, DEF_SMTP_PIX_BUG_MAPS, &var_smtp_pix_bug_maps, 0, 0,
+ VAR_SMTP_SASL_AUTH_CACHE_NAME, DEF_SMTP_SASL_AUTH_CACHE_NAME, &var_smtp_sasl_auth_cache_name, 0, 0,
VAR_CYRUS_CONF_PATH, DEF_CYRUS_CONF_PATH, &var_cyrus_conf_path, 0, 0,
VAR_SMTP_HEAD_CHKS, DEF_SMTP_HEAD_CHKS, &var_smtp_head_chks, 0, 0,
VAR_SMTP_MIME_CHKS, DEF_SMTP_MIME_CHKS, &var_smtp_mime_chks, 0, 0,
VAR_SMTP_STARTTLS_TMOUT, DEF_SMTP_STARTTLS_TMOUT, &var_smtp_starttls_tmout, 1, 0,
#endif
VAR_SCACHE_PROTO_TMOUT, DEF_SCACHE_PROTO_TMOUT, &var_scache_proto_tmout, 1, 0,
+ VAR_SMTP_SASL_AUTH_CACHE_TIME, DEF_SMTP_SASL_AUTH_CACHE_TIME, &var_smtp_sasl_auth_cache_time, 0, 0,
0,
};
static const CONFIG_INT_TABLE smtp_int_table[] = {
#endif
VAR_SMTP_SENDER_AUTH, DEF_SMTP_SENDER_AUTH, &var_smtp_sender_auth,
VAR_SMTP_CNAME_OVERR, DEF_SMTP_CNAME_OVERR, &var_smtp_cname_overr,
+ VAR_SMTP_SASL_AUTH_SOFT_BOUNCE, DEF_SMTP_SASL_AUTH_SOFT_BOUNCE, &var_smtp_sasl_auth_soft_bounce,
0,
};
--- /dev/null
+/*++
+/* NAME
+/* smtp_sasl_auth_cache 3
+/* SUMMARY
+/* Postfix SASL authentication reply cache
+/* SYNOPSIS
+/* #include "smtp.h"
+/* #include "smtp_sasl_auth_cache.h"
+/*
+/* SMTP_SASL_AUTH_CACHE *smtp_sasl_auth_cache_init(map, ttl)
+/* const char *map
+/* int ttl;
+/*
+/* void smtp_sasl_auth_cache_store(auth_cache, session, resp)
+/* SMTP_SASL_AUTH_CACHE *auth_cache;
+/* const SMTP_SESSION *session;
+/* const SMTP_RESP *resp;
+/*
+/* int smtp_sasl_auth_cache_find(auth_cache, session)
+/* SMTP_SASL_AUTH_CACHE *auth_cache;
+/* const SMTP_SESSION *session;
+/*
+/* char *smtp_sasl_auth_cache_dsn(auth_cache)
+/* SMTP_SASL_AUTH_CACHE *auth_cache;
+/*
+/* char *smtp_sasl_auth_cache_text(auth_cache)
+/* SMTP_SASL_AUTH_CACHE *auth_cache;
+/* DESCRIPTION
+/* This module maintains a cache of SASL authentication server replies.
+/* This can be used to avoid repeated login failure errors.
+/*
+/* smtp_sasl_auth_cache_init() opens or creates the named cache.
+/*
+/* smtp_sasl_auth_cache_store() stores information about a
+/* SASL login attempt together with the server status and
+/* complete response.
+/*
+/* smtp_sasl_auth_cache_find() returns non-zero when a cache
+/* entry exists for the given host, username and password.
+/*
+/* smtp_sasl_auth_cache_dsn() and smtp_sasl_auth_cache_text()
+/* return the status and complete server response as found
+/* with smtp_sasl_auth_cache_find().
+/*
+/* Arguments:
+/* .IP map
+/* Lookup table name. The name must be singular and must start
+/* with "proxy:".
+/* .IP ttl
+/* The time after which a cache entry is considered expired.
+/* .IP session
+/* Session context.
+/* .IP resp
+/* Remote SMTP server response, to be stored into the cache.
+/* DIAGNOSTICS
+/* All errors are fatal.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Original author:
+/* Keean Schupke
+/* Fry-IT Ltd.
+/*
+/* Updated by:
+/* 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 <msg.h>
+#include <mymalloc.h>
+#include <stringops.h>
+#include <base64_code.h>
+#include <dict.h>
+
+ /*
+ * Global library
+ */
+#include <dsn_util.h>
+#include <dict_proxy.h>
+
+ /*
+ * Application-specific
+ */
+#include "smtp.h"
+#include "smtp_sasl_auth_cache.h"
+
+ /*
+ * XXX This feature stores passwords, so we must mask them with a strong
+ * cryptographic hash. This requires OpenSSL support.
+ *
+ * XXX It would be even better if the stored hash were salted.
+ */
+#ifdef HAVE_SASL_AUTH_CACHE
+
+/* smtp_sasl_auth_cache_init - per-process initialization (pre jail) */
+
+SMTP_SASL_AUTH_CACHE *smtp_sasl_auth_cache_init(const char *map, int ttl)
+{
+ const char *myname = "smtp_sasl_auth_cache_init";
+ SMTP_SASL_AUTH_CACHE *auth_cache;
+
+ /*
+ * Sanity checks.
+ */
+#define HAS_MULTIPLE_VALUES(s) ((s)[strcspn((s), ", \t\r\n")] != 0)
+
+ if (*map == 0)
+ msg_panic("%s: empty SASL authentication cache name", myname);
+ if (ttl < 0)
+ msg_panic("%s: bad SASL authentication cache ttl: %d", myname, ttl);
+ if (HAS_MULTIPLE_VALUES(map))
+ msg_fatal("SASL authentication cache name \"%s\" "
+ "contains multiple values", map);
+
+ /*
+ * XXX To avoid multiple writers the map needs to be maintained by the
+ * proxywrite service. We would like to have a DICT_FLAG_REQ_PROXY flag
+ * so that the library can enforce this, but that requires moving the
+ * dict_proxy module one level down in the build dependency hierachy.
+ */
+#define CACHE_DICT_OPEN_FLAGS \
+ (DICT_FLAG_DUP_REPLACE | DICT_FLAG_SYNC_UPDATE)
+
+ if (strncmp(map, DICT_TYPE_PROXY, sizeof(DICT_TYPE_PROXY)) - 1 != 0
+ && map[sizeof(DICT_TYPE_PROXY) - 1] != ':')
+ msg_fatal("SASL authentication cache name \"%s\" must start with \""
+ DICT_TYPE_PROXY "\":", map);
+
+ auth_cache = (SMTP_SASL_AUTH_CACHE *) mymalloc(sizeof(*auth_cache));
+ auth_cache->dict = dict_open(map, O_CREAT | O_RDWR, CACHE_DICT_OPEN_FLAGS);
+ auth_cache->ttl = ttl;
+ auth_cache->dsn = mymalloc(100);
+ auth_cache->text = mymalloc(100);
+ return (auth_cache);
+}
+
+ /*
+ * Each cache lookup key contains a server host name and user name. Each
+ * cache value contains a time stamp, a hashed password, and the server
+ * response. With this organization, we don't have to worry about cache
+ * pollution, because we can detect if a cache entry has expired, or if the
+ * password has changed.
+ */
+
+/* smtp_sasl_make_auth_cache_key - format auth failure cache lookup key */
+
+static char *smtp_sasl_make_auth_cache_key(const char *host, const char *user)
+{
+ VSTRING *buf = vstring_alloc(100);
+
+ vstring_sprintf(buf, "%s;%s", host, user);
+ return (vstring_export(buf));
+}
+
+/* smtp_sasl_make_auth_cache_pass - hash the auth failure cache password */
+
+static char *smtp_sasl_make_auth_cache_pass(const char *password)
+{
+ VSTRING *buf = vstring_alloc(2 * SHA_DIGEST_LENGTH);
+
+ base64_encode(buf, (const char *) SHA1((const unsigned char *) password,
+ strlen(password), 0),
+ SHA_DIGEST_LENGTH);
+ return (vstring_export(buf));
+}
+
+/* smtp_sasl_make_auth_cache_value - format auth failure cache value */
+
+static char *smtp_sasl_make_auth_cache_value(const char *password,
+ const char *dsn,
+ const char *rep_str)
+{
+ VSTRING *val_buf = vstring_alloc(100);
+ char *pwd_hash;
+ unsigned long now = (unsigned long) time((time_t *) 0);
+
+ pwd_hash = smtp_sasl_make_auth_cache_pass(password);
+ vstring_sprintf(val_buf, "%lu;%s;%s;%s", now, pwd_hash, dsn, rep_str);
+ myfree(pwd_hash);
+ return (vstring_export(val_buf));
+}
+
+/* smtp_sasl_auth_cache_valid - validate auth failure cache value */
+
+static int smtp_sasl_auth_cache_valid(SMTP_SASL_AUTH_CACHE *auth_cache,
+ const char *entry,
+ const char *password)
+{
+ ssize_t len = strlen(entry);
+ char *cache_hash = mymalloc(len);
+ char *curr_hash;
+ unsigned long now = (unsigned long) time((time_t *) 0);
+ unsigned long time_stamp;
+ int valid;
+
+ auth_cache->dsn = myrealloc(auth_cache->dsn, len);
+ auth_cache->text = myrealloc(auth_cache->text, len);
+
+ if (sscanf(entry, "%lu;%[^;];%[^;];%[^\n]", &time_stamp, cache_hash,
+ auth_cache->dsn, auth_cache->text) != 4
+ || !dsn_valid(auth_cache->dsn)) {
+ msg_warn("bad smtp_sasl_auth_cache entry: %.100s", entry);
+ valid = 0;
+ } else if (time_stamp + auth_cache->ttl < now) {
+ valid = 0;
+ } else {
+ curr_hash = smtp_sasl_make_auth_cache_pass(password);
+ valid = (strcmp(cache_hash, curr_hash) == 0);
+ myfree(curr_hash);
+ }
+ myfree(cache_hash);
+ return (valid);
+}
+
+/* smtp_sasl_auth_cache_find - search auth failure cache */
+
+int smtp_sasl_auth_cache_find(SMTP_SASL_AUTH_CACHE *auth_cache,
+ const SMTP_SESSION *session)
+{
+ char *key;
+ const char *entry;
+ int valid = 0;
+
+ key = smtp_sasl_make_auth_cache_key(session->host, session->sasl_username);
+ if ((entry = dict_get(auth_cache->dict, key)) != 0)
+ if ((valid = smtp_sasl_auth_cache_valid(auth_cache, entry,
+ session->sasl_passwd)) == 0)
+ /* Remove expired, password changed, or malformed cache entry. */
+ if (dict_del(auth_cache->dict, key) == 0)
+ msg_warn("SASL auth failure map %s: entry not deleted: %s",
+ auth_cache->dict->name, key);
+ myfree(key);
+ return (valid);
+}
+
+/* smtp_sasl_auth_cache_store - update auth failure cache */
+
+void smtp_sasl_auth_cache_store(SMTP_SASL_AUTH_CACHE *auth_cache,
+ const SMTP_SESSION *session,
+ const SMTP_RESP *resp)
+{
+ char *key;
+ char *value;
+
+ key = smtp_sasl_make_auth_cache_key(session->host, session->sasl_username);
+ value = smtp_sasl_make_auth_cache_value(session->sasl_passwd,
+ resp->dsn, resp->str);
+ dict_put(auth_cache->dict, key, value);
+
+ myfree(value);
+ myfree(key);
+}
+
+#endif
--- /dev/null
+#ifndef _SMTP_SASL_AUTH_CACHE_H_INCLUDED_
+#define _SMTP_SASL_AUTH_CACHE_H_INCLUDED_
+
+/*++
+/* NAME
+/* smtp_sasl_auth_cache 3h
+/* SUMMARY
+/* Postfix SASL authentication failure cache
+/* SYNOPSIS
+/* #include "smtp.h"
+/* #include "smtp_sasl_auth_cache.h"
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * Utility library.
+ */
+#include <dict.h>
+
+ /*
+ * This code stores hashed passwords which requires OpenSSL.
+ */
+#ifdef USE_TLS
+#define HAVE_SASL_AUTH_CACHE
+
+ /*
+ * External interface.
+ */
+typedef struct {
+ DICT *dict;
+ int ttl;
+ char *dsn;
+ char *text;
+} SMTP_SASL_AUTH_CACHE;
+
+extern SMTP_SASL_AUTH_CACHE *smtp_sasl_auth_cache_init(const char *, int);
+extern void smtp_sasl_auth_cache_store(SMTP_SASL_AUTH_CACHE *, const SMTP_SESSION *, const SMTP_RESP *);
+extern int smtp_sasl_auth_cache_find(SMTP_SASL_AUTH_CACHE *, const SMTP_SESSION *);
+
+#define smtp_sasl_auth_cache_dsn(cp) ((cp)->dsn)
+#define smtp_sasl_auth_cache_text(cp) ((cp)->text)
+
+#endif
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Initial implementation by:
+/* Till Franke
+/* SuSE Rhein/Main AG
+/* 65760 Eschborn, Germany
+/*
+/* Adopted by:
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
*/
#include "smtp.h"
#include "smtp_sasl.h"
+#include "smtp_sasl_auth_cache.h"
#ifdef USE_SASL_AUTH
*/
static XSASL_CLIENT_IMPL *smtp_sasl_impl;
+ /*
+ * The 535 SASL authentication failure cache.
+ */
+#ifdef HAVE_SASL_AUTH_CACHE
+static SMTP_SASL_AUTH_CACHE *smtp_sasl_auth_cache;
+
+#endif
+
/* smtp_sasl_passwd_lookup - password lookup routine */
int smtp_sasl_passwd_lookup(SMTP_SESSION *session)
if (*var_smtp_sasl_mechs)
smtp_sasl_mechs = string_list_init(MATCH_FLAG_NONE,
var_smtp_sasl_mechs);
+
+ /*
+ * Initialize the 535 SASL authentication failure cache.
+ */
+ if (*var_smtp_sasl_auth_cache_name) {
+#ifdef HAVE_SASL_AUTH_CACHE
+ smtp_sasl_auth_cache =
+ smtp_sasl_auth_cache_init(var_smtp_sasl_auth_cache_name,
+ var_smtp_sasl_auth_cache_time);
+#else
+ msg_warn("not compiled with TLS support -- "
+ "ignoring the " VAR_SMTP_SASL_AUTH_CACHE_NAME " setting");
+#endif
+ }
}
/* smtp_sasl_connect - per-session client initialization */
msg_info("%s: %s: SASL mechanisms %s",
myname, session->namaddrport, session->sasl_mechanism_list);
+ /*
+ * Avoid repeated login failures after a recent 535 error.
+ */
+#ifdef HAVE_SASL_AUTH_CACHE
+ if (smtp_sasl_auth_cache
+ && smtp_sasl_auth_cache_find(smtp_sasl_auth_cache, session)) {
+ char *resp_dsn = smtp_sasl_auth_cache_dsn(smtp_sasl_auth_cache);
+ char *resp_str = smtp_sasl_auth_cache_text(smtp_sasl_auth_cache);
+
+ if (var_smtp_sasl_auth_soft_bounce && resp_dsn[0] == '5')
+ resp_dsn[0] = '4';
+ dsb_update(why, resp_dsn, DSB_DEF_ACTION, DSB_MTYPE_DNS,
+ session->host, var_procname, resp_str,
+ "SASL [CACHED] authentication failed; server %s said: %s",
+ session->host, resp_str);
+ return (0);
+ }
+#endif
+
/*
* Start the client side authentication protocol.
*/
* We completed the authentication protocol.
*/
if (resp->code / 100 != 2) {
+#ifdef HAVE_SASL_AUTH_CACHE
+ /* Update the 535 authentication failure cache. */
+ if (smtp_sasl_auth_cache && resp->code == 535)
+ smtp_sasl_auth_cache_store(smtp_sasl_auth_cache, session, resp);
+#endif
+ if (var_smtp_sasl_auth_soft_bounce && resp->code / 100 == 5)
+ STR(resp->dsn_buf)[0] = '4';
dsb_update(why, resp->dsn, DSB_DEF_ACTION,
DSB_MTYPE_DNS, session->host,
var_procname, resp->str,
* we exclude xclient authorized hosts from event count/rate control.
*/
if (var_smtpd_cntls_limit > 0
- && state->tls_context
- && state->tls_context->session_reused == 0
+ && (state->tls_context == 0 || state->tls_context->session_reused == 0)
&& SMTPD_STAND_ALONE(state) == 0
&& !xclient_allowed
&& anvil_clnt
state->error_mask |= MAIL_ERROR_POLICY;
msg_warn("New TLS session rate limit exceeded: %d from %s for service %s",
rate, state->namaddr, state->service);
- smtpd_chat_reply(state,
- "421 4.7.0 %s Error: too many new TLS sessions from %s",
- var_myhostname, state->namaddr);
+ if (state->tls_context)
+ smtpd_chat_reply(state,
+ "421 4.7.0 %s Error: too many new TLS sessions from %s",
+ var_myhostname, state->namaddr);
/* XXX Use regular return to signal end of session. */
vstream_longjmp(state->client, SMTP_ERR_QUIET);
}
/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
/* The default location of the Postfix main.cf and master.cf
/* configuration files.
+/* .IP "\fBdata_directory (see 'postconf -d' output)\fR"
+/* The directory with Postfix-writable data files (for example:
+/* caches, pseudo-random numbers).
/* .IP "\fBdaemon_timeout (18000s)\fR"
/* How much time a Postfix daemon process may take to handle a
/* request before it is terminated by a built-in watchdog timer.
/* __FreeBSD_version version is major+minor */
-#if __FreeBSD_version >= 200000
-#define HAS_DUPLEX_PIPE
-#endif
-
#if __FreeBSD_version >= 220000
#define HAS_DEV_URANDOM /* introduced in 2.1.5 */
#endif
#define SOCKOPT_SIZE socklen_t
#endif
+#if __FreeBSD_version >= 420000
+#define HAS_DUPLEX_PIPE /* 4.1 breaks with kqueue(2) */
+#endif
+
/* OpenBSD version is year+month */
#if OpenBSD >= 199805 /* XXX */