summaryrefslogtreecommitdiffstats
path: root/proto
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 16:18:56 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 16:18:56 +0000
commitb7c15c31519dc44c1f691e0466badd556ffe9423 (patch)
treef944572f288bab482a615e09af627d9a2b6727d8 /proto
parentInitial commit. (diff)
downloadpostfix-b7c15c31519dc44c1f691e0466badd556ffe9423.tar.xz
postfix-b7c15c31519dc44c1f691e0466badd556ffe9423.zip
Adding upstream version 3.7.10.upstream/3.7.10
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'proto')
-rw-r--r--proto/ADDRESS_CLASS_README.html279
-rw-r--r--proto/ADDRESS_REWRITING_README.html1246
-rw-r--r--proto/ADDRESS_VERIFICATION_README.html658
-rw-r--r--proto/BACKSCATTER_README.html410
-rw-r--r--proto/BASIC_CONFIGURATION_README.html684
-rw-r--r--proto/BDAT_README.html178
-rw-r--r--proto/BUILTIN_FILTER_README.html488
-rw-r--r--proto/CDB_README.html109
-rw-r--r--proto/COMPATIBILITY_README.html594
-rw-r--r--proto/CONNECTION_CACHE_README.html350
-rw-r--r--proto/CONTENT_INSPECTION_README.html92
-rw-r--r--proto/DATABASE_README.html497
-rw-r--r--proto/DB_README.html246
-rw-r--r--proto/DEBUG_README.html597
-rw-r--r--proto/DSN_README.html156
-rw-r--r--proto/ETRN_README.html374
-rw-r--r--proto/FILTER_README.html980
-rw-r--r--proto/FORWARD_SECRECY_README.html727
-rw-r--r--proto/INSTALL.html1676
-rw-r--r--proto/IPV6_README.html360
-rw-r--r--proto/LDAP_README.html632
-rw-r--r--proto/LINUX_README.html119
-rw-r--r--proto/LMDB_README.html421
-rw-r--r--proto/LOCAL_RECIPIENT_README.html180
-rw-r--r--proto/MAILDROP_README.html195
-rw-r--r--proto/MAILLOG_README.html183
-rw-r--r--proto/MEMCACHE_README.html76
-rw-r--r--proto/MILTER_README.html952
-rw-r--r--proto/MULTI_INSTANCE_README.html1274
-rw-r--r--proto/MYSQL_README.html186
-rw-r--r--proto/Makefile.in535
-rw-r--r--proto/NFS_README.html137
-rw-r--r--proto/OVERVIEW.html936
-rw-r--r--proto/PACKAGE_README.html154
-rw-r--r--proto/PCRE_README.html123
-rw-r--r--proto/PGSQL_README.html174
-rw-r--r--proto/POSTSCREEN_3_5_README.html1198
-rw-r--r--proto/POSTSCREEN_README.html1214
-rw-r--r--proto/QSHAPE_README.html938
-rw-r--r--proto/README34
-rw-r--r--proto/RESTRICTION_CLASS_README.html239
-rw-r--r--proto/SASL_README.html2261
-rw-r--r--proto/SCHEDULER_README.html1839
-rw-r--r--proto/SMTPD_ACCESS_README.html439
-rw-r--r--proto/SMTPD_POLICY_README.html811
-rw-r--r--proto/SMTPD_PROXY_README.html412
-rw-r--r--proto/SMTPUTF8_README.html399
-rw-r--r--proto/SQLITE_README.html114
-rw-r--r--proto/STANDARD_CONFIGURATION_README.html851
-rw-r--r--proto/STRESS_README.html566
-rw-r--r--proto/TLS_LEGACY_README.html1606
-rw-r--r--proto/TLS_README.html3252
-rw-r--r--proto/TUNING_README.html704
-rw-r--r--proto/UUCP_README.html200
-rw-r--r--proto/VERP_README.html289
-rw-r--r--proto/VIRTUAL_README.html648
-rw-r--r--proto/XCLIENT_README.html267
-rw-r--r--proto/XFORWARD_README.html241
-rw-r--r--proto/access468
-rw-r--r--proto/aliases205
-rw-r--r--proto/aliases038
-rw-r--r--proto/bounce214
-rw-r--r--proto/canonical273
-rw-r--r--proto/cidr_table176
-rw-r--r--proto/generic239
-rw-r--r--proto/header_checks520
-rw-r--r--proto/html2text.rc13
-rw-r--r--proto/ldap_table723
-rw-r--r--proto/lmdb_table119
-rw-r--r--proto/manual-format21
-rw-r--r--proto/master257
-rw-r--r--proto/memcache_table236
-rw-r--r--proto/mysql_table401
-rw-r--r--proto/nisplus_table89
-rw-r--r--proto/pcre_table248
-rw-r--r--proto/pgsql_table319
-rw-r--r--proto/postconf.html.epilog5
-rw-r--r--proto/postconf.html.prolog105
-rw-r--r--proto/postconf.man.epilog23
-rw-r--r--proto/postconf.man.prolog85
-rw-r--r--proto/postconf.proto18715
-rw-r--r--proto/postfix-wrapper290
-rw-r--r--proto/regexp_table209
-rw-r--r--proto/relocated166
-rw-r--r--proto/socketmap_table96
-rw-r--r--proto/sqlite_table261
-rw-r--r--proto/stop1564
-rw-r--r--proto/stop.double-cc330
-rw-r--r--proto/stop.double-install-proto-text41
-rw-r--r--proto/stop.double-proto-html247
-rw-r--r--proto/stop.spell-cc1784
-rw-r--r--proto/stop.spell-proto-html350
-rw-r--r--proto/tcp_table108
-rw-r--r--proto/transport306
-rw-r--r--proto/virtual302
95 files changed, 65046 insertions, 0 deletions
diff --git a/proto/ADDRESS_CLASS_README.html b/proto/ADDRESS_CLASS_README.html
new file mode 100644
index 0000000..ca4bb67
--- /dev/null
+++ b/proto/ADDRESS_CLASS_README.html
@@ -0,0 +1,279 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Address Classes </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Address Classes </h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> Postfix version 2.0 introduces the concept of address classes.
+This is a way of grouping recipient addresses by their delivery
+method. The idea comes from discussions with Victor Duchovni.
+Although address classes introduced a few incompatibilities they
+also made it possible to improve the handling of hosted domains
+and of unknown recipients. </p>
+
+<p> This document provides information on the following topics: </p>
+
+<ul>
+
+<li><a href="#wtf">What are address classes good for?</a>
+
+<li><a href="#classes">What address classes does Postfix implement?</a>
+
+<li><a href="#improvements">Improvements compared to Postfix 1.1</a>
+
+<li><a href="#incompatibility">Incompatibilities with Postfix 1.1</a>
+
+</ul>
+
+<h2><a name="wtf">What are address classes good for?</a></h2>
+
+<p> Why should you care about address classes? This is how Postfix
+decides what mail to accept, and how to deliver it. In other words,
+address classes are very important for the operation of Postfix. </p>
+
+<p> An address class is defined by three items. </p>
+
+<ul>
+
+<li> <p> The list of domains that are a member of the class: for
+example, all local domains, or all relay domains. </p>
+
+<li> <p> The default delivery transport. For example, the local,
+virtual or relay delivery transport (delivery transports are defined
+in master.cf). This helps to keep Postfix configurations simple,
+by avoiding the need for explicit routing information in transport
+maps. </p>
+
+<li> <p> The list of valid recipient addresses for that address
+class. The Postfix SMTP server rejects invalid recipients with
+"User unknown in &lt;name of address class here&gt; table". This
+helps to keep the Postfix queue free of undeliverable MAILER-DAEMON
+messages. </p>
+
+</ul>
+
+<h2><a name="classes">What address classes does Postfix implement?</a></h2>
+
+<p> Initially the list of address classes is hard coded, but this
+is meant to become extensible. The summary below describes the main
+purpose of each class, and what the relevant configuration parameters
+are. </p>
+
+<p> The <a name="local_domain_class">local </a> domain class. </p>
+
+<ul>
+
+<li> <p> Purpose: final delivery for traditional UNIX system accounts
+and traditional Sendmail-style aliases. This is typically used for
+the canonical domains of the machine. For a discussion of the
+difference between canonical domains, hosted domains and other
+domains, see the VIRTUAL_README file. </p>
+
+<li> <p> Domain names are listed with the mydestination parameter.
+This domain class also includes mail for <i>user@[ipaddress]</i>
+when the IP address is listed with the inet_interfaces or
+proxy_interfaces parameters. </p>
+
+<li> <p> Valid recipient addresses are listed with the local_recipient_maps
+parameter, as described in LOCAL_RECIPIENT_README. The Postfix SMTP
+server rejects invalid recipients with "User unknown in local
+recipient table". If the local_recipient_maps parameter value is
+empty, then the Postfix SMTP server accepts any address in the
+local domain class. </p>
+
+<li> <p> The mail delivery transport is specified with the
+local_transport parameter. The default value is <b>local:$myhostname</b>
+for delivery with the local(8) delivery agent. </p>
+
+</ul>
+
+<p> The <a name="virtual_alias_class">virtual alias </a> domain
+class. </p>
+
+<ul>
+
+<li> <p> Purpose: hosted domains where each recipient address is
+aliased to a local UNIX system account or to a remote address. A
+virtual alias example is given in the VIRTUAL_README file. </p>
+
+<li> <p> Domain names are listed in virtual_alias_domains. The
+default value is $virtual_alias_maps for Postfix 1.1 compatibility.
+</p>
+
+<li> <p> Valid recipient addresses are listed with the virtual_alias_maps
+parameter. The Postfix SMTP server rejects invalid recipients with
+"User unknown in virtual alias table". The default value is
+$virtual_maps for Postfix 1.1 compatibility. </p>
+
+<li> <p> There is no mail delivery transport parameter. Every
+address must be aliased to some other address. </p>
+
+</ul>
+
+<p> The <a name="virtual_mailbox_class">virtual mailbox </a> domain
+class. </p>
+
+<ul>
+
+<li> <p> Purpose: final delivery for hosted domains where each
+recipient address can have its own mailbox, and where users do not
+need to have a UNIX system account. A virtual mailbox example is
+given in the VIRTUAL_README file. </p>
+
+<li> <p> Domain names are listed with the virtual_mailbox_domains
+parameter. The default value is $virtual_mailbox_maps for Postfix
+1.1 compatibility. </p>
+
+<li> <p> Valid recipient addresses are listed with the virtual_mailbox_maps
+parameter. The Postfix SMTP server rejects invalid recipients with
+"User unknown in virtual mailbox table". If this parameter value
+is empty, the Postfix SMTP server accepts all recipients for domains
+listed in $virtual_mailbox_domains. </p>
+
+<li> <p> The mail delivery transport is specified with the
+virtual_transport parameter. The default value is <b>virtual</b>
+for delivery with the virtual(8) delivery agent. </p>
+
+</ul>
+
+<p> The <a name="relay_domain_class">relay </a> domain class. </p>
+
+<ul>
+
+<li> <p> Purpose: mail forwarding to remote destinations that list
+your system as primary or backup MX host. For a discussion of the
+basic configuration details, see the BASIC_CONFIGURATION_README
+document. For a discussion of the difference between canonical
+domains, hosted domains and other domains, see the VIRTUAL_README
+file. </p>
+
+<li> <p> Domain names are listed with the relay_domains parameter.
+</p>
+
+<li> <p> Valid recipient addresses are listed with the relay_recipient_maps
+parameter. The Postfix SMTP server rejects invalid recipients with
+"User unknown in relay recipient table". If this parameter value
+is empty, the Postfix SMTP server accepts all recipients for domains
+listed with the relay_domains parameter. </p>
+
+<li> <p> The mail delivery transport is specified with the
+relay_transport parameter. The default value is <b>relay</b> which
+is a clone of the smtp(8) delivery agent. </p>
+
+</ul>
+
+<p> The <a name="default_domain_class">default </a> domain class.
+</p>
+
+<ul>
+
+<li> <p> Purpose: mail forwarding to the Internet on behalf of
+authorized clients. For a discussion of the basic configuration
+details, see the BASIC_CONFIGURATION_README file. For a discussion
+of the difference between canonical domains, hosted domains and
+other domains, see the VIRTUAL_README file. </p>
+
+<li> <p> This class has no destination domain table. </p>
+
+<li> <p> This class has no valid recipient address table. </p>
+
+<li> <p> The mail delivery transport is specified with the
+default_transport parameter. The default value is <b>smtp</b> for
+delivery with the smtp(8) delivery agent. </p>
+
+</ul>
+
+<h2><a name="improvements">Improvements compared to Postfix
+1.1</a></h2>
+
+<p> Postfix 2.0 address classes made the following improvements
+possible over earlier Postfix versions: </p>
+
+<ul>
+
+<li> <p> You no longer need to specify all the virtual(8) mailbox
+domains in the Postfix transport map. The virtual(8) delivery agent
+has become a first-class citizen just like local(8) or smtp(8).
+</p>
+
+<li> <p> On mail gateway systems, address classes provide separation
+of inbound mail relay traffic ($relay_transport) from outbound
+traffic ($default_transport). This eliminates a problem where
+inbound mail deliveries could become resource starved in the presence
+of a high volume of outbound mail. </p>
+
+<li> <p> The SMTP server rejects unknown recipients in a more
+consistent manner than was possible with Postfix version 1. This
+is needed to keep undeliverable mail (and bounced undeliverable
+mail) out of the mail queue. This is controlled by the
+smtpd_reject_unlisted_recipient configuration parameter. </p>
+
+<li> <p> As of Postfix version 2.1, the SMTP server also rejects
+unknown sender addresses (i.e. addresses that it would reject as
+unknown recipient addresses). Sender "egress filtering" can help
+to slow down an email worm explosion. This is controlled by the
+smtpd_reject_unlisted_sender configuration parameter. </p>
+
+</ul>
+
+<h2><a name="incompatibility">Incompatibilities with Postfix 1.1</a></h2>
+
+<p> Postfix 2.0 address classes introduce a few incompatible changes
+in documented behavior. In order to ease the transitions, new
+parameters have default values that are backwards compatible. </p>
+
+<ul>
+
+<li> <p> The virtual_maps parameter is replaced by virtual_alias_maps
+(for address lookups) and by virtual_alias_domains (for the names
+of what were formerly called "Postfix-style virtual domains"). </p>
+
+<p> For backwards compatibility with Postfix version 1.1, the new
+virtual_alias_maps parameter defaults to $virtual_maps, and the
+new virtual_alias_domains parameter defaults to $virtual_alias_maps.
+</p>
+
+<li> <p> The virtual_mailbox_maps parameter now has a companion
+parameter called virtual_mailbox_domains (for the names of domains
+served by the virtual delivery agent). The virtual_mailbox_maps
+parameter is now used for address lookups only. </p>
+
+<p> For backwards compatibility with Postfix version 1.1, the new
+virtual_mailbox_domains parameter defaults to $virtual_mailbox_maps.
+</p>
+
+<li> <p> Introduction of the relay_recipient_maps parameter. The
+Postfix SMTP server can use this to block mail for relay recipients
+that don't exist. This list is empty by default, which means accept
+any recipient. </p>
+
+<li> <p> The local_recipient_maps feature is now turned on by
+default. The Postfix SMTP server uses this to reject mail for
+unknown local recipients. See the LOCAL_RECIPIENT_README file hints
+and tips. </p>
+
+<li> <p> Introduction of the relay delivery transport in master.cf.
+This helps to avoid mail delivery scheduling problems on inbound
+mail relays when there is a lot of outbound mail, but may require
+that you update your "defer_transports" setting. </p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/ADDRESS_REWRITING_README.html b/proto/ADDRESS_REWRITING_README.html
new file mode 100644
index 0000000..8c60b76
--- /dev/null
+++ b/proto/ADDRESS_REWRITING_README.html
@@ -0,0 +1,1246 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Address Rewriting </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Address Rewriting </h1>
+
+<hr>
+
+<h2> <a name="purpose"> Postfix address rewriting purpose </a> </h2>
+
+<p> Address rewriting is at the heart of the Postfix mail system.
+Postfix rewrites addresses for many different purposes. Some are
+merely cosmetic, and some are necessary to deliver correctly
+formatted mail to the correct destination. Examples of
+address rewriting in Postfix are: </p>
+
+<ul>
+
+<li> <p> Transform an incomplete address into a complete address.
+For example, transform "username" into "username@example.com", or
+transform "username@hostname" into "username@hostname.example.com".
+</p>
+
+<li> <p> Replace an address by an equivalent address. For example,
+replace "username@example.com" by "firstname.lastname@example.com"
+when sending mail, and do the reverse transformation when receiving
+mail. </p>
+
+<li> <p> Replace an internal address by an external address. For
+example, replace "username@localdomain.local" by "isp-account@isp.example"
+when sending mail from a home computer to the Internet.
+</p>
+
+<li> <p> Replace an address by multiple addresses. For example,
+replace the address of an alias by the addresses listed under that
+alias. </p>
+
+<li> <p> Determine how and where to deliver mail for a specific
+address. For example, deliver mail for "username@example.com" with
+the smtp(8) delivery agent, to the hosts that are listed in the
+DNS as the mail servers for the domain "example.com". </p>
+
+</ul>
+
+<p> Although Postfix currently has no address rewriting language,
+it can do surprisingly powerful address manipulation via table
+lookup. Postfix typically uses lookup tables with fixed strings
+to map one address to one or multiple addresses, and typically uses
+regular expressions to map multiple addresses to one or multiple
+addresses. Fixed-string lookup tables may be in the form of local
+files, or in the form of NIS, LDAP or SQL databases. The
+DATABASE_README document gives an introduction to Postfix lookup
+tables. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li> <a href="#william"> To rewrite message headers or not, or to label
+as invalid </a>
+
+<li> <a href="#overview"> Postfix address rewriting overview </a>
+
+<li> <a href="#receiving"> Address rewriting when mail is received</a>
+
+<ul>
+
+<li> <a href="#standard"> Rewrite addresses to standard form</a>
+
+<li> <a href="#canonical"> Canonical address mapping </a>
+
+<li> <a href="#masquerade"> Address masquerading </a>
+
+<li> <a href="#auto_bcc"> Automatic BCC recipients</a>
+
+<li> <a href="#virtual"> Virtual aliasing </a>
+
+</ul>
+
+<li> <a href="#delivering"> Address rewriting when mail is delivered</a>
+
+<ul>
+
+<li> <a href="#resolve"> Resolve address to destination </a>
+
+<li> <a href="#transport"> Mail transport switch </a>
+
+<li> <a href="#relocated"> Relocated users table </a>
+
+</ul>
+
+<li> <a href="#remote"> Address rewriting with remote delivery </a>
+
+<ul>
+
+<li> <a href="#generic"> Generic mapping for outgoing SMTP mail </a>
+
+</ul>
+
+<li> <a href="#local"> Address rewriting with local delivery </a>
+
+<ul>
+
+<li> <a href="#aliases"> Local alias database </a>
+
+<li> <a href="#forward"> Local per-user .forward files </a>
+
+<li> <a href="#luser_relay"> Local catch-all address </a>
+
+</ul>
+
+<li> <a href="#debugging"> Debugging your address manipulations </a>
+
+</ul>
+
+<h2> <a name="william"> To rewrite message headers or not, or to label
+as invalid </a> </h2>
+
+<p> Postfix versions 2.1 and earlier always rewrite message header
+addresses, and append Postfix's own domain information to addresses
+that Postfix considers incomplete. While rewriting message header
+addresses is OK for mail with a local origin, it is undesirable
+for remote mail: </p>
+
+<ul>
+
+<li> Message header address rewriting is frowned upon by mail standards,
+
+<li> Appending Postfix's own domain produces incorrect results with
+some incomplete addresses,
+
+<li> Appending Postfix's own domain sometimes creates the appearance
+that spam is sent by local users.
+
+</ul>
+
+<p> Postfix versions 2.2 give you the option to either not rewrite
+message headers from remote SMTP clients at all, or to label
+incomplete addresses in such message headers as invalid. Here is
+how it works: </p>
+
+<ul>
+
+<li> Postfix always rewrites message headers from local SMTP clients
+and from the Postfix sendmail command, and appends its own domain
+to incomplete addresses. The local_header_rewrite_clients parameter
+controls what SMTP clients Postfix considers local (by default,
+only local network interface addresses).
+
+<li> Postfix never rewrites message header addresses from remote
+SMTP clients when the remote_header_rewrite_domain parameter value
+is empty (the default setting).
+
+<li> Otherwise, Postfix rewrites message headers from remote SMTP
+clients, and appends the remote_header_rewrite_domain value to
+incomplete addresses. This feature can be used to append a reserved
+domain such as "domain.invalid", so that incomplete addresses cannot
+be mistaken for local addresses.
+
+</ul>
+
+<h2> <a name="overview"> Postfix address rewriting overview </a> </h2>
+
+<p> The figure below zooms in on those parts of Postfix that are most
+involved with address rewriting activity. See the OVERVIEW document
+for an overview of the complete Postfix architecture. Names followed
+by a number are Postfix daemon programs, while unnumbered names
+represent Postfix queues or internal sources of mail messages. </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8)<br>(std
+form) </td>
+
+<td colspan="5"> </td>
+
+<td bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8)<br>(resolve)
+</td>
+
+</tr>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td align="center"><table><tr><td align="center"> ^<br> <tt> |
+</tt> </td><td align="center"> <tt> |<br>v </tt> </td></tr></table>
+
+<td colspan="5"> </td>
+
+<td align="center"><table><tr><td align="center"> ^<br> <tt> |
+</tt> </td><td align="center"> <tt> |<br>v </tt> </td></tr></table>
+
+<td colspan="2"> </td>
+
+</tr>
+
+<tr>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> smtpd(8)
+</td>
+
+<td rowspan="3" align="center" valign="middle"> <tt> &gt;- </tt>
+</td>
+
+<td rowspan="3" bgcolor="#f0f0ff" align="center"> cleanup(8) </td>
+
+<td rowspan="3" align="center" valign="middle"> <tt> -&gt; </tt>
+</td>
+
+<td rowspan="3" bgcolor="#f0f0ff" align="center"> <a
+href="QSHAPE_README.html#incoming_queue"> incoming </a> </td>
+
+<td rowspan="3" align="center" valign="middle"> <tt> -&gt; </tt>
+</td>
+
+<td rowspan="3" bgcolor="#f0f0ff" align="center"> <a
+href="QSHAPE_README.html#active_queue"> active </a> </td>
+
+<td rowspan="3" align="center" valign="middle"> <tt> -&gt; </tt>
+</td>
+
+<td rowspan="3" bgcolor="#f0f0ff" align="center"> qmgr(8) </td>
+
+<td rowspan="3" align="center" valign="middle"> <tt> -&lt; </tt>
+</td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle">
+smtp(8) </td>
+
+</tr>
+
+<tr>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle">
+qmqpd(8) </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> lmtp(8) </td>
+
+</tr>
+
+<tr>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> pickup(8)
+</td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> local(8)
+</td>
+
+</tr>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td align="center"> ^<br> <tt> | </tt> </td>
+
+<td colspan="3"> </td>
+
+<td align="center"><table><tr><td align="center"> ^<br> <tt> |
+</tt> </td><td align="center"> <tt> |<br>v </tt> </td></tr></table>
+
+<td colspan="4"> </td>
+
+</tr>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td align="center"> bounces<br> forwarding<br> notices</td>
+
+<td colspan="3"> </td>
+
+<td bgcolor="#f0f0ff" align="center"> <a
+href="QSHAPE_README.html#deferred_queue"> deferred </a>
+
+<td colspan="2"> </td>
+
+</table>
+
+</blockquote>
+
+<p> The table below summarizes all Postfix address manipulations.
+If you're reading this document for the first time, skip forward
+to "<a href="ADDRESS_REWRITING_README.html#receiving">Address
+rewriting when mail is received</a>". Once you've finished reading
+the remainder of this document, the table will help you to quickly
+find what you need. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th nowrap> Address manipulation </th> <th nowrap> Scope </th>
+<th> Daemon </th> <th nowrap> Global turn-on control </th> <th nowrap> Selective
+turn-off control </th> </tr>
+
+<tr> <td> <a href="#standard"> Rewrite addresses to standard form</a>
+</td> <td nowrap> all mail </td> <td> trivial-<br>rewrite(8) </td>
+<td> append_at_myorigin, append_dot_mydomain, swap_bangpath,
+allow_percent_hack </td> <td> local_header_rewrite_clients,
+remote_header_rewrite_domain </td> </tr>
+
+<tr> <td> <a href="#canonical"> Canonical address mapping </a> </td>
+<td nowrap> all mail </td> <td> cleanup(8) </td> <td> canonical_maps
+</td> <td> receive_override_options, local_header_rewrite_clients,
+remote_header_rewrite_domain </td> </tr>
+
+<tr> <td> <a href="#masquerade"> Address masquerading </a> </td> <td
+nowrap> all mail </td> <td> cleanup(8) </td> <td> masquerade_domains
+</td> <td> receive_override_options, local_header_rewrite_clients,
+remote_header_rewrite_domain </td> </tr>
+
+<tr> <td> <a href="#auto_bcc"> Automatic BCC recipients </a> </td>
+<td nowrap> new mail </td> <td> cleanup(8) </td> <td> always_bcc,
+sender_bcc_maps, recipient_bcc_maps </td> <td> receive_override_options
+</td> </tr>
+
+<tr> <td> <a href="#virtual"> Virtual aliasing </a> </td> <td
+nowrap> all mail </td> <td> cleanup(8) </td> <td> virtual_alias_maps
+</td> <td> receive_override_options </td> </tr>
+
+<tr> <td> <a href="#resolve"> Resolve address to destination </a>
+</td> <td nowrap> all mail </td> <td> trivial-<br>rewrite(8) </td>
+<td> none </td> <td> none </td> </tr>
+
+<tr> <td> <a href="#transport"> Mail transport switch</a> </td>
+<td nowrap> all mail </td> <td> trivial-<br>rewrite(8) </td> <td>
+transport_maps </td> <td> none </td> </tr>
+
+<tr> <td> <a href="#relocated"> Relocated users table</a> </td>
+<td nowrap> all mail </td> <td> trivial-<br>rewrite(8) </td> <td>
+relocated_maps </td> <td> none </td> </tr>
+
+<tr> <td> <a href="#generic"> Generic mapping table </a> </td> <td>
+outgoing SMTP mail </td> <td> smtp(8) </td> <td> smtp_generic_maps
+</td> <td> none </td> </tr>
+
+<tr> <td> <a href="#aliases"> Local alias database</a> </td> <td>
+local mail only </td> <td> local(8) </td> <td> alias_maps </td> <td> none
+</td> </tr>
+
+<tr> <td> <a href="#forward"> Local per-user .forward files</a>
+</td> <td> local mail only </td> <td> local(8) </td> <td> forward_path
+</td> <td> none </td> </tr>
+
+<tr> <td> <a href="#luser_relay"> Local catch-all address</a> </td>
+<td> local mail only </td> <td> local(8) </td> <td> luser_relay </td> <td>
+none </td> </tr>
+
+</table>
+
+</blockquote>
+
+<h2> <a name="receiving"> Address rewriting when mail is received</a>
+</h2>
+
+<p> The cleanup(8) server receives mail from outside of Postfix as
+well as mail from internal sources such as forwarded mail,
+undeliverable mail that is bounced to the sender, and postmaster
+notifications about problems with the mail system. </p>
+
+<p> The cleanup(8) server transforms the sender, recipients and
+message content into a standard form before writing it to an incoming
+queue file. The server cleans up sender and recipient addresses in
+message headers and in the envelope, adds missing message headers
+such as From: or Date: that are required by mail standards, and
+removes message headers such as Bcc: that should not be present.
+The cleanup(8) server delegates the more complex address manipulations
+to the trivial-rewrite(8) server as described later in this document.
+</p>
+
+<p> Address manipulations at this stage are: </p>
+
+<ul>
+
+<li> <a href="#standard"> Rewrite addresses to standard form</a>
+
+<li> <a href="#canonical"> Canonical address mapping</a>
+
+<li> <a href="#masquerade"> Address masquerading</a>
+
+<li> <a href="#auto_bcc"> Automatic BCC recipients</a>
+
+<li> <a href="#virtual"> Virtual aliasing </a>
+
+</ul>
+
+<h3> <a name="standard"> Rewrite addresses to standard form</a> </h3>
+
+<p> Before the cleanup(8) daemon runs an address through any address
+mapping lookup table, it first rewrites the address to the standard
+"user@fully.qualified.domain" form, by sending the address to the
+trivial-rewrite(8) daemon. The purpose of rewriting to standard
+form is to reduce the number of entries needed in lookup tables.
+</p>
+
+<p> The Postfix trivial-rewrite(8) daemon implements the following
+hard-coded address manipulations: </p>
+
+<blockquote>
+
+<dl>
+
+<dt>Rewrite "@hosta,@hostb:user@site" to "user@site"</dt>
+
+<dd> <p> In case you wonder what this is, the address form above
+is called a route address, and specifies that mail for "user@site"
+be delivered via "hosta" and "hostb". Usage of this form has been
+deprecated for a long time. Postfix has no ability to handle route
+addresses, other than to strip off the route part. </p>
+
+<p> NOTE: Postfix versions 2.2 and later rewrite message headers
+from remote SMTP clients only if the client matches the
+local_header_rewrite_clients parameter, or if the
+remote_header_rewrite_domain configuration parameter specifies a
+non-empty value. To get the behavior before Postfix 2.2, specify
+"local_header_rewrite_clients = static:all". </p> </dd>
+
+<dt>Rewrite "site!user" to "user@site" </dt>
+
+<dd> <p> This feature is controlled by the boolean swap_bangpath
+parameter (default: yes). The purpose is to rewrite UUCP-style
+addresses to domain style. This is useful only when you receive
+mail via UUCP, but it probably does not hurt otherwise. </p>
+
+<p> NOTE: Postfix versions 2.2 and later rewrite message headers
+from remote SMTP clients only if the client matches the
+local_header_rewrite_clients parameter, or if the
+remote_header_rewrite_domain configuration parameter specifies a
+non-empty value. To get the behavior before Postfix 2.2, specify
+"local_header_rewrite_clients = static:all". </p> </dd>
+
+<dt>Rewrite "user%domain" to "user@domain"</dt>
+
+<dd> <p> This feature is controlled by the boolean allow_percent_hack
+parameter (default: yes). Typically, this is used in order to deal
+with monstrosities such as "user%domain@otherdomain". </p>
+
+<p> NOTE: Postfix versions 2.2 and later rewrite message headers
+from remote SMTP clients only if the client matches the
+local_header_rewrite_clients parameter, or if the
+remote_header_rewrite_domain configuration parameter specifies a
+non-empty value. To get the behavior before Postfix 2.2, specify
+"local_header_rewrite_clients = static:all". </p> </dd>
+
+<dt>
+
+Rewrite "user" to "user@$myorigin" </dt>
+
+<dd> <p> This feature is controlled by the boolean append_at_myorigin
+parameter (default: yes). You should never turn off this feature,
+because a lot of Postfix components expect that all addresses have
+the form "user@domain". </p>
+
+<p> NOTE: Postfix versions 2.2 and later rewrite message headers
+from remote SMTP clients only if the client matches the
+local_header_rewrite_clients parameter; otherwise they append the
+domain name specified with the remote_header_rewrite_domain
+configuration parameter, if one is specified. To get the behavior
+before Postfix 2.2, specify "local_header_rewrite_clients =
+static:all". </p>
+
+<p> If your machine is not the main machine for $myorigin and you
+wish to have some users delivered locally without going via that
+main machine, make an entry in the <a href="#virtual">virtual
+alias</a> table that redirects "user@$myorigin" to
+"user@$myhostname". See also the "delivering some
+users locally" section in the STANDARD_CONFIGURATION_README
+document. </p> </dd>
+
+<dt>
+
+Rewrite "user@host" to "user@host.$mydomain" </dt>
+
+<dd> <p> This feature is controlled by the boolean append_dot_mydomain
+parameter (default: Postfix ≥ 3.0: no, Postfix < 3.0: yes). The purpose
+is to get consistent treatment of different forms of the same hostname. </p>
+
+<p> NOTE: Postfix versions 2.2 and later rewrite message headers
+from remote SMTP clients only if the client matches the
+local_header_rewrite_clients parameter; otherwise they append the
+domain name specified with the remote_header_rewrite_domain
+configuration parameter, if one is specified. To get the behavior
+before Postfix 2.2, specify "local_header_rewrite_clients =
+static:all". </p>
+
+<p> Some will argue that rewriting "host" to "host.domain"
+is bad. That is why it can be turned off. Others like the convenience
+of having Postfix's own domain appended automatically. </p> </dd>
+
+<dt>Rewrite "user@site." to "user@site" (without the trailing dot).</dt>
+
+<dd> <p> A single trailing dot is silently removed. However, an
+address that ends in multiple dots will be rejected as an invalid
+address. </p>
+
+<p> NOTE: Postfix versions 2.2 and later rewrite message headers
+from remote SMTP clients only if the client matches the
+local_header_rewrite_clients parameter, or if the
+remote_header_rewrite_domain configuration parameter specifies a
+non-empty value. To get the behavior before Postfix 2.2, specify
+"local_header_rewrite_clients = static:all". </p> </dd>
+
+</dl>
+
+</blockquote>
+
+<h3> <a name="canonical"> Canonical address mapping </a> </h3>
+
+<p> The cleanup(8) daemon uses the canonical(5) tables to rewrite
+addresses in message envelopes and in message headers. By default
+all header and envelope addresses are rewritten; this is controlled
+with the canonical_classes configuration parameter. </p>
+
+<p> NOTE: Postfix versions 2.2 and later rewrite message headers
+from remote SMTP clients only if the client matches the
+local_header_rewrite_clients parameter, or if the
+remote_header_rewrite_domain configuration parameter specifies a
+non-empty value. To get the behavior before Postfix 2.2, specify
+"local_header_rewrite_clients = static:all". </p>
+
+<p> Address rewriting is
+done for local and remote addresses. The mapping is useful to
+replace login names by "Firstname.Lastname" style addresses, or to
+clean up invalid domains in mail addresses produced by legacy mail
+systems. </p>
+
+<p> Canonical mapping is disabled by default. To enable, edit the
+canonical_maps parameter in the main.cf file and specify one or
+more lookup tables, separated by whitespace or commas. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ canonical_maps = hash:/etc/postfix/canonical
+
+/etc/postfix/canonical:
+ wietse Wietse.Venema
+</pre>
+</blockquote>
+
+<p> For static mappings as shown above, lookup tables such as hash:,
+ldap:, mysql: or pgsql: are sufficient. For dynamic mappings you
+can use regular expression tables. This requires that you become
+intimately familiar with the ideas expressed in regexp_table(5),
+pcre_table(5) and canonical(5). </p>
+
+<p> In addition to the canonical maps which are applied to both sender
+and recipient addresses, you can specify canonical maps that are
+applied only to sender addresses or to recipient addresses. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ sender_canonical_maps = hash:/etc/postfix/sender_canonical
+ recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
+</pre>
+</blockquote>
+
+<p> The sender and recipient canonical maps are applied before the
+common canonical maps. The sender_canonical_classes and
+recipient_canonical_classes parameters control what addresses are
+subject to sender_canonical_maps and recipient_canonical_maps
+mappings, respectively. </p>
+
+<p> Sender-specific rewriting is useful when you want to rewrite
+ugly sender addresses to pretty ones, and still want to be able to
+send mail to the those ugly address without creating a mailer loop.
+</p>
+
+<p> Canonical mapping can be turned off selectively for mail received
+by smtpd(8), qmqpd(8), or pickup(8), by overriding main.cf settings
+in the master.cf file. This feature is available in Postfix version
+2.1 and later. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ 127.0.0.1:10026 inet n - n - - smtpd
+ -o receive_override_options=no_address_mappings
+</pre>
+</blockquote>
+
+<p> Note: do not specify whitespace around the "=" here. </p>
+
+<h3> <a name="masquerade"> Address masquerading </a> </h3>
+
+<p> Address masquerading is a method to hide hosts inside a domain
+behind their mail gateway, and to make it appear as if the mail
+comes from the gateway itself, instead of from individual machines.
+</p>
+
+<p> NOTE: Postfix versions 2.2 and later rewrite message headers
+from remote SMTP clients only if the client matches the
+local_header_rewrite_clients parameter, or if the
+remote_header_rewrite_domain configuration parameter specifies a
+non-empty value. To get the behavior before Postfix 2.2, specify
+"local_header_rewrite_clients = static:all". </p>
+
+<p> Address masquerading is disabled by default, and is implemented
+by the cleanup(8) server. To enable, edit the masquerade_domains
+parameter in the main.cf file and specify one or more domain names
+separated by whitespace or commas. When Postfix tries to masquerade
+a domain, it processes the list from left to right, and processing
+stops at the first match. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ masquerade_domains = foo.example.com example.com
+</pre>
+</blockquote>
+
+<p> strips "any.thing.foo.example.com" to "foo.example.com", but
+strips "any.thing.else.example.com" to "example.com". </p>
+
+<p> A domain name prefixed with "<tt>!</tt>" means do not masquerade
+this domain or its subdomains: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ masquerade_domains = !foo.example.com example.com
+</pre>
+</blockquote>
+
+<p> does not change "any.thing.foo.example.com" and "foo.example.com",
+but strips "any.thing.else.example.com" to "example.com". </p>
+
+<p> The masquerade_exceptions configuration parameter specifies
+what user names should not be subjected to address masquerading.
+Specify one or more user names separated by whitespace or commas.
+</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ masquerade_exceptions = root
+</pre>
+</blockquote>
+
+<p> By default, Postfix makes no exceptions. </p>
+
+<p> Subtle point: by default, address masquerading is applied only to
+message headers and to envelope sender addresses, but not to envelope
+recipients. This allows you to use address masquerading on a mail
+gateway machine, while still being able to forward mail from outside
+to users on individual machines. </p>
+
+<p> In order to subject envelope recipient addresses to masquerading,
+too, specify (Postfix version 1.1 and later):</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ masquerade_classes = envelope_sender, envelope_recipient,
+ header_sender, header_recipient
+</pre>
+</blockquote>
+
+<p> If you rewrite the envelope recipient like this, Postfix will
+no longer be able to send mail to individual machines. </p>
+
+<p> Address masquerading can be turned off selectively for mail
+received by smtpd(8), qmqpd(8), or pickup(8), by overriding main.cf
+settings in the master.cf file. This feature is available in
+Postfix version 2.1 and later. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ 127.0.0.1:10026 inet n - n - - smtpd
+ -o receive_override_options=no_address_mappings
+</pre>
+</blockquote>
+
+<p> Note: do not specify whitespace around the "=" here. </p>
+
+<h3> <a name="auto_bcc"> Automatic BCC recipients</a> </h3>
+
+<p> After applying the canonical and masquerade mappings, the
+cleanup(8) daemon can generate optional BCC (blind carbon-copy)
+recipients. Postfix provides three mechanisms: </p>
+
+<blockquote>
+
+<dl>
+
+<dt> always_bcc = address </dt> <dd> Deliver a copy of all mail to
+the specified address. In Postfix versions before 2.1, this feature
+is implemented by smtpd(8), qmqpd(8), or pickup(8). </dd>
+
+<dt> sender_bcc_maps = type:table </dt> <dd> Search the specified
+"type:table" lookup table with the envelope sender address for an
+automatic BCC address. This feature is available in Postfix 2.1
+and later. </dd>
+
+<dt> recipient_bcc_maps = type:table </dt> <dd> Search the specified
+"type:table" lookup table with the envelope recipient address for
+an automatic BCC address. This feature is available in Postfix 2.1
+and later. </dd>
+
+</dl>
+
+</blockquote>
+
+<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>
+
+<p> Automatic BCC recipients (including always_bcc) can be turned
+off selectively for mail received by smtpd(8), qmqpd(8), or pickup(8),
+by overriding main.cf settings in the master.cf file. This feature
+is available in Postfix version 2.1 and later. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ 127.0.0.1:10026 inet n - n - - smtpd
+ -o receive_override_options=no_address_mappings
+</pre>
+</blockquote>
+
+<p> Note: do not specify whitespace around the "=" here. </p>
+
+<h3> <a name="virtual"> Virtual aliasing </a> </h3>
+
+<p> Before writing the recipients to the queue file, the cleanup(8)
+daemon uses the optional virtual(5) alias tables to redirect mail
+for recipients. The mapping affects only envelope recipient
+addresses; it has no effect on message headers or envelope sender
+addresses. Virtual alias lookups are useful to redirect mail for
+virtual alias domains to real user mailboxes, and to redirect mail
+for domains that no longer exist. Virtual alias lookups can also
+be used to transform " Firstname.Lastname " back into UNIX login
+names, although it seems that local <a href="#aliases">aliases</a>
+may be a more appropriate vehicle. See the VIRTUAL_README document
+for an overview of methods to host virtual domains with Postfix.
+</p>
+
+<p> Virtual aliasing is disabled by default. To enable, edit the
+virtual_alias_maps parameter in the main.cf file and
+specify one or more lookup tables, separated by whitespace or
+commas. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ virtual_alias_maps = hash:/etc/postfix/virtual
+
+/etc/postfix/virtual:
+ Wietse.Venema wietse
+</pre>
+</blockquote>
+
+<p> Addresses found in virtual alias maps are subjected to another
+iteration of virtual aliasing, but are not subjected to canonical
+mapping, in order to avoid loops. </p>
+
+<p> For static mappings as shown above, lookup tables such as hash:,
+ldap:, mysql: or pgsql: are sufficient. For dynamic mappings you
+can use regular expression tables. This requires that you become
+intimately familiar with the ideas expressed in regexp_table(5),
+pcre_table(5) and virtual(5). </p>
+
+<p> Virtual aliasing can be turned off selectively for mail received
+by smtpd(8), qmqpd(8), or pickup(8), by overriding main.cf settings
+in the master.cf file. This feature is available in Postfix version
+2.1 and later. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ 127.0.0.1:10026 inet n - n - - smtpd
+ -o receive_override_options=no_address_mappings
+</pre>
+</blockquote>
+
+<p> Note: do not specify whitespace around the "=" here. </p>
+
+<p> At this point the message is ready to be stored into the
+Postfix incoming queue. </p>
+
+<h2> <a name="delivering"> Address rewriting when mail is delivered</a> </h2>
+
+<p> The Postfix queue manager sorts mail according to its destination
+and gives it to Postfix delivery agents such as local(8), smtp(8),
+or lmtp(8). Just like the cleanup(8) server, the Postfix queue
+manager delegates the more complex address manipulations to the
+trivial-rewrite(8) server. </p>
+
+<p> Address manipulations at this stage are: </p>
+
+<ul>
+
+<li> <a href="#resolve"> Resolve address to destination </a>
+
+<li> <a href="#transport"> Mail transport switch</a>
+
+<li> <a href="#relocated"> Relocated users table</a>
+
+</ul>
+
+<p> Each Postfix delivery agent tries to deliver the mail to its
+destination, while encapsulating the sender, recipients, and message
+content according to the rules of the SMTP, LMTP, etc. protocol.
+When mail cannot be delivered, it is either returned to the sender
+or moved to the deferred queue and tried again later. </p>
+
+<p> <a name="remote">Address</a> manipulations when mail is delivered
+via the smtp(8) delivery agent: </p>
+
+<ul>
+
+<li> <a href="#generic"> Generic mapping for outgoing SMTP mail </a>
+
+</ul>
+
+<p> <a name="local">Address</a> manipulations when mail is delivered
+via the local(8) delivery agent: </p>
+
+<ul>
+
+<li> <a href="#aliases"> Local alias database</a>
+
+<li> <a href="#forward"> Local per-user .forward files</a>
+
+<li> <a href="#luser_relay"> Local catch-all address</a>
+
+</ul>
+
+<p> The remainder of this document presents each address manipulation
+step in more detail, with specific examples or with pointers to
+documentation with examples. </p>
+
+<h3> <a name="resolve"> Resolve address to destination </a> </h3>
+
+<p> The Postfix qmgr(8) queue manager selects new mail from the
+incoming queue or old mail from the deferred queue, and asks the
+trivial-rewrite(8) address rewriting and resolving daemon where it
+should be delivered. </p>
+
+<p> As of version 2.0, Postfix distinguishes four major address
+classes. Each class has its own list of domain names, and each
+class has its own default delivery method, as shown in the table
+below. See the ADDRESS_CLASS_README document for the fine details.
+Postfix versions before 2.0 only distinguish between local delivery
+and everything else. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr><th align="left">Destination domain list </th> <th
+align="left">Default delivery method </th> <th>Availability
+</th> </tr>
+
+<tr><td>$mydestination, $inet_interfaces, $proxy_interfaces </td>
+<td>$local_transport </td> <td>Postfix 1.0</td></tr>
+
+<tr><td>$virtual_mailbox_domains </td> <td>$virtual_transport </td>
+<td>Postfix 2.0</td> </tr>
+
+<tr><td>$relay_domains </td> <td>$relay_transport </td> <td>Postfix
+2.0</td> </tr>
+
+<tr><td>none </td> <td>$default_transport </td> <td>Postfix 1.0</td>
+</tr>
+
+</table>
+
+</blockquote>
+
+<h3> <a name="transport"> Mail transport switch </a> </h3>
+
+<p> Once the trivial-rewrite(8) daemon has determined a default
+delivery method it searches the optional transport(5) table for
+information that overrides the message destination and/or delivery
+method. Typical use of the transport(5) table is to send mail to
+a system
+that is not connected to the Internet, or to use a special SMTP
+client configuration for destinations that have special requirements.
+See, for example, the STANDARD_CONFIGURATION_README and UUCP_README
+documents, and the examples in the transport(5) manual page. </p>
+
+<p> Transport table lookups are disabled by default. To enable,
+edit the transport_maps parameter in the main.cf file and specify
+one or more lookup tables, separated by whitespace or commas. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+</pre>
+</blockquote>
+
+<h3> <a name="relocated"> Relocated users table </a> </h3>
+
+<p> Next, the trivial-rewrite(8) address rewriting and resolving
+daemon runs each recipient through the relocated(5) database. This
+table provides information on how to reach users that no longer
+have an account, or what to do with mail for entire domains that
+no longer exist. When mail is sent to an address that is listed
+in this table, the message is returned to the sender with an
+informative message. </p>
+
+<p> The relocated(5) database is searched after transport(5)
+table lookups, in anticipation of transport(5) tables that
+can replace one recipient address by a different one. </p>
+
+<p> Lookups of relocated users are disabled by default. To enable,
+edit the relocated_maps parameter in the main.cf file and specify
+one or more lookup tables, separated by whitespace or commas. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relocated_maps = hash:/etc/postfix/relocated
+
+/etc/postfix/relocated:
+ username@example.com otheruser@elsewhere.tld
+</pre>
+</blockquote>
+
+<p> As of Postfix version 2, mail for a relocated user will be
+rejected by the SMTP server with the reason "user has moved to
+otheruser@elsewhere.tld". Older Postfix versions will receive the
+mail first, and then return it to the sender as undeliverable, with
+the same reason. </p>
+
+<h3> <a name="generic"> Generic mapping for outgoing SMTP mail </a> </h3>
+
+<p> Some hosts have no valid Internet domain name, and instead use
+a name such as <i>localdomain.local</i>. This can be a problem when
+you want to send mail over the Internet, because many mail servers
+reject mail addresses with invalid domain names. </p>
+
+<p> With the smtp_generic_maps parameter you can specify generic(5)
+lookup tables that replace local mail addresses by valid Internet
+addresses when mail leaves the machine via SMTP. The generic(5)
+mapping replaces envelope and header addresses, and is non-recursive.
+It does not happen when you send mail between addresses on the
+local machine. </p>
+
+<p> This feature is available in Postfix version 2.2 and later.</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_generic_maps = hash:/etc/postfix/generic
+
+/etc/postfix/generic:
+ his@localdomain.local hisaccount@hisisp.example
+ her@localdomain.local heraccount@herisp.example
+ @localdomain.local hisaccount+local@hisisp.example
+</pre>
+</blockquote>
+
+<p> When mail is sent to a remote host via SMTP, this replaces
+<i>his@localdomain.local</i> by his ISP mail address, replaces
+<i>her@localdomain.local</i> by her ISP mail address, and replaces
+other local addresses by his ISP account, with an address extension
+of +<i>local</i> (this example assumes that the ISP supports "+"
+style address extensions). </p>
+
+<h3> <a name="aliases"> Local alias database </a> </h3>
+
+<p> When mail is to be delivered locally, the local(8) delivery
+agent runs each local recipient name through the aliases(5) database.
+The mapping does not affect addresses in message headers. Local
+aliases are typically used to implement distribution lists, or to
+direct mail for standard aliases such as postmaster to real people.
+The table can also be used to map "Firstname.Lastname" addresses
+to login names. </p>
+
+<p> Alias lookups are enabled by default. The default configuration
+depends on the operating system environment, but it is typically
+one of the following: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ alias_maps = hash:/etc/aliases
+ alias_maps = dbm:/etc/aliases, nis:mail.aliases
+</pre>
+</blockquote>
+
+<p> The pathname of the alias database file is controlled with the
+alias_database configuration parameter. The value is system dependent.
+Usually it is one of the following: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ alias_database = hash:/etc/aliases (4.4BSD, LINUX)
+ alias_database = dbm:/etc/aliases (4.3BSD, SYSV&lt;4)
+ alias_database = dbm:/etc/mail/aliases (SYSV4)
+</pre>
+</blockquote>
+
+<p> An aliases(5) file can specify that mail should be delivered
+to a local file, or to a command that receives the message in the
+standard input stream. For security reasons, deliveries to command
+and file destinations are performed with the rights of the alias
+database owner. A default userid, default_privs, is used for
+deliveries to commands or files in "root"-owned aliases. </p>
+
+<h3> <a name="forward"> Local per-user .forward files </a> </h3>
+
+<p> With delivery via the local(8) delivery agent, users can control
+their own mail delivery by specifying destinations in a file called
+.forward in their home directories. The syntax of these files is
+the same as with the local aliases(5) file, except that the left-hand
+side of the alias (lookup key and colon) are not present. </p>
+
+<h3> <a name="luser_relay"> Local catch-all address </a> </h3>
+
+<p> When the local(8) delivery agent finds that a message recipient
+does not exist, the message is normally returned to the sender ("user
+unknown"). Sometimes it is desirable to forward mail for non-existing
+recipients to another machine. For this purpose you can specify
+an alternative destination with the luser_relay configuration
+parameter. </p>
+
+<p> Alternatively, mail for non-existent recipients can be delegated
+to an entirely different message transport, as specified with the
+fallback_transport configuration parameter. For details, see the
+local(8) delivery agent documentation. </p>
+
+<p> Note: if you use the luser_relay feature in order to receive
+mail for non-UNIX accounts, then you must specify: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ local_recipient_maps =
+</pre>
+</blockquote>
+
+<p> (i.e. empty) in the main.cf file, otherwise the Postfix SMTP
+server will reject mail for non-UNIX accounts with "User unknown
+in local recipient table". See the LOCAL_RECIPIENT_README file
+for more information on this.
+</p>
+
+<p> luser_relay can specify one address. It is subjected to "$name"
+expansions. Examples: </p>
+
+<blockquote>
+
+<dl>
+
+<dt>$user@other.host </dt>
+
+<dd> <p> The bare username, without address extension, is prepended
+to "@other.host". For example, mail for "username+foo" is sent to
+"username@other.host". </p> </dd>
+
+<dt>$local@other.host </dt>
+
+<dd> <p> The entire original recipient localpart, including address
+extension, is prepended to "@other.host". For example, mail for
+"username+foo" is sent to "username+foo@other.host". </p> </dd>
+
+<dt>sysadmin+$user </dt>
+
+<dd> <p> The bare username, without address extension, is appended
+to "sysadmin". For example, mail for "username+foo" is sent to
+"sysadmin+username". </p> </dd>
+
+<dt>sysadmin+$local </dt>
+
+<dd> <p> The entire original recipient localpart, including address
+extension, is appended to "sysadmin". For example, mail for
+"username+foo" is sent to "sysadmin+username+foo". </p> </dd>
+
+</dl>
+
+</blockquote>
+
+<h2> <a name="debugging"> Debugging your address manipulations </a> </h2>
+
+<p> Postfix version 2.1 and later can
+produce mail delivery reports for debugging purposes. These reports
+not only show sender/recipient addresses after address rewriting
+and alias expansion or forwarding, they also show information about
+delivery to mailbox, delivery to non-Postfix command, responses
+from remote SMTP servers, and so on. </p>
+
+<p> Postfix can produce two types of mail delivery reports for
+debugging: </p>
+
+<ul>
+
+<li> <p> What-if: report what would happen, but do not actually
+deliver mail. This mode of operation is requested with: </p>
+
+<pre>
+$ <b>/usr/sbin/sendmail -bv address...</b>
+Mail Delivery Status Report will be mailed to &lt;your login name&gt;.
+</pre>
+
+<li> <p> What happened: deliver mail and report successes and/or
+failures, including replies from remote SMTP servers. This mode
+of operation is requested with: </p>
+
+<pre>
+$ <b>/usr/sbin/sendmail -v address...</b>
+Mail Delivery Status Report will be mailed to &lt;your login name&gt;.
+</pre>
+
+</ul>
+
+<p> These reports contain information that is generated by Postfix
+delivery agents. Since these run as daemon processes and do not
+interact with users directly, the result is sent as mail to the
+sender of the test message. The format of these reports is practically
+identical to that of ordinary non-delivery notifications. </p>
+
+<p> As an example, below is the delivery report that is produced
+with the command "sendmail -bv postfix-users@postfix.org". The
+first part of the report contains human-readable text. In this
+case, mail would be delivered via mail.cloud9.net, and the SMTP
+server replies with "250 Ok". Other reports may show delivery
+to mailbox, or delivery to non-Postfix command. </p>
+
+<blockquote>
+<pre>
+Content-Description: Notification
+Content-Type: text/plain
+
+This is the mail system at host spike.porcupine.org.
+
+Enclosed is the mail delivery report that you requested.
+
+ The mail system
+
+&lt;postfix-users@postfix.org&gt;: delivery via mail.cloud9.net[168.100.1.4]: 250 2.1.5 Ok
+</pre>
+</blockquote>
+
+<p> The second part of the report is in machine-readable form, and
+includes the following information: </p>
+
+<ul>
+
+<li> The envelope sender address (wietse@porcupine.org).
+
+<li> The envelope recipient address (postfix-users@postfix.org).
+If the recipient address was changed by Postfix then Postfix also
+includes the original recipient address.
+
+<li> The delivery status.
+
+</ul>
+
+<p> Some details depend on Postfix version. The example below is
+for Postfix version 2.3 and later. </p>
+
+<blockquote>
+<pre>
+Content-Description: Delivery report
+Content-Type: message/delivery-status
+
+Reporting-MTA: dns; spike.porcupine.org
+X-Postfix-Queue-ID: 84863BC0E5
+X-Postfix-Sender: rfc822; wietse@porcupine.org
+Arrival-Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
+
+Final-Recipient: rfc822; postfix-users@postfix.org
+Action: deliverable
+Status: 2.1.5
+Remote-MTA: dns; mail.cloud9.net
+Diagnostic-Code: smtp; 250 2.1.5 Ok
+</pre>
+</blockquote>
+
+<p> The third part of the report contains the message that Postfix
+would have delivered, including From: and To: message headers, so
+that you can see any effects of address rewriting on those. Mail
+submitted with "sendmail -bv" has no body content so none is shown
+in the example below. </p>
+
+<blockquote>
+<pre>
+Content-Description: Message
+Content-Type: message/rfc822
+
+Received: by spike.porcupine.org (Postfix, from userid 1001)
+ id 84863BC0E5; Sun, 26 Nov 2006 17:01:01 -0500 (EST)
+Subject: probe
+To: postfix-users@postfix.org
+Message-Id: &lt;20061126220101.84863BC0E5@spike.porcupine.org&gt;
+Date: Sun, 26 Nov 2006 17:01:01 -0500 (EST)
+From: wietse@porcupine.org (Wietse Venema)
+</pre>
+</blockquote>
+
+</body>
+
+</html>
diff --git a/proto/ADDRESS_VERIFICATION_README.html b/proto/ADDRESS_VERIFICATION_README.html
new file mode 100644
index 0000000..aaaf24d
--- /dev/null
+++ b/proto/ADDRESS_VERIFICATION_README.html
@@ -0,0 +1,658 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Address Verification </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Address Verification Howto</h1>
+
+<hr>
+
+<h2>WARNING </h2>
+
+<p> Recipient address verification may cause an increased load on
+down-stream servers in the case of a dictionary attack or a flood
+of backscatter bounces. Sender address verification may cause your
+site to be denylisted by some providers. See also the "<a
+href="#limitations">Limitations</a>" section below for more. </p>
+
+<h2><a name="summary">What Postfix address verification can do for you</a></h2>
+
+<p> Address verification is a feature that allows the Postfix SMTP
+server to block a sender (MAIL FROM) or recipient (RCPT TO) address
+until the address has been verified to be deliverable. </p>
+
+<p> The technique has obvious uses to reject junk mail
+with an unreplyable sender address. </p>
+
+<p> The technique is also useful to block mail for undeliverable
+recipients, for example on a mail relay host that does not have a
+list of all the valid recipient addresses. This prevents undeliverable
+junk mail from entering the queue, so that Postfix doesn't have to
+waste resources trying to send MAILER-DAEMON messages back. </p>
+
+<p> This feature is available in Postfix version 2.1 and later. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#how"> How address verification works</a>
+
+<li><a href="#limitations">Limitations of address verification</a>
+
+<li><a href="#recipient">Recipient address verification</a>
+
+<li><a href="#forged_sender">Sender address verification for mail
+from frequently forged domains</a>
+
+<li><a href="#sender_always">Sender address verification for all
+email</a>
+
+<li><a href="#caching">Address verification database</a>
+
+<li><a href="#dirty_secret">Managing the address verification
+database</a>
+
+<li><a href="#probe_routing">Controlling the routing of address
+verification probes</a>
+
+<li><a href="#forced_examples">Forced probe routing examples</a>
+
+<li><a href="#forced_limitations">Limitations of forced probe routing</a>
+
+</ul>
+
+<h2><a name="how">How address verification works</a></h2>
+
+<p> A Postfix MTA verifies a sender or recipient address by probing
+the preferred MTAs
+for that address, without actually delivering mail. The preferred
+MTAs could include the Postfix MTA itself, or some remote MTAs
+(SMTP
+interruptus). Probe messages are like normal mail, except that
+they are never delivered, deferred or bounced; probe messages are
+always discarded. </p>
+
+<blockquote>
+
+<table border="0">
+
+<tr>
+
+ <td rowspan="2" colspan="5" align="center" valign="middle">
+ &nbsp; </td>
+
+ <td rowspan="3" align="center" valign="bottom"> <tt> -&gt; </tt>
+ </td>
+
+ <td rowspan="3" align="center" valign="middle"> probe<br>
+ message </td>
+
+ <td rowspan="3" align="center" valign="middle"> <tt> -&gt; </tt>
+ </td>
+
+ <td rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle">
+ Postfix<br> mail<br> queue </td>
+
+</tr>
+
+<tr> <td> </td> </tr>
+
+<tr>
+
+ <td rowspan="3" align="center" valign="middle"> Internet </td>
+
+ <td rowspan="3" align="center" valign="middle"> <tt> -&gt; </tt>
+ </td>
+
+ <td rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle">
+ <a href="smtpd.8.html">Postfix<br> SMTP<br> server</a> </td>
+
+ <td rowspan="3" align="center" valign="middle"> <tt> &lt;-&gt;
+ </tt> </td>
+
+ <td rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle">
+ <a href="verify.8.html">Postfix<br> verify<br> server</a>
+ </td>
+
+</tr>
+
+<tr>
+
+ <td rowspan="1" colspan="3"> </td>
+
+ <td rowspan="1" align="center" valign="middle"> <tt> |</tt><br>
+ <tt> v</tt> </td>
+
+</tr>
+
+<tr>
+
+ <td rowspan="3" align="center" valign="top"> <tt> &lt;- </tt>
+ </td>
+
+ <td rowspan="3" align="center" valign="middle"> probe<br>
+ status </td>
+
+ <td rowspan="3" align="center" valign="middle"> <tt> &lt;- </tt>
+ </td>
+
+ <td rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle">
+ Postfix<br> delivery<br> agents </td>
+
+ <td rowspan="3" align="left" valign="middle"> <tt>-&gt;</tt>
+ Local<br> <tt>-&gt;</tt> Remote</td>
+
+</tr>
+
+<tr>
+
+ <td rowspan="3" colspan="4" align="center" valign="middle">
+ &nbsp; </td>
+
+ <td rowspan="3" align="center" valign="middle"> <tt>
+ ^</tt><br> <tt> |</tt><br> <tt> v</tt> </td>
+
+</tr>
+
+<tr> <td> </td> </tr>
+
+<tr> <td colspan="4"> &nbsp; </td> </tr>
+
+<tr>
+
+ <td colspan="4" align="center" valign="middle"> &nbsp; </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Address<br> verification<br> database </td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<p> With Postfix address verification turned on, normal mail will
+suffer only a short delay of up to 6 seconds while an address is
+being verified for the first time. Once an address status is known,
+the status is cached and Postfix replies immediately. </p>
+
+<p> When verification takes too long the Postfix SMTP server defers
+the sender or recipient address with a 450 reply. Normal mail
+clients will connect again after some delay. The address verification
+delay is configurable with the main.cf address_verify_poll_count
+and address_verify_poll_delay parameters. See postconf(5) for
+details. </p>
+
+<h2><a name="limitations">Limitations of address verification</a></h2>
+
+<ul>
+
+<li> <p> Postfix assumes that a remote SMTP server will reject
+unknown addresses in reply to the RCPT TO command. However, some
+sites report this in reply to the DATA command. For such sites
+you may configure a workaround with the smtp_address_verify_target
+parameter (Postfix 3.0 and later). </p>
+
+<li> <p> When verifying a remote address, Postfix probes the preferred
+MTAs for that address, without actually delivering mail. If
+a preferred MTA accepts the address, then Postfix assumes that the
+address is deliverable. In reality, mail for a remote address can
+bounce AFTER a preferred MTA accepts the recipient address, or AFTER
+a preferred MTA accepts the message content. </p>
+
+<li> <p> Some sites may denylist you when you are probing them
+too often (a probe is an SMTP session that does not deliver mail),
+or when you are probing them too often for a non-existent address.
+This is one reason why you should use sender address verification
+sparingly, if at all, when your site receives lots of email. </p>
+
+<li> <p> Normally, address verification probe messages follow the
+same path as regular mail. However, some sites send mail to the
+Internet via an intermediate relayhost; this breaks address
+verification. See below, section <a href="#probe_routing">"Controlling
+the routing of address verification probes"</a>, for how to override
+mail routing and for possible limitations when you have to do this.
+</p>
+
+<li> <p> Postfix assumes that an address is undeliverable when a
+preferred MTA for the address rejects the probe, regardless of the
+reason for rejection (client rejected, HELO rejected, MAIL FROM
+rejected, etc.). Thus, Postfix rejects an address when a preferred
+MTA for that address rejects mail from your machine for any reason.
+This is not a limitation, but it is mentioned here just in case
+people believe that it is a limitation. </p>
+
+<li> <p> Unfortunately, some sites do not reject unknown addresses
+in reply to the RCPT TO or DATA command, but instead report a
+delivery failure in response to end of DATA after a message is
+transferred. Postfix address verification does not work with such
+sites. </p>
+
+<li> <p> By default, Postfix probe messages have a sender address
+"double-bounce@$myorigin" (with Postfix versions before 2.5, the
+default
+is "postmaster@$myorigin"). This is SAFE because the Postfix SMTP
+server does not reject mail for this address. </p>
+
+<p> You can change the probe sender address into the null address
+("address_verify_sender
+="). This is UNSAFE because address probes will fail with
+mis-configured sites that reject MAIL FROM: &lt;&gt;, while
+probes from "double-bounce@$myorigin" would succeed. </p>
+
+<li> <p> The downside of using a non-empty sender address is that
+the address may end up on spammer mailing lists. Although Postfix
+always discards mail to the double-bounce address, this still results
+in wasted network bandwidth and server capacity. To defeat
+address harvesting, Postfix 2.9 and later support time-dependent
+sender addresses when you specify a non-zero address_verify_sender_ttl
+value. </p>
+
+</ul>
+
+<h2><a name="recipient">Recipient address verification</a></h2>
+
+<p> As mentioned earlier, recipient address verification is
+useful to block mail for undeliverable recipients on a mail relay
+host that does not have a list of all valid recipient addresses.
+This can help to prevent the mail queue from filling up with
+MAILER-DAEMON messages. </p>
+
+<p> Recipient address verification is relatively straightforward
+and there are no surprises. If a recipient probe fails, then Postfix
+rejects mail for the recipient address. If a recipient probe
+succeeds, then Postfix accepts mail for the recipient address.
+However, recipient address verification probes can increase the
+load on down-stream MTAs when you're being flooded by backscatter
+bounces, or when some spammer is mounting a dictionary attack. </p>
+
+<p> By default, address verification results are saved in a <a
+href="#caching">persistent database</a> (Postfix version 2.7 and
+later; with earlier versions, specify the database in main.cf as
+described later). The persistent database helps to avoid probing
+the same address repeatedly. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ permit_mynetworks
+ # reject_unauth_destination is not needed here if the mail
+ # relay policy is specified under smtpd_relay_restrictions
+ # (available with Postfix 2.10 and later).
+ reject_unauth_destination
+ ...
+ reject_unknown_recipient_domain
+ reject_unverified_recipient
+ ...
+ # Postfix 2.6 and later privacy feature.
+ # unverified_recipient_reject_reason = Address lookup failed
+
+ # Postfix 3.2 and earlier workaround.
+ # Do not set enable_original_recipient=no. This prevents Postfix
+ # from saving the recipient address verification result under
+ # the original address, when the address verification probe
+ # message goes through address aliasing or canonical mapping.
+</pre>
+</blockquote>
+
+<p> The "reject_unknown_recipient_domain" restriction blocks mail
+for non-existent domains. Putting this before "reject_unverified_recipient"
+avoids the overhead of generating unnecessary probe messages. </p>
+
+<p> The unverified_recipient_reject_code parameter (default 450)
+specifies the numerical Postfix SMTP server reply code when a
+recipient address is known to
+bounce. Change this setting into 550 when you trust Postfix's
+judgments. </p>
+
+<p> The following features are available in Postfix 2.6 and later.
+</p>
+
+<p> The unverified_recipient_defer_code parameter (default 450)
+specifies the numerical Postfix SMTP server reply code when a
+recipient address probe fails with some temporary error. Some sites
+insist on changing this into 250. NOTE: This change turns MX servers
+into backscatter sources when the load is high. </p>
+
+<p> The unverified_recipient_reject_reason parameter (default:
+empty) specifies fixed text that Postfix will send to remote SMTP
+clients, instead of sending actual address verification details.
+Do not specify the SMTP status code or enhanced status code. </p>
+
+<p> The unverified_recipient_tempfail_action parameter (default:
+defer_if_permit) specifies the Postfix SMTP server action when a
+recipient address verification probe fails with some temporary
+error. </p>
+
+<h2><a name="forged_sender">Sender address verification for mail from frequently forged domains</a></h2>
+
+<p> Only for very small sites, it is relatively safe to turn on
+sender address verification for specific domains that often appear
+in forged email. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sender_restrictions = hash:/etc/postfix/sender_access
+ unverified_sender_reject_code = 550
+ # Postfix 2.6 and later.
+ # unverified_sender_defer_code = 250
+
+ # Default setting for Postfix 2.7 and later.
+ # Note 1: Be sure to read the "<a href="#caching">Caching</a>" section below!
+ # Note 2: Avoid hash files here. Use btree or lmdb instead.
+ address_verify_map = btree:/var/lib/postfix/verify
+
+ # Postfix 3.2 and earlier workaround.
+ # Do not set enable_original_recipient=no. This prevents Postfix
+ # from saving the sender address verification result under the
+ # original address, when the address verification probe message
+ # goes through address aliasing or canonical mapping.
+
+/etc/postfix/sender_access:
+ # Don't do this when you handle lots of email.
+ aol.com reject_unverified_sender
+ hotmail.com reject_unverified_sender
+ bigfoot.com reject_unverified_sender
+ ... etcetera ...
+</pre>
+</blockquote>
+
+<p> At some point in cyberspace/time, a list of frequently forged
+MAIL FROM domains could be found at
+http://www.monkeys.com/anti-spam/filtering/sender-domain-validate.in. </p>
+
+<p> NOTE: One of the first things you might want to do is to turn
+on sender address verification for all your own domains. </p>
+
+<h2><a name="sender_always">Sender address verification for all
+email</a></h2>
+
+<p> Unfortunately, sender address verification cannot simply be
+turned on for all email - you are likely to lose legitimate mail
+from mis-configured systems. You almost certainly will have to set
+up allow lists for specific addresses, or even for entire domains.
+</p>
+
+<p> To find out how sender address verification would affect your
+mail, specify "warn_if_reject reject_unverified_sender" so that
+you can see what mail would be blocked: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sender_restrictions =
+ permit_mynetworks
+ ...
+ check_sender_access hash:/etc/postfix/sender_access
+ reject_unknown_sender_domain
+ warn_if_reject reject_unverified_sender
+ ...
+ # Postfix 2.6 and later.
+ # unverified_sender_reject_reason = Address verification failed
+
+ # Default setting for Postfix 2.7 and later.
+ # Note 1: Be sure to read the "<a href="#caching">Caching</a>" section below!
+ # Note 2: Avoid hash files here. Use btree or lmdb instead.
+ address_verify_map = btree:/var/lib/postfix/verify
+</pre>
+</blockquote>
+
+<p> This is also a good way to populate your cache with address
+verification results before you start to actually reject mail. </p>
+
+<p> The sender_access restriction is needed to allowlist domains
+or addresses that are known to be OK. Although Postfix will not
+mark a known-to-be-good address as bad after a probe fails, it is
+better to be safe than sorry. </p>
+
+<p> NOTE: You will have to allowlist sites such as securityfocus.com
+and other sites that operate mailing lists that use a different
+sender address for each posting (VERP). Such addresses pollute
+the address verification cache quickly, and generate unnecessary
+sender verification probes. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/sender_access
+ securityfocus.com OK
+ ...
+</pre>
+</blockquote>
+
+<p> The "reject_unknown_sender_domain" restriction blocks mail from
+non-existent domains. Putting this before "reject_unverified_sender"
+avoids the overhead of generating unnecessary probe messages. </p>
+
+<p> The unverified_sender_reject_code parameter (default 450)
+specifies the numerical Postfix server reply code when a sender
+address is known to
+bounce. Change this setting into 550 when you trust Postfix's
+judgments. </p>
+
+<p> The following features are available in Postfix 2.6 and later.
+</p>
+
+<p> The unverified_sender_defer_code parameter (default 450) specifies
+the numerical Postfix SMTP server reply code when a sender address
+verification probe fails with some temporary error. Specify a valid
+2xx or 4xx code. </p>
+
+<p> The unverified_sender_reject_reason parameter (default:
+empty) specifies fixed text that Postfix will send to remote SMTP
+clients, instead of sending actual address verification details.
+Do not specify the SMTP status code or enhanced status code. </p>
+
+<p> The unverified_sender_tempfail_action parameter (default:
+defer_if_permit) specifies the Postfix SMTP server action when a
+sender address verification probe fails with some temporary error.
+</p>
+
+<h2><a name="caching">Address verification database</a></h2>
+
+<p> To improve performance, the Postfix verify(8) daemon can save
+address verification results to a persistent database. This is
+enabled by default with Postfix 2.7 and later. The
+address_verify_map (NOTE: singular) configuration parameter specifies
+persistent storage for sender or recipient address verification
+results. If you specify an empty value, all address verification
+results are lost after "postfix reload" or "postfix stop". </p>
+
+<blockquote>
+<pre>
+# Example 1: Default setting for Postfix 2.7 and later.
+# Note: avoid hash files here. Use btree or lmdb instead.
+/etc/postfix/main.cf:
+ address_verify_map = btree:$data_directory/verify_cache
+
+# Example 2: Shared persistent lmdb: cache (Postfix 2.11 or later).
+# Disable automatic cache cleanup in all Postfix instances except
+# for one instance that will be responsible for cache cleanup.
+/etc/postfix/main.cf:
+ address_verify_map = lmdb:$data_directory/verify_cache
+ # address_verify_cache_cleanup_interval = 0
+
+# Example 3: Shared persistent btree: cache (Postfix 2.9 or later).
+# Disable automatic cache cleanup in all Postfix instances except
+# for one instance that will be responsible for cache cleanup.
+/etc/postfix/main.cf:
+ address_verify_map = proxy:btree:$data_directory/verify_cache
+ # address_verify_cache_cleanup_interval = 0
+
+# Example 4: Shared memory cache (requires Postfix 2.9 or later).
+# Disable automatic cache cleanup in all Postfix instances.
+# See memcache_table(5) for details.
+/etc/postfix/main.cf:
+ address_verify_map = memcache:/etc/postfix/verify-memcache.cf
+ address_verify_cache_cleanup_interval = 0
+
+# Example 5: Default setting for Postfix 2.6 and earlier.
+# This uses non-persistent storage only.
+/etc/postfix/main.cf:
+ address_verify_map =
+</pre>
+</blockquote>
+
+<p> NOTE 1: The database file should be stored under a Postfix-owned
+directory, such as $data_directory. </p>
+
+<blockquote> As of version 2.5, Postfix no longer uses root privileges
+when opening this file. To maintain backwards compatibility, an
+attempt to open the file under a non-Postfix directory is redirected
+to the Postfix-owned data_directory, and a warning is logged. If
+you wish to continue using a pre-existing database file, change its
+file ownership to the account specified with the mail_owner parameter,
+and either move the file to the data_directory, or move it to some
+other Postfix-owned directory. </blockquote>
+
+<p> NOTE 2: Do not put this file in a file system that may run out
+of space. When the address verification table gets corrupted the
+world comes to an end and YOU will have to MANUALLY fix things as
+described in the next section. Meanwhile, you will not receive mail
+via SMTP. </p>
+
+<p> NOTE 3: The verify(8) daemon will create a new database when
+none exists. It will open or create the file before entering the
+chroot jail. </p>
+
+<h2><a name="dirty_secret">Managing the address verification
+database</a></h2>
+
+<p> The verify(8) manual page describes parameters that control how
+long address verification results are cached before they need to
+be refreshed, and how long results can remain "unrefreshed" before
+they expire. Postfix uses different controls for positive results
+(address was accepted) and for negative results (address was rejected,
+or address verification failed for some other reason). </p>
+
+<p> The verify(8) daemon will periodically remove expired entries
+from the address verification database, and log the number of entries
+retained and dropped (Postfix versions 2.7 and later). A cleanup
+run is logged as "partial" when the daemon terminates early because
+of "postfix reload, "postfix stop", or because the daemon received
+no requests for $max_idle seconds. Postfix versions 2.6 and earlier
+do not implement automatic address verification database cleanup.
+There, the database is managed manually as described next. </p>
+
+<p> When the address verification database file becomes too big,
+or when it becomes corrupted, the solution is to manually rename
+or delete (NOT: truncate) the file and run "postfix reload". The
+verify(8) daemon will then create a new database file. </p>
+
+<h2><a name="probe_routing">Controlling the routing of address
+verification probes</a></h2>
+
+<p> By default, Postfix sends address verification probe messages
+via the same route as regular mail, because that normally produces
+the most accurate result. It's no good to verify a local address
+by connecting to your own SMTP port; that just triggers all kinds
+of mailer loop alarms. The same is true for any destination that
+your machine is best MX host for: hidden domains, virtual domains,
+etc. </p>
+
+<p> However, some sites have a complex infrastructure where mail
+is not sent directly to the Internet, but is instead given to an
+intermediate relayhost. This is a problem for address verification,
+because remote Internet addresses can be verified only when Postfix
+can access remote destinations directly. </p>
+
+<p> For this reason, Postfix allows you to override the routing
+parameters when it delivers an address verification probe message.
+</p>
+
+<p> First, the address_verify_relayhost parameter allows you to
+override the relayhost setting, and the address_verify_transport_maps
+parameter allows you to override the transport_maps setting.
+The address_verify_sender_dependent_relayhost_maps parameter
+does the same for sender-dependent relayhost selection. </p>
+
+<p> Second, each address class is given its own address verification
+version of the message delivery transport, as shown in the table
+below. Address classes are defined in the ADDRESS_CLASS_README
+file. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Domain list </th> <th> Regular transport</th> <th> Verify
+transport </th> </tr>
+
+<tr> <td> mydestination </td> <td> local_transport </td> <td>
+address_verify_local_transport </td> </tr>
+
+<tr> <td> virtual_alias_domains </td> <td> (not applicable) </td>
+<td> (not applicable) </td> </tr>
+
+<tr> <td> virtual_mailbox_domains </td> <td> virtual_transport
+</td> <td> address_verify_virtual_transport </td> </tr>
+
+<tr> <td> relay_domains </td> <td> relay_transport </td> <td>
+address_verify_relay_transport </td> </tr>
+
+<tr> <td> (not applicable) </td> <td> default_transport </td> <td>
+address_verify_default_transport </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> By default, the parameters that control delivery of address
+probes have the same value as the parameters that control normal
+mail delivery. </p>
+
+<h2><a name="forced_examples">Forced probe routing examples</a></h2>
+
+<p> In a typical scenario one would override the relayhost setting
+for address verification probes and leave everything else alone:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relayhost = $mydomain
+ address_verify_relayhost =
+ ...
+</pre>
+</blockquote>
+
+<p> Sites behind a network address translation box might have to
+use a different SMTP client that sends the correct hostname
+information: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relayhost = $mydomain
+ address_verify_relayhost =
+ address_verify_default_transport = direct_smtp
+
+/etc/postfix/master.cf:
+ direct_smtp .. .. .. .. .. .. .. .. .. smtp
+ -o smtp_helo_name=nat.box.tld
+</pre>
+</blockquote>
+
+<h2><a name="forced_limitations">Limitations of forced probe routing</a></h2>
+
+<p> Inconsistencies can happen when probe messages don't follow
+the same path as regular mail. For example, a message can be
+accepted when it follows the regular route while an otherwise
+identical probe message is rejected when it follows the forced
+route. The opposite can happen, too, but is less likely. </p>
+
+</body>
+
+</html>
diff --git a/proto/BACKSCATTER_README.html b/proto/BACKSCATTER_README.html
new file mode 100644
index 0000000..aae9430
--- /dev/null
+++ b/proto/BACKSCATTER_README.html
@@ -0,0 +1,410 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Backscatter Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Backscatter Howto</h1>
+
+<hr>
+
+<h2>Overview </h2>
+
+<p> This document describes features that require Postfix version
+2.0 or later. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#wtf">What is backscatter mail?</a>
+
+<li><a href="#random">How do I block backscatter mail to random
+recipient addresses?</a>
+
+<li><a href="#real">How do I block backscatter mail to real
+recipient addresses?</a>
+
+<ul>
+
+<li><a href="#forged_helo">Blocking backscatter mail with forged
+mail server information</a>
+
+<li><a href="#forged_sender">Blocking backscatter mail with forged
+sender information</a>
+
+<li><a href="#forged_other">Blocking backscatter mail with other
+forged information</a>
+
+<li><a href="#scanner">Blocking backscatter mail from virus
+scanners</a>
+
+</ul>
+
+</ul>
+
+<p> The examples use Perl Compatible Regular Expressions (Postfix
+pcre: tables), but also provide a translation to POSIX regular
+expressions (Postfix regexp: tables). PCRE is preferred primarily
+because the implementation is often faster.</p>
+
+<h2><a name="wtf">What is backscatter mail?</a></h2>
+
+<p> When a spammer or worm sends mail with forged sender addresses,
+innocent sites are flooded with undeliverable mail notifications.
+This is called backscatter mail. With Postfix, you know that you're
+a backscatter victim when your logfile goes on and on like this:
+</p>
+
+<blockquote>
+<pre>
+Dec 4 04:30:09 hostname postfix/smtpd[58549]: NOQUEUE: reject:
+RCPT from xxxxxxx[x.x.x.x]: 550 5.1.1 &lt;yyyyyy@your.domain.here&gt;:
+Recipient address rejected: User unknown; from=&lt;&gt;
+to=&lt;yyyyyy@your.domain.here&gt; proto=ESMTP helo=&lt;zzzzzz&gt;
+</pre>
+</blockquote>
+
+<p> What you see are lots of "user unknown" errors with "from=&lt;&gt;".
+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
+recipient addresses?</a></h2>
+
+<p> If your machine receives backscatter mail to random addresses,
+configure Postfix to reject all mail for non-existent recipients
+as described in the LOCAL_RECIPIENT_README and
+STANDARD_CONFIGURATION_README documentation. </p>
+
+<p> If your machine runs Postfix 2.0 and earlier, disable the "pause
+before reject" feature in the SMTP server. If your system is under
+stress then it should not waste time. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Not needed with Postfix 2.1 and later.
+ smtpd_error_sleep_time = 0
+
+ # Not needed with Postfix 2.4 and later.
+ unknown_local_recipient_reject_code = 550
+</pre>
+</blockquote>
+
+<h2><a name="real">How do I block backscatter mail to real
+recipient addresses?</a></h2>
+
+<p> When backscatter mail passes the "unknown recipient" barrier,
+there still is no need to despair. Many mail systems are kind
+enough to attach the message headers of the undeliverable mail in
+the non-delivery notification. These message headers contain
+information that you can use to recognize and block forged mail.
+</p>
+
+<h3><a name="forged_helo">Blocking backscatter mail with forged
+mail server information</a></h3>
+
+<p> Although my email address is "wietse@porcupine.org", all my
+mail systems announce themselves with the SMTP HELO command as
+"hostname.porcupine.org". Thus, if returned mail has a Received:
+message header like this: </p>
+
+<blockquote>
+<pre>
+Received: from porcupine.org ...
+</pre>
+</blockquote>
+
+<p> Then I know that this is almost certainly forged mail (almost;
+see <a href="#caveats">next section</a> for the fly in the ointment).
+Mail that is really
+sent by my systems looks like this: </p>
+
+<blockquote>
+<pre>
+Received: from hostname.porcupine.org ...
+</pre>
+</blockquote>
+
+<p> For the same reason the following message headers are very likely
+to be the result of forgery:</p>
+
+<blockquote>
+<pre>
+Received: from host.example.com ([1.2.3.4] helo=porcupine.org) ...
+Received: from [1.2.3.4] (port=12345 helo=porcupine.org) ...
+Received: from host.example.com (HELO porcupine.org) ...
+Received: from host.example.com (EHLO porcupine.org) ...
+</pre>
+</blockquote>
+
+<p> Some forgeries show up in the way that a mail server reports
+itself in Received: message headers. Keeping in mind that all my
+systems have a mail server name of <i>hostname</i>.porcupine.org,
+the following is definitely a forgery:</p>
+
+<blockquote>
+<pre>
+Received: by porcupine.org ...
+Received: from host.example.com ( ... ) by porcupine.org ...
+</pre>
+</blockquote>
+
+<p> Another frequent sign of forgery is the Message-ID: header. My
+systems produce a Message-ID: of
+&lt;<i>stuff</i>@<i>hostname</i>.porcupine.org&gt;. The following
+are forgeries, especially the first one:
+
+<blockquote>
+<pre>
+Message-ID: &lt;1cb479435d8eb9.2beb1.qmail@porcupine.org&gt;
+Message-ID: &lt;yulszqocfzsficvzzju@porcupine.org&gt;
+</pre>
+</blockquote>
+
+<p> To block such backscatter I use header_checks and body_checks
+patterns like this: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ header_checks = pcre:/etc/postfix/header_checks
+ body_checks = pcre:/etc/postfix/body_checks
+
+/etc/postfix/header_checks:
+ # Do not indent the patterns between "if" and "endif".
+ if /^Received:/
+ /^Received: +from +(porcupine\.org) +/
+ reject forged client name in Received: header: $1
+ /^Received: +from +[^ ]+ +\(([^ ]+ +[he]+lo=|[he]+lo +)(porcupine\.org)\)/
+ reject forged client name in Received: header: $2
+ /^Received:.* +by +(porcupine\.org)\b/
+ reject forged mail server name in Received: header: $1
+ endif
+ /^Message-ID:.* &lt;!&amp;!/ DUNNO
+ /^Message-ID:.*@(porcupine\.org)/
+ reject forged domain name in Message-ID: header: $1
+
+/etc/postfix/body_checks:
+ # Do not indent the patterns between "if" and "endif".
+ if /^[&gt; ]*Received:/
+ /^[&gt; ]*Received: +from +(porcupine\.org) /
+ reject forged client name in Received: header: $1
+ /^[&gt; ]*Received: +from +[^ ]+ +\(([^ ]+ +[he]+lo=|[he]+lo +)(porcupine\.org)\)/
+ reject forged client name in Received: header: $2
+ /^[&gt; ]*Received:.* +by +(porcupine\.org)\b/
+ reject forged mail server name in Received: header: $1
+ endif
+ /^[&gt; ]*Message-ID:.* &lt;!&amp;!/ DUNNO
+ /^[&gt; ]*Message-ID:.*@(porcupine\.org)/
+ reject forged domain name in Message-ID: header: $1
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> The example uses pcre: tables mainly for speed; with minor
+modifications, you can use regexp: tables as explained below. </p>
+
+<li> <p> The example is simplified for educational purposes. In
+reality my patterns list multiple domain names, as
+"<tt>(domain|domain|...)</tt>". </p>
+
+<li> <p> The "<tt>\.</tt>" matches "<tt>.</tt>" literally. Without
+the "<tt>\</tt>", the "<tt>.</tt>" would match any character. </p>
+
+<li> <p> The "<tt>\(</tt>" and "<tt>\)</tt>" match "<tt>(</tt>"
+and "<tt>)</tt>" literally. Without the "<tt>\</tt>", the "<tt>(</tt>"
+and "<tt>)</tt>" would be grouping operators. </p>
+
+<li> <p> The "<tt>\b</tt>" is used here to match the end of a word.
+If you use regexp: tables, specify "<tt>[[:&gt;:]]</tt>" (on some
+systems you should specify "<tt>\&gt;</tt>" instead; for details
+see your system documentation).
+
+<li> <p> The "if /pattern/" and "endif" eliminate unnecessary
+matching attempts. DO NOT indent lines starting with /pattern/
+between the "if" and "endif"! </p>
+
+<li> <p> The two "<tt>Message-ID:.* &lt;!&amp;!</tt>" rules are
+workarounds for some versions of Outlook express, as described in
+the <a href="#caveats"> caveats </a> section below.
+
+</ul>
+
+<p><a name="caveats"><strong>Caveats</strong></a></p>
+
+<ul>
+
+<li>
+
+<p> Netscape Messenger (and reportedly, Mozilla) sends a HELO name
+that is identical to the sender address domain part. If you have
+such clients then the above patterns would block legitimate email.
+</p>
+
+<p> My network has only one such machine, and to prevent its mail
+from being blocked I have configured it to send mail as
+user@hostname.porcupine.org. On the Postfix server, a canonical
+mapping translates this temporary address into user@porcupine.org.
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ canonical_maps = hash:/etc/postfix/canonical
+
+/etc/postfix/canonical:
+ @hostname.porcupine.org @porcupine.org
+</pre>
+</blockquote>
+
+<p> This is of course practical only when you have very few systems
+that send HELO commands like this, and when you never have to send
+mail to a user on such a host. </p>
+
+<p> An alternative would be to remove the hostname from
+"hostname.porcupine.org" with address
+masquerading, as described in the ADDRESS_REWRITING_README document.
+</p>
+
+<li> <p> Reportedly, Outlook 2003 (perhaps Outlook Express, and
+other versions as well) present substantially different Message-ID
+headers depending upon whether or not a DSN is requested (via Options
+"Request a delivery receipt for this message"). </p>
+
+<p> When a DSN is requested, Outlook 2003 uses a Message-ID string
+that ends in the sender's domain name: </p>
+
+<blockquote>
+<pre>
+Message-ID: &lt;!&amp;! ...very long string... ==@example.com&gt;
+</pre>
+</blockquote>
+
+<p> where <i>example.com</i> is the domain name part of the email
+address specified in Outlook's account settings for the user. Since
+many users configure their email addresses as <i>username@example.com</i>,
+messages with DSN turned on will trigger the REJECT action in the
+previous section. </p>
+
+<p> If you have such clients then you can exclude their Message-ID
+strings with the two "<tt>Message-ID:.* &lt;!&amp;!</tt>" patterns
+that are shown in the previous section. Otherwise you will not be
+able to use the two backscatter rules to stop forged Message ID
+strings. Of course this workaround may break the next time Outlook
+is changed. </p>
+
+</ul>
+
+<h3><a name="forged_sender">Blocking backscatter mail with forged
+sender information</a></h3>
+
+Like many people I still have a few email addresses in domains that
+I used in the past. Mail for those addresses is forwarded to my
+current address. Most of the backscatter mail that I get claims
+to be sent from these addresses. Such mail is obviously forged
+and is very easy to stop.
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ header_checks = pcre:/etc/postfix/header_checks
+ body_checks = pcre:/etc/postfix/body_checks
+
+/etc/postfix/header_checks:
+ /^(From|Return-Path):.*\b(user@domain\.tld)\b/
+ reject forged sender address in $1: header: $2
+
+/etc/postfix/body_checks:
+ /^[&gt; ]*(From|Return-Path):.*\b(user@domain\.tld)\b/
+ reject forged sender address in $1: header: $2
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> The example uses pcre: tables mainly for speed; with minor
+modifications, you can use regexp: tables as explained below. </p>
+
+<li> <p> The example is simplified for educational purposes. In
+reality, my patterns list multiple email addresses as
+"<tt>(user1@domain1\.tld|user2@domain2\.tld)</tt>". </p>
+
+<li> <p> The two "<tt>\b</tt>" as used in "<tt>\b(user@domain\.tld)\b</tt>"
+match the beginning and end of a word, respectively. If you use
+regexp: tables, specify "<tt>[[:&lt;:]]</tt> and <tt>[[:&gt;:]]</tt>"
+(on some systems you should specify "<tt>\&lt;</tt> and <tt>\&gt;</tt>"
+instead; for details see your system documentation). </p>
+
+<li> <p> The "<tt>\.</tt>" matches "<tt>.</tt>" literally. Without
+the "<tt>\</tt>", the "<tt>.</tt>" would match any character. </p>
+
+</ul>
+
+<h3><a name="forged_other">Blocking backscatter mail with other
+forged information</a></h3>
+
+<p> Another sign of forgery can be found in the IP address that is
+recorded in Received: headers next to your HELO host or domain name.
+This information must be used with care, though. Some mail servers
+are behind a network address translator and never see the true
+client IP address. </p>
+
+<h3><a name="scanner">Blocking backscatter mail from virus
+scanners</a></h3>
+
+<p> With all the easily recognizable forgeries eliminated, there
+is one category of backscatter mail that remains, and that is
+notifications from virus scanner software. Unfortunately, some
+virus scanning software doesn't know that viruses forge sender
+addresses. To make matters worse, the software also doesn't know
+how to report a mail delivery problem, so that we cannot use the
+above techniques to recognize forgeries. </p>
+
+<p> Recognizing virus scanner mail is an error prone process,
+because there is a lot of variation in report formats. The following
+is only a small example of message header patterns. For a large
+collection of header and body patterns that recognize virus
+notification email, see
+https://web.archive.org/web/20100317123907/http://std.dkuug.dk/keld/virus/
+or http://www.t29.dk/antiantivirus.txt. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/header_checks:
+ /^Subject: *Your email contains VIRUSES/ DISCARD virus notification
+ /^Content-Disposition:.*VIRUS1_DETECTED_AND_REMOVED/
+ DISCARD virus notification
+ /^Content-Disposition:.*VirusWarning.txt/ DISCARD virus notification
+</pre>
+</blockquote>
+
+<p> Note: these documents haven't been updated since 2004, so they
+are useful only as a starting point. </p>
+
+<p> A plea to virus or spam scanner operators: please do not make
+the problem worse by sending return mail to forged sender addresses.
+You're only harassing innocent people. If you must return mail to
+the purported sender, please return the full message headers, so
+that the sender can filter out the obvious forgeries. </p>
+
+</body>
+
+</html>
diff --git a/proto/BASIC_CONFIGURATION_README.html b/proto/BASIC_CONFIGURATION_README.html
new file mode 100644
index 0000000..531dbf9
--- /dev/null
+++ b/proto/BASIC_CONFIGURATION_README.html
@@ -0,0 +1,684 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title> Postfix Basic Configuration </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Basic Configuration </h1>
+
+<hr>
+
+<h2> Introduction </h2>
+
+<p> Postfix has several hundred configuration parameters that are
+controlled via the main.cf file. Fortunately, all parameters have
+sensible default values. In many cases, you need to configure only
+two or three parameters before you can start to play with the mail
+system. Here's a quick introduction to the syntax: </p>
+
+<ul>
+
+<li> <p> <a href="#syntax">Postfix configuration files</a></p>
+
+</ul>
+
+<p> The text below assumes that you already have Postfix installed
+on the system, either by compiling the source code yourself (as
+described in the INSTALL file) or by installing an already compiled
+version. </p>
+
+<p> This document covers basic Postfix configuration. Information
+about how to configure Postfix for specific applications such as
+mailhub, firewall or dial-up client can be found in the
+STANDARD_CONFIGURATION_README file. But don't go there until you
+already have covered the material presented below. </p>
+
+<p> The first parameters of interest specify the machine's identity
+and role in the network. </p>
+
+<ul>
+
+<li> <p> <a href="#myorigin"> What domain name to use in outbound mail </a> </p>
+
+<li> <p> <a href="#mydestination"> What domains to receive mail for </a> </p>
+
+<li> <p> <a href="#relay_from"> What clients to relay mail from </a> </p>
+
+<li> <p> <a href="#relay_to"> What destinations to relay mail to </a> </p>
+
+<li> <p> <a href="#relayhost"> What delivery method: direct or
+indirect </a> </p>
+
+</ul>
+
+<p> The default values for many other configuration parameters are
+derived from just these. </p>
+
+<p> The next parameter of interest controls the amount of mail sent
+to the local postmaster: </p>
+
+<ul>
+
+<li> <p> <a href="#notify"> What trouble to report to the postmaster
+</a> </p>
+
+</ul>
+
+<p> Be sure to set the following correctly if you're behind a proxy or
+network address translator, and you are running a backup MX host
+for some other domain: </p>
+
+<ul>
+
+<li> <p> <a href="#proxy_interfaces"> Proxy/NAT external network
+addresses </a> </p>
+
+</ul>
+
+<p> Postfix daemon processes run in the background, and log problems
+and normal activity to the syslog daemon. Here are a few things
+that you need to be aware of: </p>
+
+<ul>
+
+<li> <p> <a href="#syslog_howto"> What you need to know about
+Postfix logging </a> </p>
+
+</ul>
+
+<p> If your machine has unusual security requirements you may
+want to run Postfix daemon processes inside a chroot environment. </p>
+
+<ul>
+
+<li> <p> <a href="#chroot_setup"> Running Postfix daemon processes
+chrooted </a> </p>
+
+</ul>
+<p> If you run Postfix on a virtual network interface, or if your
+machine runs other mailers on virtual interfaces, you'll have to
+look at the other parameters listed here as well: </p>
+
+<ul>
+
+<li> <p> <a href="#myhostname"> My own hostname </a> </p>
+
+<li> <p> <a href="#mydomain"> My own domain name </a> </p>
+
+<li> <p> <a href="#inet_interfaces"> My own network addresses </a> </p>
+
+</ul>
+
+<h2> <a name="syntax">Postfix configuration files</a></h2>
+
+<p> By default, Postfix configuration files are in /etc/postfix.
+The two most important files are main.cf and master.cf; these files
+must be owned by root. Giving someone else write permission to
+main.cf or master.cf (or to their parent directories) means giving
+root privileges to that person. </p>
+
+<p> In /etc/postfix/main.cf you will have to set up a minimal number
+of configuration parameters. Postfix configuration parameters
+resemble shell variables, with two important differences: the first
+one is that Postfix does not know about quotes like the UNIX shell
+does.</p>
+
+<p> You specify a configuration parameter as: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ parameter = value
+</pre>
+</blockquote>
+
+<p> and you use it by putting a "$" character in front of its name: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ other_parameter = $parameter
+</pre>
+</blockquote>
+
+<p> You can use $parameter before it is given a value (that is the
+second main difference with UNIX shell variables). The Postfix
+configuration language uses lazy evaluation, and does not look at
+a parameter value until it is needed at runtime. </p>
+
+<p> Postfix uses database files for access control, address rewriting
+and other purposes. The DATABASE_README file gives an introduction
+to how Postfix works with Berkeley DB, LDAP or SQL and other types.
+Here is a common example of how Postfix invokes a database: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ virtual_alias_maps = hash:/etc/postfix/virtual
+</pre>
+</blockquote>
+
+<p> Whenever you make a change to the main.cf or master.cf file,
+execute the following command as root in order to refresh a running
+mail system: </p>
+
+<blockquote>
+<pre>
+# postfix reload
+</pre>
+</blockquote>
+
+<h2> <a name="myorigin"> What domain name to use in outbound mail </a> </h2>
+
+<p> The myorigin parameter specifies the domain that appears in
+mail that is posted on this machine. The default is to use the
+local machine name, $myhostname, which defaults to the name of the
+machine. Unless you are running a really small site, you probably
+want to change that into $mydomain, which defaults to the parent
+domain of the machine name. </p>
+
+<p> For the sake of consistency between sender and recipient addresses,
+myorigin also specifies the domain name that is appended
+to an unqualified recipient address. </p>
+
+<p> Examples (specify only one of the following): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ myorigin = $myhostname (default: send mail as "user@$myhostname")
+ myorigin = $mydomain (probably desirable: "user@$mydomain")
+</pre>
+</blockquote>
+
+<h2><a name="mydestination"> What domains to receive mail for </a>
+</h2>
+
+<p> The mydestination parameter specifies what domains this
+machine will deliver locally, instead of forwarding to another
+machine. The default is to receive mail for the machine itself.
+See the VIRTUAL_README file for how to configure Postfix for
+hosted domains. </p>
+
+<p> You can specify zero or more domain names, "/file/name" patterns
+and/or "type:table" lookup tables (such as hash:, btree:, nis:, ldap:,
+or mysql:), separated by whitespace and/or commas. A "/file/name"
+pattern is replaced by its contents; "type:table" requests that a
+table lookup is done and merely tests for existence: the lookup
+result is ignored. </p>
+
+<p> IMPORTANT: If your machine is a mail server for its entire
+domain, you must list $mydomain as well. </p>
+
+<p> Example 1: default setting. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mydestination = $myhostname localhost.$mydomain localhost
+</pre>
+</blockquote>
+
+<p> Example 2: domain-wide mail server. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mydestination = $myhostname localhost.$mydomain localhost $mydomain
+</pre>
+</blockquote>
+
+<p> Example 3: host with multiple DNS A records. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mydestination = $myhostname localhost.$mydomain localhost
+ www.$mydomain ftp.$mydomain
+</pre>
+</blockquote>
+
+<p> Caution: in order to avoid mail delivery loops, you must list all
+hostnames of the machine, including $myhostname, and localhost.$mydomain. </p>
+
+<h2> <a name="relay_from"> What clients to relay mail from </a> </h2>
+
+<p> By default, Postfix will forward mail from clients in authorized
+network blocks to any destination. Authorized networks are defined
+with the mynetworks configuration parameter. The current default is to
+authorize the local machine only. Prior to Postfix 3.0, the default
+was to authorize all clients in the IP subnetworks that the local
+machine is attached to. </p>
+
+<p> Postfix can also be configured to relay mail from "mobile"
+clients that send mail from outside an authorized network block.
+This is explained in the SASL_README and TLS_README documents. </p>
+
+<p> IMPORTANT: If your machine is connected to a wide area network
+then the "mynetworks_style = subnet" setting may be too friendly. </p>
+
+<p> Examples (specify only one of the following): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mynetworks_style = subnet (not safe on a wide area network)
+ mynetworks_style = host (authorize local machine only)
+ mynetworks = 127.0.0.0/8 (authorize local machine only)
+ mynetworks = 127.0.0.0/8 168.100.189.2/32 (authorize local machine)
+ mynetworks = 127.0.0.0/8 168.100.189.2/28 (authorize local networks)
+</pre>
+</blockquote>
+
+<p> You can specify the trusted networks in the main.cf file, or
+you can let Postfix do the work for you. The default is to let
+Postfix do the work. The result depends on the mynetworks_style
+parameter value.
+
+<ul>
+
+<li> <p> Specify "mynetworks_style = host" (the default when
+compatibility_level &ge; 2) when Postfix should forward mail from
+only the local machine. </p>
+
+<li> <p> Specify "mynetworks_style = subnet" (the default when
+compatibility_level &lt; 2) when Postfix should forward mail from
+SMTP clients in the same IP subnetworks as the local machine.
+On Linux, this works correctly only with interfaces specified
+with the "ifconfig" or "ip" command. </p>
+
+<li> <p> Specify "mynetworks_style = class" when Postfix should
+forward mail from SMTP clients in the same IP class A/B/C networks
+as the local machine. Don't do this with a dialup site - it would
+cause Postfix to "trust" your entire provider's network. Instead,
+specify an explicit mynetworks list by hand, as described below.
+</p>
+
+</ul>
+
+<p> Alternatively, you can specify the mynetworks list by hand,
+in which case Postfix ignores the mynetworks_style setting.
+To specify the list of trusted networks by hand, specify network
+blocks in CIDR (network/mask) notation, for example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mynetworks = 168.100.189.0/28, 127.0.0.0/8
+</pre>
+</blockquote>
+
+<p> You can also specify the absolute pathname of a pattern file instead
+of listing the patterns in the main.cf file. </p>
+
+<h2> <a name="relay_to"> What destinations to relay mail to </a> </h2>
+
+<p> By default, Postfix will forward mail from strangers (clients outside
+authorized networks) to authorized remote destinations only.
+Authorized remote
+destinations are defined with the relay_domains configuration
+parameter. The default is to authorize all domains (and subdomains)
+of the domains listed with the mydestination parameter. </p>
+
+<p> Examples (specify only one of the following): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relay_domains = $mydestination (default)
+ relay_domains = (safe: never forward mail from strangers)
+ relay_domains = $mydomain (forward mail to my domain and subdomains)
+</pre>
+</blockquote>
+
+<h2> <a name="relayhost"> What delivery method: direct or
+indirect </a> </h2>
+
+<p> By default, Postfix tries to deliver mail directly to the
+Internet. Depending on your local conditions this may not be possible
+or desirable. For example, your system may be turned off outside
+office hours, it may be behind a firewall, or it may be connected
+via a provider who does not allow direct mail to the Internet. In
+those cases you need to configure Postfix to deliver mail indirectly
+via a relay host. </p>
+
+<p> Examples (specify only one of the following): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relayhost = (default: direct delivery to Internet)
+ relayhost = $mydomain (deliver via local mailhub)
+ relayhost = [mail.$mydomain] (deliver via local mailhub)
+ relayhost = [mail.isp.tld] (deliver via provider mailhub)
+</pre>
+</blockquote>
+
+<p> The form enclosed with <tt>[]</tt> eliminates DNS MX lookups.
+Don't worry if you don't know what that means. Just be sure to
+specify the <tt>[]</tt> around the mailhub hostname that your ISP
+gave to you, otherwise mail may be mis-delivered. </p>
+
+<p> The STANDARD_CONFIGURATION_README file has more hints and tips
+for firewalled and/or dial-up networks. </p>
+
+<h2> <a name="notify"> What trouble to report to the postmaster</a> </h2>
+
+<p> You should set up a postmaster alias in the aliases(5) table
+that directs mail to a human person. The postmaster address is
+required to exist, so that people can report mail delivery problems.
+While you're updating the aliases(5) table, be sure to direct mail
+for the super-user to a human person too. </p>
+
+<blockquote>
+<pre>
+/etc/aliases:
+ postmaster: you
+ root: you
+</pre>
+</blockquote>
+
+<p> Execute the command "newaliases" after changing the aliases
+file. Instead of /etc/aliases, your alias file may be located
+elsewhere. Use the command "postconf alias_maps" to find out.</p>
+
+<p> The Postfix system reports problems to the postmaster alias.
+You may not be interested in all types of trouble reports, so this
+reporting mechanism is configurable. The default is to report only
+serious problems (resource, software) to postmaster: </p>
+
+<p> Default setting: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ notify_classes = resource, software
+</pre>
+</blockquote>
+
+<p> The meaning of the classes is as follows: </p>
+
+<blockquote>
+
+<dl>
+
+<dt> bounce </dt> <dd> Inform the postmaster of undeliverable
+mail. Either send the postmaster a copy of undeliverable mail that
+is returned to the sender, or send a transcript of the SMTP session
+when Postfix rejected mail. For privacy reasons, the postmaster
+copy of undeliverable mail is truncated after the original message
+headers. This implies "2bounce" (see below). See also the
+luser_relay feature. The notification is sent to the address
+specified with the bounce_notice_recipient configuration parameter
+(default: postmaster). </dd>
+
+<dt> 2bounce </dt> <dd> When Postfix is unable to return undeliverable
+mail to the sender, send it to the postmaster instead (without
+truncating the message after the primary headers). The notification
+is sent to the address specified with the 2bounce_notice_recipient
+configuration parameter (default: postmaster). </dd>
+
+<dt> delay </dt> <dd> Inform the postmaster of delayed mail. In
+this case, the postmaster receives message headers only. The
+notification is sent to the address specified with the
+delay_notice_recipient configuration parameter (default: postmaster).
+</dd>
+
+<dt> policy </dt> <dd> Inform the postmaster of client requests
+that were rejected because of (UCE) policy restrictions. The
+postmaster receives a transcript of the SMTP session. The notification
+is sent to the address specified with the error_notice_recipient
+configuration parameter (default: postmaster). </dd>
+
+<dt> protocol </dt> <dd> Inform the postmaster of protocol errors
+(client or server side) or attempts by a client to execute
+unimplemented commands. The postmaster receives a transcript of
+the SMTP session. The notification is sent to the address specified
+with the error_notice_recipient configuration parameter (default:
+postmaster). </dd>
+
+<dt> resource </dt> <dd> Inform the postmaster of mail not delivered
+due to resource problems (for example, queue file write errors).
+The notification is sent to the address specified with the
+error_notice_recipient configuration parameter (default: postmaster).
+</dd>
+
+<dt> software </dt> <dd> Inform the postmaster of mail not delivered
+due to software problems. The notification is sent to the address
+specified with the error_notice_recipient configuration parameter
+(default: postmaster). </dd>
+
+</dl>
+
+</blockquote>
+
+<h2><a name="proxy_interfaces"> Proxy/NAT external network
+addresses</a> </h2>
+
+<p> Some mail servers are connected to the Internet via a network
+address translator (NAT) or proxy. This means that systems on the
+Internet connect to the address of the NAT or proxy, instead of
+connecting to the network address of the mail server. The NAT or
+proxy forwards the connection to the network address of the mail
+server, but Postfix does not know this. </p>
+
+<p> If you run a Postfix server behind a proxy or NAT, you need to
+configure the proxy_interfaces parameter and specify all the external
+proxy or NAT addresses that Postfix receives mail on. You may
+specify symbolic hostnames instead of network addresses. </p>
+
+<p> IMPORTANT: You must specify your proxy/NAT external addresses
+when your system is a backup MX host for other domains, otherwise
+mail delivery loops will happen when the primary MX host is down.
+</p>
+
+<p> Example: host behind NAT box running a backup MX host. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ proxy_interfaces = 1.2.3.4 (the proxy/NAT external network address)
+</pre>
+</blockquote>
+
+<h2> <a name="syslog_howto"> What you need to know about
+Postfix logging </a> </h2>
+
+<p> Postfix daemon processes run in the background, and log problems
+and normal activity to the syslog daemon. The syslogd process sorts
+events by class and severity, and appends them to logfiles. The
+logging classes, levels and logfile names are usually specified in
+/etc/syslog.conf. At the very least you need something like: </p>
+
+<blockquote>
+<pre>
+/etc/syslog.conf:
+ mail.err /dev/console
+ mail.debug /var/log/maillog
+</pre>
+</blockquote>
+
+<p> After changing the syslog.conf file, send a "HUP" signal to
+the syslogd process. </p>
+
+<p> IMPORTANT: many syslogd implementations will not create files.
+You must create files before (re)starting syslogd. </p>
+
+<p> IMPORTANT: on Linux you need to put a "-" character before the
+pathname, e.g., -/var/log/maillog, otherwise the syslogd process
+will use more system resources than Postfix. </p>
+
+<p> Hopefully, the number of problems will be small, but it is a good
+idea to run every night before the syslog files are rotated: </p>
+
+<blockquote>
+<pre>
+# postfix check
+# egrep '(reject|warning|error|fatal|panic):' /some/log/file
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> The first line (postfix check) causes Postfix to report
+file permission/ownership discrepancies. </p>
+
+<li> <p> The second line looks for problem reports from the mail
+software, and reports how effective the relay and junk mail access
+blocks are. This may produce a lot of output. You will want to
+apply some postprocessing to eliminate uninteresting information.
+</p>
+
+</ul>
+
+<p> The <a href="DEBUG_README.html#logging"> DEBUG_README </a>
+document describes the meaning of the "warning" etc. labels in
+Postfix logging. </p>
+
+<h2> <a name="chroot_setup"> Running Postfix daemon processes
+chrooted </a> </h2>
+
+<p> Postfix daemon processes can be configured (via the master.cf
+file) to run in a chroot jail. The processes run at a fixed low
+privilege and with file system access limited to the Postfix queue
+directories (/var/spool/postfix). This provides a significant
+barrier against intrusion. The barrier is not impenetrable (chroot
+limits file system access only), but every little bit helps.</p>
+
+<p>With the exception of Postfix daemons that deliver mail locally
+and/or that execute non-Postfix commands, every Postfix daemon can
+run chrooted.</p>
+
+<p>Sites with high security requirements should consider to chroot
+all daemons that talk to the network: the smtp(8) and smtpd(8)
+processes, and perhaps also the lmtp(8) client. The author's own
+porcupine.org mail server runs all daemons chrooted that can be
+chrooted. </p>
+
+<p>The default /etc/postfix/master.cf file specifies that no Postfix
+daemon runs chrooted. In order to enable chroot operation, edit
+the file /etc/postfix/master.cf, and follow instructions in the
+file. When you're finished, execute "postfix reload" to make the
+change effective. </p>
+
+<p>Note that a chrooted daemon resolves all filenames relative to
+the Postfix queue directory (/var/spool/postfix). For successful
+use of a chroot jail, most UNIX systems require you to bring in
+some files or device nodes. The examples/chroot-setup directory in
+the source code distribution has a collection of scripts that help
+you set up Postfix chroot environments on different operating
+systems.</p>
+
+<p> Additionally, you almost certainly need to configure syslogd
+so that it listens on a socket inside the Postfix queue directory.
+Examples of syslogd command line options that achieve this for
+specific systems: </p>
+
+<p> FreeBSD: <tt>syslogd -l /var/spool/postfix/var/run/log</tt> </p>
+
+<p> Linux, OpenBSD: <tt>syslogd -a /var/spool/postfix/dev/log</tt> </p>
+
+<h2><a name="myhostname"> My own hostname </a> </h2>
+
+<p> The myhostname parameter specifies the fully-qualified domain
+name of the machine running the Postfix system. $myhostname
+appears as the default value in many other Postfix configuration
+parameters. </p>
+
+<p> By default, myhostname is set to the local machine name. If
+your local machine name is not in fully-qualified domain name form,
+or if you run Postfix on a virtual interface, you will have to
+specify the fully-qualified domain name that the mail system should
+use. </p>
+
+<p> Alternatively, if you specify mydomain in main.cf, then Postfix
+will use its value to generate a fully-qualified default value
+for the myhostname parameter. </p>
+
+<p> Examples (specify only one of the following): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ myhostname = host.local.domain (machine name is not FQDN)
+ myhostname = host.virtual.domain (virtual interface)
+ myhostname = virtual.domain (virtual interface)
+</pre>
+</blockquote>
+
+<h2><a name="mydomain"> My own domain name</a> </h2>
+
+<p> The mydomain parameter specifies the parent domain of
+$myhostname. By default, it is derived from $myhostname
+by stripping off the first part (unless the result would be a
+top-level domain). </p>
+
+<p> Conversely, if you specify mydomain in main.cf, then Postfix
+will use its value to generate a fully-qualified default value
+for the myhostname parameter. </p>
+
+<p> Examples (specify only one of the following): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mydomain = local.domain
+ mydomain = virtual.domain (virtual interface)
+</pre>
+</blockquote>
+
+<h2><a name="inet_interfaces">My own network addresses</a> </h2>
+
+<p>The inet_interfaces parameter specifies all network interface
+addresses that the Postfix system should listen on; mail addressed
+to "user@[network address]" will be delivered locally,
+as if it is addressed to a domain listed in $mydestination.</p>
+
+<p> You can override the inet_interfaces setting in the Postfix
+master.cf file by prepending an IP address to a server name. </p>
+
+<p> The default is to listen on all active interfaces. If you run
+mailers on virtual interfaces, you will have to specify what
+interfaces to listen on. </p>
+
+<p> IMPORTANT: If you run MTAs on virtual interfaces you must
+specify explicit inet_interfaces values for the MTA that receives
+mail for the machine itself: this MTA should never listen on the
+virtual interfaces or you would have a mailer loop when a virtual
+MTA is down. </p>
+
+<p> Example: default setting. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ inet_interfaces = all
+</pre>
+</blockquote>
+
+<p> Example: host running one or more virtual mailers. For
+each Postfix instance, specify only one of the following. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ inet_interfaces = virtual.host.tld (virtual Postfix)
+ inet_interfaces = $myhostname localhost... (non-virtual Postfix)
+</pre>
+</blockquote>
+
+<p> Note: you need to stop and start Postfix after changing this
+parameter. </p>
+
+</body>
+
+</html>
diff --git a/proto/BDAT_README.html b/proto/BDAT_README.html
new file mode 100644
index 0000000..1891c7b
--- /dev/null
+++ b/proto/BDAT_README.html
@@ -0,0 +1,178 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix BDAT (CHUNKING) support</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+BDAT (CHUNKING) support</h1>
+
+<hr>
+
+<h2>Overview </h2>
+
+<p> Postfix SMTP server supports RFC 3030 CHUNKING (the BDAT command)
+without BINARYMIME, in both smtpd(8) and postscreen(8). It is enabled
+by default. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#disable"> Disabling BDAT support</a>
+
+<li><a href="#impact"> Impact on existing configurations</a>
+
+<li><a href="#example"> Example SMTP session</a>
+
+<li> <a href="#benefits">Benefits of CHUNKING (BDAT) support without BINARYMIME</a>
+
+<li> <a href="#downsides">Downsides of CHUNKING (BDAT) support</a>
+
+</ul>
+
+<h2> <a name="disable"> Disabling BDAT support </a> </h2>
+
+<p> BDAT support is enabled by default. To disable BDAT support
+globally: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # The logging alternative:
+ smtpd_discard_ehlo_keywords = chunking
+ # The non-logging alternative:
+ smtpd_discard_ehlo_keywords = chunking, silent-discard
+</pre>
+</blockquote>
+
+<p> Specify '-o smtpd_discard_ehlo_keywords=' in master.cf
+for the submission and smtps services, if you have clients
+that benefit from CHUNKING support. </p>
+
+<h2> <a name="impact"> Impact on existing configurations </a> </h2>
+
+<ul>
+
+<li> <p> There are no changes for smtpd_mumble_restrictions,
+smtpd_proxy_filter, smtpd_milters, or for postscreen settings,
+except for the above mentioned option to suppress the SMTP server's
+CHUNKING service announcement. </p>
+
+<li> <p> There are no changes in the Postfix queue file content,
+no changes for down-stream SMTP servers or after-queue content
+filters, and no changes in the envelope or message content that
+Milters will receive. </p>
+
+</ul>
+
+<h2> <a name="example"> Example SMTP session</a> </h2>
+
+<p> The main differences are that the Postfix SMTP server announces
+"CHUNKING" support in the EHLO response, and that instead of sending
+one DATA request, the remote SMTP client may send one or more BDAT
+requests. In the example below, "S:" indicates server responses,
+and "C:" indicates client requests (bold font). </p>
+
+<blockquote>
+<pre>
+ S: 220 server.example.com
+ C: <b>EHLO client.example.com</b>
+ S: 250-server.example.com
+ S: 250-PIPELINING
+ S: 250-SIZE 153600000
+ S: 250-VRFY
+ S: 250-ETRN
+ S: 250-STARTTLS
+ S: 250-AUTH PLAIN LOGIN
+ S: 250-ENHANCEDSTATUSCODES
+ S: 250-8BITMIME
+ S: 250-DSN
+ S: 250-SMTPUTF8
+ S: 250 CHUNKING
+ C: <b>MAIL FROM:&lt;sender@example.com&gt;</b>
+ S: 250 2.1.0 Ok
+ C: <b>RCPT TO:&lt;recipient@example.com&gt;</b>
+ S: 250 2.1.5 Ok
+ C: <b>BDAT 10000</b>
+ C: <b>..followed by 10000 bytes...</b>
+ S: 250 2.0.0 Ok: 10000 bytes
+ C: <b>BDAT 123</b>
+ C: <b>..followed by 123 bytes...</b>
+ S: 250 2.0.0 Ok: 123 bytes
+ C: <b>BDAT 0 LAST</b>
+ S: 250 2.0.0 Ok: 10123 bytes queued as 41yYhh41qmznjbD
+ C: <b>QUIT</b>
+ S: 221 2.0.0 Bye
+</pre>
+</blockquote>
+
+<p> Internally in Postfix, there is no difference between mail that
+was received with BDAT or with DATA. Postfix smtpd_mumble_restrictions,
+policy delegation queries, smtpd_proxy_filter and Milters all behave
+as if Postfix received (MAIL + RCPT + DATA + end-of-data). However,
+Postfix will log BDAT-related failures as "xxx after BDAT" to avoid
+complicating troubleshooting (xxx = 'lost connection' or 'timeout'),
+and will log a warning when a client sends a malformed BDAT command.
+</p>
+
+<h2> <a name="benefits">Benefits of CHUNKING (BDAT) support without
+BINARYMIME</a> </h2>
+
+<p> Support for CHUNKING (BDAT) was added to improve interoperability
+with some clients, a benefit that would reportedly exist even without
+Postfix support for BINARYMIME. Since June 2018, Wietse's mail
+server has received BDAT commands from a variety of systems. </p>
+
+<p> Postfix does not support BINARYMIME at this time because: </p>
+
+<ul>
+
+<li> <p> BINARYMIME support would require moderately invasive
+changes to Postfix, to support email content that is not line-oriented.
+With BINARYMIME, the Content-Length: message header specifies the
+length of content that may or may not have line boundaries. Without
+BINARYMIME support, email RFCs require that binary content is
+base64-encoded, and formatted as lines of text. </p>
+
+<li> <p> For delivery to non-BINARYMIME systems including UNIX mbox,
+the available options are to convert binary content into 8bit text,
+one of the 7bit forms (base64 or quoted-printable), or to return
+email as undeliverable. Any conversion would obviously break digital
+signatures, so conversion would have to happen before signing. </p>
+
+</ul>
+
+<h2> <a name="downsides">Downsides of CHUNKING (BDAT) support</a>
+</h2>
+
+<p> The RFC 3030 authors did not specify any limitations on how
+clients may pipeline commands (i.e. send commands without waiting
+for a server response). If a server announces PIPELINING support,
+like Postfix does, then a remote SMTP client can pipeline all
+commands following EHLO, for example, MAIL/RCPT/BDAT/BDAT/MAIL/RCPT/BDAT,
+without ever having to wait for a server response. This means that
+with BDAT, the Postfix SMTP server cannot distinguish between a
+well-behaved client and a spambot, based on their command pipelining
+behavior. If you require "reject_unauth_pipelining" to block spambots,
+then turn off Postfix's CHUNKING announcement as described above.
+</p>
+
+<p> In RFC 4468, the authors write that a client may pipeline
+commands, and that after sending BURL LAST or BDAT LAST, a client
+must wait for the server's response. But as this text does not
+appear in RFC 3030 which defines BDAT, it is a useless restriction
+that Postfix will not enforce. </p>
+
+</body>
+
+</html>
diff --git a/proto/BUILTIN_FILTER_README.html b/proto/BUILTIN_FILTER_README.html
new file mode 100644
index 0000000..939fafb
--- /dev/null
+++ b/proto/BUILTIN_FILTER_README.html
@@ -0,0 +1,488 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Built-in Content Inspection</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" alt="">
+Postfix Built-in Content Inspection</h1>
+
+<hr>
+
+<h2>Built-in content inspection introduction </h2>
+
+<p> Postfix supports a built-in filter mechanism that examines
+message header and message body content, one line at a time, before
+it is stored in the Postfix queue. The filter is usually implemented
+with POSIX or PCRE regular expressions, as described in the
+header_checks(5) manual page. </p>
+
+<p> The original purpose of the built-in filter is to stop an
+outbreak of specific email worms or viruses, and it does this job
+well. The filter has also helped to block bounced junk email,
+bounced email from worms or viruses, and notifications from virus
+detection systems. Information about this secondary application
+is given in the BACKSCATTER_README document. </p>
+
+<p> Because the built-in filter is optimized for stopping specific
+worms and virus outbreaks, it has <a href="#limitations">limitations</a>
+that make it NOT suitable for general junk email and virus detection.
+For that, you should use one of the external content inspection
+methods that are described in the FILTER_README, SMTPD_PROXY_README
+and MILTER_README documents. </p>
+
+<p> The following diagram gives an over-all picture of how Postfix
+built-in content inspection works: </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+ <td colspan="4"> <td bgcolor="#f0f0ff" align="center"
+ valign="middle"> Postmaster<br> notifications </td>
+
+</tr>
+
+<tr>
+
+ <td colspan="4"> <td align="center"> <tt> |<br>v </tt></td>
+
+</tr>
+
+<tr>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Network or<br> local users </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+
+ <b> Built-in<br> filter</b> </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Postfix<br> queue </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Delivery<br> agents </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Network or<br> local mailbox </td>
+
+</tr>
+
+<tr>
+
+ <td colspan="4"> <td align="center"> ^<br> <tt> | </tt> </td>
+ <td> </td> <td align="center"> <tt> |<br>v </tt> </td>
+
+</tr>
+
+<tr>
+
+ <td colspan="4"> <td colspan="3" bgcolor="#f0f0ff" align="center"
+ valign="middle"> Undeliverable mail<br> Forwarded mail</td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<p> The picture makes clear that the filter works while Postfix is
+receiving new mail. This means that Postfix can reject mail from
+the network without having to return undeliverable mail to the
+originator address (which is often spoofed anyway). However, this
+ability comes at a price: if mail inspection takes too much time,
+then the remote client will time out, and the client may send the
+same message repeatedly. </p>
+
+<p>Topics covered by this document: </p>
+
+<ul>
+
+<li><a href="#what">What mail is subjected to header/body checks </a>
+
+<li><a href="#limitations">Limitations of Postfix header/body checks </a>
+
+<li><a href="#daily">Preventing daily mail status reports from being blocked </a>
+
+<li><a href="#remote_only">Configuring header/body checks for mail from outside users only</a>
+
+<li><a href="#mx_submission">Configuring different header/body checks for MX service and submission service</a>
+
+<li><a href="#domain_except">Configuring header/body checks for mail to some domains only</a>
+
+</ul>
+
+<h2><a name="what">What mail is subjected to header/body checks </a></h2>
+
+<p> Postfix header/body checks are implemented by the cleanup(8)
+server before it injects mail into the incoming queue. The diagram
+below zooms in on the cleanup(8) server, and shows that this server
+handles mail from many different sources. In order to keep the
+diagram readable, the sources of postmaster notifications are not
+shown, because they can be produced by many Postfix daemon processes.
+</p>
+
+<blockquote>
+
+<table>
+
+<tr> <td colspan="2"> </td> <td bgcolor="#f0f0ff" align="center"
+valign="middle"> bounce(8)<br> (undeliverable) </td> </tr>
+
+<tr> <td bgcolor="#f0f0ff" align="center" valign="middle"> <b>
+smtpd(8)<br> (network)</b> </td> <td align="left" valign="bottom">
+<tt> \ </tt> </td> <td align="center" valign="middle"> <tt> |<br>v
+</tt> </td> </tr>
+
+<tr> <td> </td> <td> </td> </tr>
+
+<tr> <td bgcolor="#f0f0ff" align="center" valign="middle"> <b>
+qmqpd(8)<br> (network)</b> </td> <td align="center" valign="middle">
+<tt> -\<br>-/ </tt> </td> <td bgcolor="#f0f0ff" align="center"
+valign="middle"> cleanup(8) </td> <td align="center" valign="middle">
+<tt> -&gt; </tt> </td> <td bgcolor="#f0f0ff" align="center"
+valign="middle"> <a href="QSHAPE_README.html#incoming_queue">
+incoming<br> queue </a> </td> </tr>
+
+<tr> <td bgcolor="#f0f0ff" align="center" valign="middle"> <b>
+pickup(8)<br> (local)</b> </td> <td align="left" valign="top"> <tt>
+/ </tt> </td> <td align="center" valign="middle"> ^<br> <tt> |
+</tt> </td> </tr>
+
+<tr> <td colspan="2"> </td> <td bgcolor="#f0f0ff" align="center"
+valign="middle"> local(8)<br> (forwarded) </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> For efficiency reasons, only mail that enters from outside of
+Postfix is inspected with header/body checks. It would be inefficient
+to filter already filtered mail again, and it would be undesirable
+to block postmaster notifications. The table below summarizes what
+mail is and is not subject to header/body checks. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Message type </th> <th> Source </th> <th> Header/body checks? </th> </tr>
+
+<tr> <td> Undeliverable mail </td> <td> bounce(8) </td> <td> No </td> </tr>
+
+<tr> <td> Network mail </td> <td> smtpd(8) </td> <td> Configurable </td> </tr>
+
+<tr> <td> Network mail </td> <td> qmqpd(8) </td> <td> Configurable </td> </tr>
+
+<tr> <td> Local submission </td> <td> pickup(8) </td> <td> Configurable </td> </tr>
+
+<tr> <td> Local forwarding </td> <td> local(8) </td> <td> No </td> </tr>
+
+<tr> <td> Postmaster notice </td> <td> many </td> <td> No </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> How does Postfix decide what mail needs to be filtered? It
+would be clumsy to make the decision in the cleanup(8) server, as
+this program receives mail from so many different sources. Instead,
+header/body checks are requested by the source. Examples of how
+to turn off header/body checks for mail received with smtpd(8),
+qmqpd(8) or pickup(8) are given below under "<a
+href="#remote_only">Configuring header/body checks for mail from
+outside users only</a>", "<a href="#mx_submission">Configuring
+different header/body checks for MX service and submission
+service</a>", and "<a href="#domain_except">Configuring
+header/body checks for mail to some domains only</a>". </p>
+
+<h2><a name="limitations">Limitations of Postfix header/body checks </a></h2>
+
+<ul>
+
+<li> <p> Header/body checks do not decode message headers or message
+body content. For example, if text in the message body is BASE64
+encoded (RFC 2045) then your regular expressions will have to match
+the BASE64 encoded form. Likewise, message headers with encoded
+non-ASCII characters (RFC 2047) need to be matched in their encoded
+form. </p>
+
+<li> <p> Header/body checks cannot filter on a combination of
+message headers or body lines. Header/body checks examine content
+one message header at a time, or one message body line at a time,
+and cannot carry a decision over to the next message header or body
+line. </p>
+
+<li> <p> Header/body checks cannot depend on the recipient of a
+message. </p>
+
+<ul>
+
+<li> <p> One message can have multiple recipients, and all recipients
+of a message receive the same treatment. Workarounds have been
+proposed that involve selectively deferring some recipients of
+multi-recipient mail, but that results in poor SMTP performance
+and does not work for non-SMTP mail. </p>
+
+<li> <p> Some sources of mail send the headers and content ahead
+of the recipient information. It would be inefficient to buffer up
+an entire message before deciding if it needs to be filtered, and
+it would be clumsy to filter mail and to buffer up all the actions
+until it is known whether those actions need to be executed. </p>
+
+</ul>
+
+<li> <p> Despite warnings, some people try to use the built-in
+filter feature for general junk email and/or virus blocking, using
+hundreds or even thousands of regular expressions. This can result
+in catastrophic performance failure. The symptoms are as follows:
+</p>
+
+<ul>
+
+<li> <p> The cleanup(8) processes use up all available CPU time in
+order to process the regular expressions, and/or they use up all
+available memory so that the system begins to swap. This slows down
+all incoming mail deliveries. </p>
+
+<li> <p> As Postfix needs more and more time to receive an email
+message, the number of simultaneous SMTP sessions increases to the
+point that the SMTP server process limit is reached. </p>
+
+<li> <p> While all SMTP server processes are waiting for the
+cleanup(8) servers to finish, new SMTP clients have to wait until
+an SMTP server process becomes available. This causes mail deliveries
+to time out before they have even begun. </p>
+
+</ul>
+
+<p> The remedy for this type of performance problem is simple:
+don't use header/body checks for general junk email and/or virus
+blocking, and don't filter mail before it is queued. When performance
+is a concern, use an external content filter that runs after mail
+is queued, as described in the FILTER_README document. </p>
+
+</ul>
+
+<h2><a name="daily">Preventing daily mail status reports from being blocked </a></h2>
+
+<p>The following is quoted from Jim Seymour's Pflogsumm FAQ at
+http://jimsun.linxnet.com/downloads/pflogsumm-faq.txt. Pflogsumm
+is a program that analyzes Postfix logs, including the logging from
+rejected mail. If these logs contain text that was rejected by
+Postfix body_checks patterns, then the logging is also likely to
+be rejected by those same body_checks patterns. This problem does
+not exist with header_checks patterns, because those are not applied
+to the text that is part of the mail status report. </p>
+
+<blockquote>
+
+<p>You configure Postfix to do body checks, Postfix does its thing,
+Pflogsumm reports it and Postfix catches the same string in the
+Pflogsumm report. There are several solutions to this. </p>
+
+<p> Wolfgang Zeikat contributed this: </p>
+
+<blockquote>
+<pre>
+#!/usr/bin/perl
+use MIME::Lite;
+
+### Create a new message:
+$msg = MIME::Lite-&gt;new(
+ From =&gt; 'your@send.er',
+ To =&gt; 'your@recipie.nt',
+ # Cc =&gt; 'some@other.com, some@more.com',
+ Subject =&gt; 'pflogsumm',
+ Date =&gt; `date`,
+ Type =&gt; 'text/plain',
+ Encoding =&gt; 'base64',
+ Path =&gt; '/tmp/pflogg',
+);
+
+$msg-&gt;send;
+</pre>
+</blockquote>
+
+<p> Where "/tmp/pflogg" is the output of Pflogsumm. This puts Pflogsumm's
+output in a base64 MIME attachment. </p>
+
+</blockquote>
+
+<p> Note by Wietse: if you run this on a machine that is accessible
+by untrusted users, it is safer to store the Pflogsumm report in
+a directory that is not world writable. </p>
+
+<blockquote>
+
+<p> In a follow-up to a thread in the postfix-users mailing list, Ralf
+Hildebrandt noted: </p>
+
+<blockquote> <p> "mpack does the same thing." </p> </blockquote>
+
+</blockquote>
+
+<p> And it does. Which tool one should use is a matter of preference.
+</p>
+
+<p> Other solutions involve additional body_checks rules that make
+exceptions for daily mail status reports, but this is not recommended.
+Such rules slow down all mail and complicate Postfix maintenance.
+</p>
+
+<h2><a name="remote_only">Configuring header/body checks for mail from outside users only</a></h2>
+
+<p> The following information applies to Postfix 2.1 and later.
+Earlier
+Postfix versions do not support the receive_override_options feature.
+</p>
+
+<p> The easiest approach is to configure ONE Postfix instance with
+multiple SMTP server IP addresses in master.cf: </p>
+
+<ul>
+
+<li> <p> Two SMTP server IP addresses for mail from inside users
+only, with header/body filtering turned off, and a local mail pickup
+service with header/body filtering turned off. </p>
+
+<pre>
+/etc/postfix.master.cf:
+ # ==================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # ==================================================================
+ 1.2.3.4:smtp inet n - n - - smtpd
+ -o receive_override_options=no_header_body_checks
+ 127.0.0.1:smtp inet n - n - - smtpd
+ -o receive_override_options=no_header_body_checks
+ pickup fifo n - n 60 1 pickup
+ -o receive_override_options=no_header_body_checks
+</pre>
+
+<li> <p> Add some firewall rule to prevent access to 1.2.3.4:smtp
+from the outside world. </p>
+
+<li> <p> One SMTP server address for mail from outside users with
+header/body filtering turned on via main.cf. </p>
+
+<pre>
+/etc/postfix.master.cf:
+ # =================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =================================================================
+ 1.2.3.5:smtp inet n - n - - smtpd
+</pre>
+
+</ul>
+
+<h2><a name="mx_submission">Configuring different header/body checks for MX service and submission service</a></h2>
+
+<p> If authorized user submissions require different header/body
+checks than mail from remote MTAs, then this is possible as long
+as you have separate mail streams for authorized users and for MX
+service. </p>
+
+<p> The example below assumes that authorized users connect to TCP
+port 587 (submission) or 465 (smtps), and that remote MTAs connect
+to TCP port 25 (smtp). </p>
+
+<p> First, we define a few "user-defined" parameters that will
+override settings for the submission and smtps services. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ msa_cleanup_service_name = msa_cleanup
+ msa_header_checks = pcre:/etc/postfix/msa_header_checks
+ msa_body_checks = pcre:/etc/postfix/msa_body_checks
+</pre>
+</blockquote>
+
+<p> Next, we define msa_cleanup as a dedicated cleanup service that
+will be used only by the submission and smtps services. This service
+uses the header_checks and body_checks overrides that were defined
+above. </p>
+
+<blockquote>
+<pre>
+/etc/postfix.master.cf:
+ # =================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =================================================================
+ smtp inet n - n - - smtpd
+ msa_cleanup unix n - n - 0 cleanup
+ -o header_checks=$msa_header_checks
+ -o body_checks=$msa_body_checks
+ submission inet n - n - - smtpd
+ -o cleanup_service_name=$msa_cleanup_service_name
+ -o syslog_name=postfix/submission
+ <i>...[see sample master.cf file for more]...</i>
+ smtps inet n - n - - smtpd
+ -o cleanup_service_name=$msa_cleanup_service_name
+ -o syslog_name=postfix/smtps
+ -o smtpd_tls_wrappermode=yes
+ <i>...[see sample master.cf file for more]...</i>
+</pre>
+</blockquote>
+
+<p> By keeping the "msa_xxx" parameter settings in main.cf, you
+keep your master.cf file simple, and you minimize the amount
+of duplication. </p>
+
+<h2><a name="domain_except">Configuring header/body checks for mail to some domains only</a></h2>
+
+<p> The following information applies to Postfix 2.1. Earlier
+Postfix versions do not support the receive_override_options feature.
+</p>
+
+<p> If you are an MX service provider and want to enable header/body
+checks only for some domains, you can configure ONE Postfix
+instance with multiple SMTP server IP addresses in master.cf. Each
+address provides a different service. </p>
+
+<blockquote>
+
+<pre>
+/etc/postfix.master.cf:
+ # =================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =================================================================
+ # SMTP service for domains with header/body checks turned on.
+ 1.2.3.4:smtp inet n - n - - smtpd
+
+ # SMTP service for domains with header/body checks turned off.
+ 1.2.3.5:smtp inet n - n - - smtpd
+ -o receive_override_options=no_header_body_checks
+</pre>
+</blockquote>
+
+<p> Once this is set up you can configure MX records in the DNS
+that route each domain to the proper SMTP server instance. </p>
+
+</body>
+
+</html>
diff --git a/proto/CDB_README.html b/proto/CDB_README.html
new file mode 100644
index 0000000..3fd0973
--- /dev/null
+++ b/proto/CDB_README.html
@@ -0,0 +1,109 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix CDB Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix CDB Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> CDB (Constant DataBase) is an indexed file format designed by
+Daniel Bernstein. CDB is optimized exclusively for read access
+and guarantees that each record will be read in at most two disk
+accesses. This is achieved by forgoing support for incremental
+updates: no single-record inserts or deletes are supported. CDB
+databases can be modified only by rebuilding them completely from
+scratch, hence the "constant" qualifier in the name. </p>
+
+<p> Postfix CDB databases are specified as "cdb:<i>name</i>", where
+<i>name</i> specifies the CDB file name without the ".cdb" suffix
+(another suffix, ".tmp", is used temporarily while a CDB file is
+under construction). CDB databases are maintained with the postmap(1)
+or postalias(1) command. The DATABASE_README document has general
+information about Postfix databases. </p>
+
+<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 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>
+
+<ul>
+
+<li> <p> The original cdb library from Daniel Bernstein, available
+from http://cr.yp.to/cdb.html, and </p>
+
+<li> <p> tinycdb (version 0.5 and later) from Michael Tokarev,
+available from http://www.corpit.ru/mjt/tinycdb.html. </p>
+
+</ul>
+
+<p> Tinycdb is preferred, since it is a bit faster, has additional
+useful functionality and is much simpler to use. </p>
+
+<p>To build Postfix after you have installed tinycdb, use something
+like: </p>
+
+<blockquote>
+<pre>
+% make tidy
+% CDB=../../../tinycdb-0.5
+% make -f Makefile.init makefiles "CCARGS=-DHAS_CDB -I$CDB" \
+ "AUXLIBS_CDB=$CDB/libcdb.a"
+% make
+</pre>
+</blockquote>
+
+<p> Alternatively, for the D.J.B. version of CDB:<p>
+
+<blockquote>
+<pre>
+% make tidy
+% CDB=../../../cdb-0.75
+% make -f Makefile.init makefiles "CCARGS=-DHAS_CDB -I$CDB" \
+ "AUXLIBS_CDB=$CDB/cdb.a $CDB/alloc.a $CDB/buffer.a $CDB/unix.a $CDB/byte.a"
+% make
+</pre>
+</blockquote>
+
+<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_CDB.
+With Postfix 3.0 and later, the old AUXLIBS variable still supports
+building a statically-loaded CDB database client, but only the new
+AUXLIBS_CDB variable supports building a dynamically-loaded or
+statically-loaded CDB database client. </p>
+
+<blockquote>
+
+<p> Failure to use the AUXLIBS_CDB variable will defeat the purpose
+of dynamic database client loading. Every Postfix executable file
+will have CDB database library dependencies. And that was exactly
+what dynamic database client loading was meant to avoid. </p>
+
+</blockquote>
+
+<p> After Postfix has been built with cdb support, you can use
+"cdb" tables wherever you can use read-only "hash", "btree" or
+"dbm" tables. However, the "<b>postmap -i</b>" (incremental record
+insertion) and "<b>postmap -d</b>" (incremental record deletion)
+command-line options are not available. For the same reason the
+"cdb" map type cannot be used to store the persistent address
+verification cache for the verify(8) service, or to store
+TLS session information for the tlsmgr(8) service. </p>
diff --git a/proto/COMPATIBILITY_README.html b/proto/COMPATIBILITY_README.html
new file mode 100644
index 0000000..7020dbe
--- /dev/null
+++ b/proto/COMPATIBILITY_README.html
@@ -0,0 +1,594 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Backwards-Compatibility Safety Net</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Backwards-Compatibility Safety Net</h1>
+
+<hr>
+
+<h2>Purpose of this document </h2>
+
+<p> Postfix 3.0 introduces a safety net that runs Postfix programs
+with backwards-compatible default settings after an upgrade. The
+safety net will log a warning whenever a "new" default setting could
+have an negative effect on your mail flow. </p>
+
+<p>This document provides information on the following topics: </p>
+
+<ul>
+
+<li> <p> <a href="#overview">Detailed descriptions</a> of Postfix
+backwards-compatibility warnings.
+
+<li> <p> What backwards-compatible settings you may have to make
+permanent in main.cf or master.cf. </p>
+
+<li> <p> <a href="#turnoff">How to turn off</a> Postfix
+backwards-compatibility warnings. </p>
+
+</ul>
+
+<h2> <a name="overview"> Overview </a> </h2>
+
+<p> With backwards compatibility turned on, Postfix logs a message
+whenever a backwards-compatible default setting may be required for
+continuity of service. Based on this logging the system administrator
+can decide if any backwards-compatible settings need to be made
+permanent in main.cf or master.cf, before <a href="#turnoff">turning
+off the backwards-compatibility safety net</a> as described at the
+end of this document. </p>
+
+<p> Logged with compatibility_level &lt; 1: </p>
+
+<ul>
+
+<li> <p> <a href="#append_dot_mydomain"> Using backwards-compatible
+default setting append_dot_mydomain=yes </a> </p>
+
+<li> <p> <a href="#chroot"> Using backwards-compatible default setting
+chroot=y</a> </p>
+
+</ul>
+
+<p> Logged with compatibility_level &lt; 2: </p>
+
+<ul>
+
+<li><p> <a href="#relay_restrictions"> Using backwards-compatible
+default setting "smtpd_relay_restrictions = (empty)"</a> </p>
+
+<li> <p> <a href="#mynetworks_style"> Using backwards-compatible
+default setting mynetworks_style=subnet </a> </p>
+
+<li> <p> <a href="#relay_domains"> Using backwards-compatible default
+setting relay_domains=$mydestination </a> </p>
+
+<li> <p> <a href="#smtputf8_enable"> Using backwards-compatible
+default setting smtputf8_enable=no</a> </p>
+
+</ul>
+
+<p> Logged with compatibility_level &lt; 3.6: </p>
+
+<ul>
+
+<li> <p> <a href="#smtpd_digest"> Using backwards-compatible
+default setting smtpd_tls_fingerprint_digest=md5</a> </p>
+
+<li> <p> <a href="#smtp_digest"> Using backwards-compatible
+default setting smtp_tls_fingerprint_digest=md5</a> </p>
+
+<li> <p> <a href="#smtp_digest"> Using backwards-compatible
+default setting lmtp_tls_fingerprint_digest=md5</a> </p>
+
+<li> <p> <a href="#relay_before_rcpt"> Using backwards-compatible
+default setting smtpd_relay_before_recipient_restrictions=no</a> </p>
+
+<li> <p> <a href="#respectful_logging"> Using backwards-compatible
+default setting respectful_logging=no</a> </p>
+
+</ul>
+
+<p> If such a message is logged in the context of a legitimate
+request, the system administrator should make the backwards-compatible
+setting permanent in main.cf or master.cf, as detailed in the
+sections that follow. </p>
+
+<p> When no more backwards-compatible settings need to be made
+permanent, the system administrator should <a href="#turnoff">turn
+off the backwards-compatibility safety net</a> as described at the
+end of this document. </p>
+
+<h2> <a name="append_dot_mydomain"> Using backwards-compatible default
+setting append_dot_mydomain=yes</a> </h2>
+
+<p> The append_dot_mydomain default value has changed from "yes"
+to "no". This could result in unexpected non-delivery of email after
+Postfix is updated from an older version. The backwards-compatibility
+safety net is designed to prevent such surprises. </p>
+
+<p> As long as the append_dot_mydomain parameter is left at
+its implicit default value, and the compatibility_level setting is
+less than 1, Postfix may log one of the following messages:</p>
+
+<ul>
+
+<li> <p> Messages about missing "localhost" in mydestination or
+other address class: </p>
+
+<blockquote>
+<pre>
+postfix/trivial-rewrite[14777]: using backwards-compatible
+ default setting append_dot_mydomain=yes to rewrite
+ "localhost" to "localhost.example.com"; please add
+ "localhost" to mydestination or other address class
+</pre>
+</blockquote>
+
+<p> If Postfix logs the above message, add "localhost" to
+mydestination (or virtual_alias_domains, virtual_mailbox_domains,
+or relay_domains) and execute the command "<b>postfix reload</b>".
+
+<li> <p> Messages about incomplete domains in email addresses: </p>
+
+<blockquote>
+<pre>
+postfix/trivial-rewrite[25835]: using backwards-compatible
+ default setting append_dot_mydomain=yes to rewrite "foo" to
+ "foo.example.com"
+</pre>
+</blockquote>
+
+<p> If Postfix logs the above message for domains different from
+"localhost", and the sender cannot be changed to use complete domain
+names in email addresses, then the system administrator should make
+the backwards-compatible setting "append_dot_mydomain = yes" permanent
+in main.cf: </p>
+
+<blockquote>
+<pre>
+# <b>postconf append_dot_mydomain=yes</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+</ul>
+
+<h2> <a name="chroot"> Using backwards-compatible default
+setting chroot=y</a> </h2>
+
+<p> The master.cf chroot default value has changed from "y" (yes)
+to "n" (no). The new default avoids the need for copies of system
+files under the Postfix queue directory. However, sites with strict
+security requirements may want to keep the chroot feature enabled
+after updating Postfix from an older version. The backwards-compatibility
+safety net is designed allow the administrator to choose if they
+want to keep the old behavior. </p>
+
+<p> As long as a master.cf chroot field is left at its
+implicit default value, and the compatibility_level setting
+is less than 1, Postfix may log the following message while it
+reads the master.cf file: </p>
+
+<blockquote>
+<pre>
+postfix/master[27664]: /etc/postfix/master.cf: line 72: using
+ backwards-compatible default setting chroot=y
+</pre>
+</blockquote>
+
+<p> If this service should remain chrooted, then the system
+administrator should make the backwards-compatible setting "chroot
+= y" permanent in master.cf. For example, to update the chroot
+setting for the "smtp inet" service: </p>
+
+<blockquote>
+<pre>
+# <b>postconf -F smtp/inet/chroot=y</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<h2> <a name="relay_restrictions"> Using backwards-compatible default
+setting smtpd_relay_restrictions = (empty)</a> </h2>
+
+<p> The smtpd_relay_restrictions feature was introduced with Postfix
+version 2.10, as a safety mechanism for configuration errors in
+smtpd_recipient_restrictions that could make Postfix an open relay.
+</p>
+
+<p> The smtpd_relay_restrictions implicit default setting forbids
+mail to remote destinations from clients that don't match
+permit_mynetworks or permit_sasl_authenticated. This could result
+in unexpected 'Relay access denied' errors after Postfix is updated
+from an older Postfix version. The backwards-compatibility safety
+net is designed to prevent such surprises. </p>
+
+<p> When the compatibility_level less than 1, and the
+smtpd_relay_restrictions parameter is left at its implicit default
+setting, Postfix may log the following message: </p>
+
+<blockquote>
+<pre>
+postfix/smtpd[38463]: using backwards-compatible default setting
+ "smtpd_relay_restrictions = (empty)" to avoid "Relay access
+ denied" error for recipient "user@example.com" from client
+ "host.example.net[10.0.0.2]"
+</pre>
+</blockquote>
+
+<p> If this request should not be blocked, then the system
+administrator should make the backwards-compatible setting
+"smtpd_relay_restrictions=" (i.e. empty) permanent in main.cf:
+
+<blockquote>
+<pre>
+# <b>postconf smtpd_relay_restrictions=</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<h2> <a name="mynetworks_style"> Using backwards-compatible default
+setting mynetworks_style=subnet</a> </h2>
+
+<p> The mynetworks_style default value has changed from "subnet"
+to "host". This parameter is used to implement the "permit_mynetworks"
+feature. The change could cause unexpected 'access denied' errors after
+Postfix is updated from an older version. The backwards-compatibility
+safety net is designed to prevent such surprises. </p>
+
+<p> As long as the mynetworks and mynetworks_style parameters are
+left at their implicit default values, and the compatibility_level
+setting is less than 2, the Postfix SMTP server may log one of the
+following messages: </p>
+
+<blockquote>
+<pre>
+postfix/smtpd[17375]: using backwards-compatible default setting
+ mynetworks_style=subnet to permit request from client
+ "foo.example.com[10.1.1.1]"
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+postfix/postscreen[24982]: using backwards-compatible default
+ setting mynetworks_style=subnet to permit request from client
+ "10.1.1.1"
+</pre>
+</blockquote>
+
+<p> If the client request should not be rejected, then the system
+administrator should make the backwards-compatible setting
+"mynetworks_style = subnet" permanent in main.cf: </p>
+
+<blockquote>
+<pre>
+# <b>postconf mynetworks_style=subnet</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<h2><a name="relay_domains"> Using backwards-compatible default
+setting relay_domains=$mydestination </a> </h2>
+
+<p> The relay_domains default value has changed from "$mydestination"
+to the empty value. This could result in unexpected 'Relay access
+denied' errors or ETRN errors after Postfix is updated from an older
+version. The backwards-compatibility safety net is designed to
+prevent such surprises. </p>
+
+<p> As long as the relay_domains parameter is left at its implicit
+default value, and the compatibility_level setting is less than 2,
+Postfix may log one of the following messages. </p>
+
+<ul>
+
+<li> <p> Messages about accepting mail for a remote domain:</p>
+
+<blockquote>
+<pre>
+postfix/smtpd[19052]: using backwards-compatible default setting
+ relay_domains=$mydestination to accept mail for domain
+ "foo.example.com"
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+postfix/smtpd[19052]: using backwards-compatible default setting
+ relay_domains=$mydestination to accept mail for address
+ "user@foo.example.com"
+</pre>
+</blockquote>
+
+<li> <p> Messages about providing ETRN service for a remote domain:</p>
+
+<blockquote>
+<pre>
+postfix/smtpd[19138]: using backwards-compatible default setting
+ relay_domains=$mydestination to flush mail for domain
+ "bar.example.com"
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+postfix/smtp[13945]: using backwards-compatible default setting
+ relay_domains=$mydestination to update fast-flush logfile for
+ domain "bar.example.com"
+</pre>
+</blockquote>
+
+</ul>
+
+<p> If Postfix should continue to accept mail for that domain or
+continue to provide ETRN service for that domain, then the system
+administrator should make the backwards-compatible setting
+"relay_domains = $mydestination" permanent in main.cf: </p>
+
+<blockquote>
+<pre>
+# <b>postconf 'relay_domains=$mydestination'</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> Note: quotes are required as indicated above. </p>
+
+<p> Instead of $mydestination, it may be better to specify an
+explicit list of domain names. </p>
+
+<h2> <a name="smtputf8_enable"> Using backwards-compatible default
+setting smtputf8_enable=no</a> </h2>
+
+<p> The smtputf8_enable default value has changed from "no" to "yes".
+With the new "yes" setting, the Postfix SMTP server rejects non-ASCII
+addresses from clients that don't request SMTPUTF8 support, after
+Postfix is updated from an older version. The backwards-compatibility
+safety net is designed to prevent such surprises. </p>
+
+<p> As long as the smtputf8_enable parameter is left at its implicit
+default value, and the compatibility_level setting is
+less than 1, Postfix logs a warning each time an SMTP command uses a
+non-ASCII address localpart without requesting SMTPUTF8 support: </p>
+
+<blockquote>
+<pre>
+postfix/smtpd[27560]: using backwards-compatible default setting
+ smtputf8_enable=no to accept non-ASCII sender address
+ "??@example.org" from localhost[127.0.0.1]
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+postfix/smtpd[27560]: using backwards-compatible default setting
+ smtputf8_enable=no to accept non-ASCII recipient address
+ "??@example.com" from localhost[127.0.0.1]
+</pre>
+</blockquote>
+
+<p> If the address should not be rejected, and the client cannot
+be updated to use SMTPUTF8, then the system administrator should
+make the backwards-compatible setting "smtputf8_enable = no" permanent
+in main.cf:
+
+<blockquote>
+<pre>
+# <b>postconf smtputf8_enable=no</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<h2> <a name="smtpd_digest"> Using backwards-compatible
+default setting smtpd_tls_fingerprint_digest=md5</a> </h2>
+
+<p> The smtpd_tls_fingerprint_digest default value has changed from
+"md5" to "sha256". With the new "sha256" setting, the Postfix SMTP
+server avoids using the deprecated "md5" algorithm and computes a more
+secure digest of the client certificate. </p>
+
+<p> If you're using the default "md5" setting, or even an explicit
+"sha1" (also deprecated) setting, you should consider switching to
+"sha256". This will require updating any associated lookup table keys
+with the "sha256" digests of the expected client certificate or public
+key. </p>
+
+<p> As long as the smtpd_tls_fingerprint_digest parameter is left at its
+implicit default value, and the compatibility_level setting is less than
+3.6, Postfix logs a warning each time a client certificate or public key
+fingerprint is (potentially) used for access control: </p>
+
+<blockquote>
+<pre>
+postfix/smtpd[27560]: using backwards-compatible default setting
+ smtpd_tls_fingerprint_digest=md5 to compute certificate fingerprints
+</pre>
+</blockquote>
+
+<p> Since any client certificate fingerprints are passed in policy service
+lookups, and Postfix doesn't know whether the fingerprint will be used, the
+warning may also be logged when policy lookups are performed for connections
+that used a client certificate, even if the policy service does not in fact
+examine the client certificate. To reduce the noise somewhat, such warnings
+are issued at most once per smtpd(8) process instance. </p>
+
+<p> If you prefer to stick with "md5", you can suppress the warnings by
+making that setting explicit. After addressing any other compatibility
+warnings, you can <a href="#turnoff">update</a> your compatibility level.
+</p>
+
+<blockquote>
+<pre>
+# <b>postconf smtpd_tls_fingerprint_digest=md5</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<h2> <a name="smtp_digest"> Using backwards-compatible
+default setting smtp_tls_fingerprint_digest=md5</a> </h2>
+
+<p> The smtp_tls_fingerprint_digest and lmtp_tls_fingerprint_digest
+default values have changed from "md5" to "sha256". With the new
+"sha256" setting, the Postfix SMTP and LMTP client avoids using the
+deprecated "md5" algorithm and computes a more secure digest of the
+server certificate. </p>
+
+<p> If you're using the default "md5" setting, or even an explicit
+"sha1" (also deprecated) setting, you should consider switching to
+"sha256". This will require updating any "fingerprint" security level
+policies in the TLS policy table to specify matching "sha256" digests of
+the expected server certificates or public keys. </p>
+
+<p> As long as the smtp_tls_fingerprint_digest (or LMTP equivalent)
+parameter is left at its implicit default value, and the
+compatibility_level setting is less than 3.6, Postfix logs a warning each
+time the "fingerprint" security level is used to specify matching "md5"
+digests of trusted server certificates or public keys: </p>
+
+<blockquote>
+<pre>
+postfix/smtp[27560]: using backwards-compatible default setting
+ smtp_tls_fingerprint_digest=md5 to compute certificate fingerprints
+</pre>
+</blockquote>
+
+<p> If you prefer to stick with "md5", you can suppress the warnings by
+making that setting explicit. After addressing any other compatibility
+warnings, you can <a href="#turnoff">update</a> your compatibility level.
+</p>
+
+<blockquote>
+<pre>
+# <b>postconf 'smtp_tls_fingerprint_digest = md5' \
+ 'lmtp_tls_fingerprint_digest = md5' </b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<h2> <a name="relay_before_rcpt"> Using backwards-compatible
+default setting smtpd_relay_before_recipient_restrictions=no</a> </h2>
+
+<p> The smtpd_relay_before_recipient_restrictions feature was
+introduced in Postfix version 3.6, to evaluate smtpd_relay_restrictions
+before smtpd_recipient_restrictions. Historically, smtpd_relay_restrictions
+was evaluated after smtpd_recipient_restrictions, contradicting
+documented behavior. </p>
+
+<blockquote> <p> Background: smtpd_relay_restrictions is
+primarily designed to enforce a mail relaying policy, while
+smtpd_recipient_restrictions is primarily designed to enforce spam
+blocking policy. Both are evaluated while replying to the RCPT TO
+command, and both support the same features. </p> </blockquote>
+
+<p> To maintain compatibility with earlier versions, Postfix will
+keep evaluating smtpd_recipient_restrictions before
+smtpd_relay_restrictions, as long as the compatibility_level is
+less than 3.6, and the smtpd_relay_before_recipient_restrictions
+parameter is left at its implicit default setting. As a reminder,
+Postfix may log the following message: </p>
+
+<blockquote>
+<pre>
+postfix/smtpd[54696]: using backwards-compatible default setting
+ smtpd_relay_before_recipient_restrictions=no to reject recipient
+ "user@example.com" from client "host.example.net[10.0.0.2]"
+</pre>
+</blockquote>
+
+<p> If Postfix should keep evaluating smtpd_recipient_restrictions
+before smtpd_relay_restrictions, then the system
+administrator should make the backwards-compatible setting
+"smtpd_relay_before_recipient_restrictions=no" permanent in main.cf: </p>
+
+<blockquote>
+<pre>
+# <b> postconf smtpd_relay_before_recipient_restrictions=no </b>
+# <b> postfix reload </b>
+</pre>
+</blockquote>
+
+<h2> <a name="respectful_logging"> Using backwards-compatible
+default setting respectful_logging=no</a> </h2>
+
+<p> Postfix version 3.6 deprecates configuration parameter names and
+logging that suggest white is better than black. Instead it prefers
+'allowlist, 'denylist', and variations of those words. While the renamed
+configuration parameters have backwards-compatible default values,
+the changes in logging could affect logfile analysis tools. </p>
+
+<p> To avoid breaking existing logfile analysis tools, Postfix will keep
+logging the deprecated form, as long as the respectful_logging parameter
+is left at its implicit default value, and the compatibility_level
+setting is less than 3.6. As a reminder, Postfix may log the following
+when a remote SMTP client is allowlisted or denylisted: </p>
+
+<blockquote>
+<pre>
+postfix/postscreen[22642]: Using backwards-compatible default setting
+ respectful_logging=no for client [<i>address</i>]:<i>port</i>
+</pre>
+</blockquote>
+
+<p> If Postfix should keep logging the deprecated form, then the
+system administrator should make the backwards-compatible setting
+"respectful_logging = no" permanent in main.cf.
+
+<blockquote>
+<pre>
+# <b>postconf "respectful_logging = no"</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2>
+
+<p> Backwards compatibility is turned off by updating the
+compatibility_level setting in main.cf. </p>
+
+<blockquote>
+<pre>
+# <b>postconf compatibility_level=<i>N</i></b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> For <i>N</i> specify the number that is logged in your postfix(1)
+warning message: </p>
+
+<blockquote>
+<pre>
+warning: To disable backwards compatibility use "postconf compatibility_level=<i>N</i>" and "postfix reload"
+</pre>
+</blockquote>
+
+<p> Sites that don't care about backwards compatibility may set
+"compatibility_level = 9999" at their own risk. </p>
+
+<p> Starting with Postfix version 3.6, the compatibility level in
+the above warning message is the Postfix version that introduced
+the last incompatible change. The level is formatted as
+<i>major.minor.patch</i>, where <i>patch</i> is usually omitted and
+defaults to zero. Earlier compatibility levels are 0, 1 and 2. </p>
+
+<p> NOTE: Postfix 3.6 also introduces support for the "&lt;level",
+"&lt;=level", and other operators to compare compatibility levels.
+With the standard operators "&lt;", "&lt;=", etc., compatibility
+level "3.10" would be smaller than "3.9" which is undesirable. </p>
+
+</body>
+
+</html>
diff --git a/proto/CONNECTION_CACHE_README.html b/proto/CONNECTION_CACHE_README.html
new file mode 100644
index 0000000..bc2e34e
--- /dev/null
+++ b/proto/CONNECTION_CACHE_README.html
@@ -0,0 +1,350 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Connection Cache </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Connection Cache </h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> This document describes the Postfix connection cache implementation,
+which is available with Postfix version 2.2 and later. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#summary"> What SMTP connection caching can do for you</a>
+
+<li><a href="#implementation"> Connection cache implementation</a>
+
+<li><a href="#configuration"> Connection cache configuration</a>
+
+<li><a href="#safety">Connection cache safety mechanisms </a>
+
+<li><a href="#limitations">Connection cache limitations</a>
+
+<li><a href="#statistics">Connection cache statistics</a>
+
+</ul>
+
+<h2><a name="summary">What SMTP connection caching can do for
+you</a></h2>
+
+<p> With SMTP connection caching, Postfix can deliver multiple
+messages over the same SMTP connection. By default, Postfix 2.2
+reuses a plaintext SMTP connection automatically when a destination has
+high volume of mail in the active queue. </p>
+
+<p> SMTP Connection caching is a performance feature. Whether or not
+it actually improves performance depends on the conditions: </p>
+
+<ul>
+
+<li> <p> SMTP Connection caching can greatly improve performance
+when delivering mail to a destination with multiple mail servers,
+because it can help Postfix to skip over a non-responding server.
+</p>
+
+<li> <p> SMTP Connection caching can also help with receivers that
+impose rate limits on new connections. </p>
+
+<li> <p> Otherwise, the benefits of SMTP connection caching are
+minor: it eliminates the latency of the TCP handshake (SYN, SYN+ACK,
+ACK), plus the latency of the SMTP initial handshake (220 greeting,
+EHLO command, EHLO response). With TLS-encrypted connections, this
+can save an additional two roundtrips that would otherwise be needed
+to send STARTTLS and to resume a TLS session. </p>
+
+<li> <p> SMTP Connection caching gives no gains with respect to
+SMTP session tear-down. The Postfix smtp(8) client normally does
+not wait for the server's reply to the QUIT command, and it never
+waits for the TCP final handshake to complete. </p>
+
+<li> <p> SMTP Connection caching introduces some overhead: the
+client needs to send an RSET command to find out if a connection
+is still usable, before it can send the next MAIL FROM command.
+This introduces one additional round-trip delay. </p>
+
+</ul>
+
+<p> For other potential issues with SMTP connection caching, see
+the discussion of <a href="#limitations">limitations</a> at the end
+of this document. </p>
+
+<h2><a name="implementation">Connection cache implementation</a></h2>
+
+<p> For an overview of how Postfix delivers mail, see the Postfix
+architecture OVERVIEW document. </p>
+
+<p> The Postfix connection cache is shared among Postfix mail
+delivering processes. This maximizes the opportunity to reuse an
+open connection. Some MTAs such as Sendmail have a
+non-shared connection cache. Here, a connection can be reused only
+by the mail delivering process that creates the connection. To get
+the same performance improvement as with a shared connection cache,
+non-shared connections need to be kept open for a longer time. </p>
+
+<p> The scache(8) server, introduced with Postfix version 2.2,
+maintains the shared connection cache. With Postfix version 2.2,
+only the smtp(8) client has support to access this cache. </p>
+
+<p> When SMTP connection caching is enabled (see next section), the
+smtp(8) client does not disconnect after a mail transaction, but
+gives the connection to the scache(8) server which keeps the
+connection open for a limited amount of time. </p>
+
+<p> After handing over the open connection to the scache(8) server,
+the smtp(8) client continues with some other mail delivery request.
+Meanwhile, any smtp(8) client process can ask the scache(8) server
+for that cached connection and reuse it for mail delivery. </p>
+
+<blockquote>
+
+<table>
+
+<tr> <td> </td> <td> <tt> /-- </tt> </td> <td align="center"
+colspan="3" bgcolor="#f0f0ff"> smtp(8) </td> <td colspan="2"> <tt>
+--&gt; </tt> </td> <td> Internet </td> </tr>
+
+<tr> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> </td>
+<td align="center" rowspan="3"><tt>|<br>|<br>|<br>|<br>v</tt></td>
+</tr>
+
+<tr> <td> &nbsp; </td> <td> <tt> \-- </tt> </td> <td align="center"
+colspan="4" bgcolor="#f0f0ff"> smtp(8) </td> <td align="left">
+&nbsp; </td> </tr>
+
+<tr> <td colspan="2"> &nbsp; </td> <td> </td> <td
+align="center"><tt>^<br>|</tt></td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" colspan="3"
+bgcolor="#f0f0ff"> scache(8) </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> With TLS connection reuse (Postfix 3.4 and later), the Postfix
+smtp(8) client connects to a remote SMTP server and sends plaintext
+EHLO and STARTTLS commands, then inserts a tlsproxy(8) process into
+the connection as shown below. </p>
+
+<p> After delivering mail, the smtp(8) client hands over the open
+smtp(8)-to-tlsproxy(8) connection to the scache(8) server, and
+continues with some other mail delivery request. Meanwhile, any
+smtp(8) client process can ask the scache(8) server for that cached
+connection and reuse it for mail delivery. </p>
+
+<blockquote>
+
+<table>
+
+<tr> <td> </td> <td> <tt> /-- </tt> </td> <td align="center"
+colspan="3" bgcolor="#f0f0ff"> smtp(8) </td> <td colspan="2"> <tt>
+--&gt; </tt> </td> <td align="center"bgcolor="#f0f0ff"> tlsproxy(8)
+</td> <td> <tt> --&gt; </tt> </td> <td> Internet </td> </tr>
+
+<tr> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> </td>
+<td align="center" rowspan="3"><tt>|<br>|<br>|<br>|<br>v</tt></td>
+</tr>
+
+<tr> <td> &nbsp; </td> <td> <tt> \-- </tt> </td> <td align="center"
+colspan="4" bgcolor="#f0f0ff"> smtp(8) </td> <td align="left">
+&nbsp; </td> </tr>
+
+<tr> <td colspan="2"> &nbsp; </td> <td> </td> <td
+align="center"><tt>^<br>|</tt></td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" colspan="3"
+bgcolor="#f0f0ff"> scache(8) </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> The connection cache can be searched by destination domain name
+(the right-hand side of the recipient address) and by the IP address
+of the host at the other end of the connection. This allows Postfix
+to reuse a connection even when the remote host is a mail server for
+domains with different names. </p>
+
+<h2><a name="configuration">Connection cache configuration </a></h2>
+
+<p> The Postfix smtp(8) client supports two connection caching
+strategies: </p>
+
+<ul>
+
+<li> <p> On-demand connection caching. This is enabled by default,
+and is controlled with the smtp_connection_cache_on_demand configuration
+parameter. When this feature is enabled, the Postfix smtp(8) client
+automatically saves a connection to the connection cache when a
+destination has a high volume of mail in the active queue. </p>
+
+<p> Example: </p>
+
+<blockquote>
+
+<pre>
+/etc/postfix/main.cf:
+ smtp_connection_cache_on_demand = yes
+</pre>
+
+</blockquote>
+
+<li> <p> Per-destination connection caching. This is enabled by
+explicitly listing specific destinations with the
+smtp_connection_cache_destinations configuration parameter. After
+completing delivery to a selected destination, the Postfix smtp(8)
+client <i>always</i> saves the connection to the connection cache.
+</p>
+
+<p> Specify a comma or white space separated list of destinations
+or pseudo-destinations: </p>
+
+<ul>
+
+<li> <p> if mail is sent without a relay host: a domain name (the
+right-hand side of an email address, without the [] around a numeric
+IP address), </p>
+
+<li> <p> if mail is sent via a relay host: a relay host name (without
+the [] or non-default TCP port), as specified in main.cf or in the
+transport map, </p>
+
+<li> <p> a /file/name with domain names and/or relay host names as
+defined above, </p>
+
+<li> <p> a "type:table" with domain names and/or relay host names
+on the left-hand side. The right-hand side result from "type:table"
+lookups is ignored. </p>
+
+</ul>
+
+<p> Examples: </p>
+
+<blockquote>
+
+<pre>
+/etc/postfix/main.cf:
+ smtp_connection_cache_destinations = $relayhost
+ smtp_connection_cache_destinations = hotmail.com, ...
+ smtp_connection_cache_destinations = static:all (<i>not recommended</i>)
+</pre>
+
+</blockquote>
+
+<p> See <a href="TLS_README.html#client_tls_reuse">Client-side TLS
+connection reuse</a> to enable multiple deliveries over a TLS-encrypted
+connection (Postfix version 3.4 and later). </p>
+
+</ul>
+
+<h2><a name="safety">Connection cache safety mechanisms </a></h2>
+
+<p> Connection caching must be used wisely. It is anti-social to
+keep an unused SMTP connection open for a significant amount of
+time, and it is unwise to send huge numbers of messages through
+the same connection. In order to avoid problems with SMTP connection
+caching, Postfix implements the following safety mechanisms: </p>
+
+<ul>
+
+<li> <p> The Postfix scache(8) server keeps a connection open for
+only a limited time. The time limit is specified with the
+smtp_connection_cache_time_limit and with the connection_cache_ttl_limit
+configuration parameters. This prevents anti-social behavior. </p>
+
+<li> <p> The Postfix smtp(8) client reuses a session for only a
+limited number of times. This avoids triggering bugs in implementations
+that do not correctly handle multiple deliveries per session. </p>
+
+<p> As of Postfix 2.3 connection reuse is preferably limited with
+the smtp_connection_reuse_time_limit parameter. In addition, Postfix
+2.11 provides smtp_connection_reuse_count_limit to limit how many
+times a connection may be reused, but this feature is unsafe as it
+introduces a "fatal attractor" failure mode (when a destination has
+multiple inbound MTAs, the slowest inbound MTA will attract most
+connections from Postfix to that destination). </p>
+
+<p> Postfix 2.3 logs the use count of multiply-used connections,
+as shown in the following example: </p>
+
+<blockquote>
+<pre>
+Nov 3 16:04:31 myname postfix/smtp[30840]: 19B6B2900FE:
+to=&lt;wietse@test.example.com&gt;, orig_to=&lt;wietse@test&gt;,
+relay=mail.example.com[1.2.3.4], <b>conn_use=2</b>, delay=0.22,
+delays=0.04/0.01/0.05/0.1, dsn=2.0.0, status=sent (250 2.0.0 Ok)
+</pre>
+</blockquote>
+
+<li> <p> The connection cache explicitly labels each cached connection
+with destination domain and IP address information. A connection
+cache lookup succeeds only when the correct information is specified.
+This prevents mis-delivery of mail. </p>
+
+</ul>
+
+<h2><a name="limitations">Connection cache limitations</a></h2>
+
+<p> Postfix SMTP connection caching conflicts with certain applications:
+</p>
+
+<ul>
+
+<li> <p> With Postfix versions &lt; 3.4, the Postfix shared connection
+cache cannot be used with TLS, because an open TLS connection can
+be reused only in the process that creates it. For this reason,
+the Postfix smtp(8) client historically always closed the connection
+after completing an attempt to deliver mail over TLS.</p>
+
+<li> <p> Postfix connection caching currently does not support
+multiple SASL accounts per mail server. Specifically, Postfix
+connection caching assumes that a SASL credential is valid for all
+hostnames or domain names that deliver via the same mail server IP
+address and TCP port, and assumes that the SASL credential does not
+depend on the message originator. </p>
+
+</ul>
+
+
+<h2><a name="statistics">Connection cache statistics </a></h2>
+
+<p> The scache(8) connection cache server logs statistics about the
+peak cache size and the cache hit rates. This information is logged
+every connection_cache_status_update_time seconds, when the process
+terminates after the maximal idle time is exceeded, or when Postfix
+is reloaded. </p>
+
+<ul>
+
+<li> <p> Hit rates for connection cache lookups by domain will tell
+you how useful connection caching is. </p>
+
+<li> <p> Connection cache lookups by network address will always
+fail, unless you're sending mail to different domains that share
+the same MX hosts. </p>
+
+<li> <p> No statistics are logged when no attempts are made to
+access the connection cache. </p>
+
+</ul>
+
+
+</body>
+
+</html>
diff --git a/proto/CONTENT_INSPECTION_README.html b/proto/CONTENT_INSPECTION_README.html
new file mode 100644
index 0000000..57d4836
--- /dev/null
+++ b/proto/CONTENT_INSPECTION_README.html
@@ -0,0 +1,92 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Content Inspection </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Content Inspection </h1>
+
+<hr>
+
+<p> Postfix supports three content inspection methods, ranging from
+light-weight one-line-at-a-time scanning before mail is queued, to
+heavy duty machinery that does sophisticated content analysis after
+mail is queued. Each approach serves a different purpose. </p>
+
+<dl>
+
+<dt> <b> before queue, built-in, light-weight</b> </dt>
+
+<dd> <p> This method inspects mail BEFORE it is stored in the queue,
+and uses Postfix's built-in message header and message body
+inspection. Although the main purpose is to stop a specific flood
+of mail from worms or viruses, it is also useful to block a flood
+of bounced junk email and email notifications from virus detection
+systems. The built-in regular expressions are not meant to implement
+general SPAM and virus detection. For that, you should use one of
+the content inspection methods described below. Details are described
+in the BUILTIN_FILTER_README and BACKSCATTER_README documents.
+</p>
+
+<dt> <b> after queue, external, heavy-weight</b> </dt>
+
+<dd> <p> This method inspects mail AFTER it is stored in the queue,
+and uses standard protocols such as SMTP or "pipe to command and
+wait for exit status". After-queue inspection allows you to use
+content filters of arbitrary complexity without causing timeouts
+while receiving mail, and without running out of memory resources
+under a peak load. Details of this approach are in the FILTER_README
+document. </p>
+
+<dt> <b> before queue, external, medium-weight</b> </dt>
+
+<dd> <p> The following two methods inspect mail BEFORE it is stored in the
+queue. </p>
+
+<ul>
+
+<li> <p> The first method uses the SMTP protocol, and is described
+in the SMTPD_PROXY_README document. This approach is available
+with Postfix version 2.1 and later. </p>
+
+<li> <p> The second method uses the Sendmail 8 Milter protocol, and
+is described in the MILTER_README document. This approach is
+available with Postfix version 2.3 and later. </p>
+
+</ul>
+
+<p> Although these approaches appear to be attractive, they have
+some serious limitations that you need to be aware of. First,
+content inspection software must finish in a limited amount of time;
+if content inspection needs too much time then incoming mail
+deliveries will time out. Second, content inspection software must
+run in a limited amount of memory; if content inspection needs too
+much memory then software will crash under a peak load. Before-queue
+inspection limits the peak load that your system can handle, and
+limits the sophistication of the content filter that you can use.
+</p>
+
+</dl>
+
+<p> The more sophisticated content filtering software is not built
+into Postfix for good reasons: writing an MTA requires different
+skills than writing a SPAM or virus killer. Postfix encourages the
+use of external filters and standard protocols because this allows
+you to choose the best MTA and the best content inspection software
+for your purpose. Information about external content inspection
+software can be found on the Postfix website at http://www.postfix.org/,
+and on the postfix-users@postfix.org mailing list. </p>
+
+</body>
+
+</html>
diff --git a/proto/DATABASE_README.html b/proto/DATABASE_README.html
new file mode 100644
index 0000000..1db3372
--- /dev/null
+++ b/proto/DATABASE_README.html
@@ -0,0 +1,497 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Lookup Table Overview</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Lookup Table Overview</h1>
+
+<hr>
+
+<h2>Overview </h2>
+
+This document covers the following topics:
+
+<ul>
+
+<li><a href="#intro">The Postfix lookup table model</a>
+
+<li><a href="#lists">Postfix lists versus tables </a>
+
+<li><a href="#preparing">Preparing Postfix for LDAP or SQL lookups</a>
+
+<li><a href="#detect">Maintaining Postfix lookup table files</a>
+
+<li><a href="#safe_db">Updating Berkeley DB files safely</a>
+
+<li><a href="#types">Postfix lookup table types</a>
+
+</ul>
+
+<h2><a name="intro">The Postfix lookup table model</a></h2>
+
+<p> Postfix uses lookup tables to store and look up information
+for access control, address rewriting and even for content filtering.
+All Postfix lookup tables are specified as "type:table", where
+"type" is one of the database types described under "<a
+href="#types">Postfix lookup table types</a>" at the end of this
+document, and where "table" is the lookup table name. The Postfix
+documentation uses the terms "database" and "lookup table" for the
+same thing. </p>
+
+<p> Examples of lookup tables that appear often in the Postfix
+documentation: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ alias_maps = hash:/etc/postfix/aliases (local aliasing)
+ header_checks = regexp:/etc/postfix/header_checks (content filtering)
+ transport_maps = hash:/etc/postfix/transport (routing table)
+ virtual_alias_maps = hash:/etc/postfix/virtual (address rewriting)
+</pre>
+</blockquote>
+
+<p> All Postfix lookup tables store information as (key, value)
+pairs. This interface may seem simplistic at first, but it turns
+out to be very powerful. The (key, value) query interface completely
+hides the complexities of LDAP or SQL from Postfix. This is a good
+example of connecting complex systems with simple interfaces. </p>
+
+<p> Benefits of the Postfix (key, value) query interface:</p>
+
+<ul>
+
+<li> You can implement Postfix lookup tables first with local
+Berkeley DB files and then switch to LDAP or MySQL without any
+impact on the Postfix configuration itself, as described under "<a
+href="#preparing">Preparing Postfix for LDAP or SQL lookups</a>"
+below.
+
+<li> You can use Berkeley DB files with fixed lookup strings for
+simple address rewriting operations and you can use regular expression
+tables for the more complicated work. In other words, you don't
+have to put everything into the same table.
+
+</ul>
+
+<h2><a name="lists">Postfix lists versus tables </a></h2>
+
+<p> Most Postfix lookup tables are used to look up information.
+Examples are address rewriting (the lookup string is the old address,
+and the result is the new address) or access control (the lookup
+string is the client, sender or recipient, and the result is an
+action such as "reject"). </p>
+
+<p> With some tables, however, Postfix needs to know only if the
+lookup key exists. Any non-empty lookup result value may be used
+here: the lookup result is not used. Examples
+are the local_recipient_maps that determine what local recipients
+Postfix accepts in mail from the network, the mydestination parameter
+that specifies what domains Postfix delivers locally for, or the
+mynetworks parameter that specifies the IP addresses of trusted
+clients or client networks. Technically, these are lists, not
+tables. Despite the difference, Postfix lists are described here
+because they use the same underlying infrastructure as Postfix
+lookup tables. </p>
+
+<h2><a name="preparing">Preparing Postfix for LDAP or SQL lookups</a>
+</h2>
+
+<p> LDAP and SQL are complex systems. Trying to set up both Postfix
+and LDAP or SQL at the same time is definitely not a good idea.
+You can save yourself a lot of time by implementing Postfix first
+with local files such as Berkeley DB. Local files have few surprises,
+and are easy to debug with the postmap(1) command: </p>
+
+<blockquote>
+<pre>
+% <b>postmap -q info@example.com hash:/etc/postfix/virtual </b>
+</pre>
+</blockquote>
+
+<p> Once you have local files working properly you can follow the
+instructions in ldap_table(5), mysql_table(5), pgsql_table(5)
+or sqlite_table(5)
+and replace local file lookups with LDAP or SQL lookups. When you
+do this, you should use the postmap(1) command again, to verify
+that database lookups still produce the exact same results as local
+file lookup: </p>
+
+<blockquote>
+<pre>
+% <b>postmap -q info@example.com ldap:/etc/postfix/virtual.cf </b>
+</pre>
+</blockquote>
+
+<p> Be sure to exercise all the partial address or parent domain
+queries that are documented under "table search order" in the
+relevant manual page: access(5), canonical(5), virtual(5),
+transport(5), or under the relevant configuration parameter:
+mynetworks, relay_domains, parent_domain_matches_subdomains. </p>
+
+<h2><a name="detect">Maintaining Postfix lookup table files</a></h2>
+
+<p> When you make changes to a database while the mail system is
+running, it would be desirable if Postfix avoids reading information
+while that information is being changed. It would also be nice if
+you can change a database without having to execute "postfix reload",
+in order to force Postfix to use the new information. Each time
+you do "postfix reload" Postfix loses a lot of performance.
+</p>
+
+<ul>
+
+<li> <p> If you change a network database such as LDAP, NIS or
+SQL, there is no need to execute "postfix reload". The LDAP, NIS
+or SQL server takes care of read/write access conflicts and gives
+the new data to Postfix once that data is available. </p>
+
+<li> <p> If you change a regexp:, pcre:, cidr: or texthash: file
+then Postfix
+may not pick up the file changes immediately. This is because a
+Postfix process reads the entire file into memory once and never
+examines the file again. </p>
+
+<ul>
+
+<li> <p> If the file is used by a short-running process such as
+smtpd(8), cleanup(8) or local(8), there is no need to execute
+"postfix reload" after making a change. </p>
+
+<li> <p> If the file is being used by a long-running process such
+as trivial-rewrite(8) on a busy server it may be necessary to
+execute "postfix reload". </p>
+
+</ul>
+
+<li> <p> If you change a local file based database such as DBM or
+Berkeley DB, there is no need to execute "postfix reload". Postfix
+uses file locking to avoid read/write access conflicts, and whenever
+a Postfix daemon process notices that a file has changed it will
+terminate before handling the next client request, so that a new
+process can initialize with the new database. </p>
+
+</ul>
+
+<h2><a name="safe_db">Updating Berkeley DB files safely</a></h2>
+
+<p> Postfix uses file locking to avoid access conflicts while
+updating Berkeley DB or other local database files. This used to
+be safe, but as Berkeley DB has evolved to use more aggressive
+caching, file locking may no longer be sufficient. </p>
+
+<p> Furthermore, file locking would not prevent problems when the
+update fails because the disk is full or something else causes a
+database update to fail. In particular, commands such as postmap(1)
+or postalias(1) overwrite existing files. If the overwrite
+fails in the middle then you have no usable database, and Postfix
+will stop working. This is not an issue with the CDB database type
+available with Postfix 2.2 and later: <a href="CDB_README.html">CDB</a>
+creates a new file, and renames the file upon successful completion.
+</p>
+
+<p> With Berkeley DB and other "one file" databases, it is
+possible to add some extra robustness by using "mv" to REPLACE an
+existing database file instead of overwriting it: </p>
+
+<blockquote>
+<pre>
+# <b>postmap access.in &amp;&amp; mv access.in.db access.db</b>
+</pre>
+</blockquote>
+
+<p> This converts the input file "access.in" into the output file
+"access.in.db", and replaces the file "access.db" only when the
+postmap(1) command was successful. Of course typing such commands
+becomes boring quickly, and this is why people use "make" instead,
+as shown below. User input is shown in bold font. </p>
+
+<blockquote>
+<pre>
+# <b>cat Makefile</b>
+all: aliases.db access.db virtual.db ...etcetera...
+
+# Note 1: commands are specified after a TAB character.
+# Note 2: use postalias(1) for local aliases, postmap(1) for the rest.
+aliases.db: aliases.in
+ postalias aliases.in
+ mv aliases.in.db aliases.db
+
+access.db: access.in
+ postmap access.in
+ mv access.in.db access.db
+
+virtual.db: virtual.in
+ postmap virtual.in
+ mv virtual.in.db virtual.db
+
+...etcetera...
+# <b>vi access.in</b>
+...editing session not shown...
+# <b>make</b>
+postmap access.in
+mv access.in.db access.db
+#
+</pre>
+</blockquote>
+
+<p> The "make" command updates only the files that have changed.
+In case of error, the "make" command will stop and will not invoke
+the "mv" command, so that Postfix will keep using the existing
+database file as if nothing happened. </p>
+
+<h2><a name="types">Postfix lookup table types</a> </h2>
+
+<p> To find out what database types your Postfix system supports,
+use the "<b>postconf -m</b>" command. Here is a list of database types
+that are often supported: </p>
+
+<blockquote>
+
+<dl>
+
+<dt> <b>btree</b> </dt>
+
+<dd> A sorted, balanced tree structure. This is available only on
+systems with support for Berkeley DB databases. Database files are
+created with the postmap(1) or postalias(1) command. The lookup
+table name as used in "btree:table" is the database file name
+without the ".db" suffix. </dd>
+
+<dt> <b>cdb</b> </dt>
+
+<dd> A read-optimized structure with no support for incremental updates.
+Database files are created with the postmap(1) or postalias(1) command.
+The lookup table name as used in "cdb:table" is the database file name
+without the ".cdb" suffix. This feature is available with Postfix 2.2
+and later. </dd>
+
+<dt> <b>cidr</b> </dt>
+
+<dd> A table that associates values with Classless Inter-Domain
+Routing (CIDR) patterns. The table format is described in cidr_table(5).
+</dd>
+
+<dt> <b>dbm</b> </dt>
+
+<dd> An indexed file type based on hashing. This is available only
+on systems with support for DBM databases. Public database files
+are created with the postmap(1) or postalias(1) command, and private
+databases are maintained by Postfix daemons. The lookup table name
+as used in "dbm:table" is the database file name without the ".dir"
+or ".pag" suffix. </dd>
+
+<dt> <b>environ</b> </dt>
+
+<dd> The UNIX process environment array. The lookup key is the
+variable name. The lookup table name in "environ:table" is ignored.
+</dd>
+
+<dt> <b>fail</b> </dt>
+
+<dd> A table that reliably fails all requests. The lookup table
+name is used for logging only. This table exists to simplify Postfix
+error tests. </dd>
+
+<dt> <b>hash</b> </dt>
+
+<dd> An indexed file type based on hashing. This is available only
+on systems with support for Berkeley DB databases. Public database
+files are created with the postmap(1) or postalias(1) command, and
+private databases are maintained by Postfix daemons. The database
+name as used in "hash:table" is the database file name without the
+".db" suffix. </dd>
+
+<dt> <b>inline</b> (read-only) </dt>
+
+<dd> A non-shared, in-memory lookup table. Example: "inline:{
+<i>key=value</i>, { <i>key = text with whitespace or comma</i> }}".
+Key-value pairs are separated by whitespace or comma; with a key-value
+pair inside "{}", whitespace is ignored after the opening "{",
+around the "=" between key and value, and before the closing "}".
+Inline tables eliminate the
+need to create a database file for just a few fixed elements. See
+also the static: map type. </dd>
+
+<dt> <b>internal</b> </dt>
+
+<dd> A non-shared, in-memory hash table. Its contents are lost when
+a process terminates. </dd>
+
+<dt> <b>lmdb</b> </dt>
+
+<dd> OpenLDAP LMDB database. This is available only on systems
+with support for LMDB databases. Public database files are created
+with the postmap(1) or postalias(1) command, and private databases
+are maintained by Postfix daemons. The database name as used in
+"lmdb:table" is the database file name without the ".lmdb" suffix.
+See lmdb_table(5) for details. </dd>
+
+<dt> <b>ldap</b> (read-only) </dt>
+
+<dd> LDAP database client. Configuration details are given in the
+ldap_table(5). </dd>
+
+<dt> <b>memcache</b> </dt>
+
+<dd> Memcache database client. Configuration details are given in
+memcache_table(5). </dd>
+
+<dt> <b>mysql</b> (read-only) </dt>
+
+<dd> MySQL database client. Configuration details are given in
+mysql_table(5). </dd>
+
+<dt> <b>netinfo</b> (read-only) </dt>
+
+<dd> Netinfo database client. </dd>
+
+<dt> <b>nis</b> (read-only) </dt>
+
+<dd> NIS database client. </dd>
+
+<dt> <b>nisplus</b> (read-only) </dt>
+
+<dd> NIS+ database client. Configuration details are given in
+nisplus_table(5). </dd>
+
+<dt> <b>pcre</b> (read-only) </dt>
+
+<dd> A lookup table based on Perl Compatible Regular Expressions.
+The file format is described in pcre_table(5). The lookup table
+name as used in "pcre:table" is the name of the regular expression
+file. </dd>
+
+<dt> <b>pipemap</b> (read-only) </dt>
+
+<dd> A pipeline of lookup tables. Example:
+"pipemap:{<i>type<sub>1</sub>:name<sub>1</sub>, ...,
+type<sub>n</sub>:name<sub>n</sub></i>}". Each "pipemap:" query is
+given to the first table. Each lookup result becomes the query for
+the next table in the pipeline, and the last table produces the
+final result. When any table lookup produces no result, the pipeline
+produces no result. The first and last characters of the "pipemap:"
+table name must be "{" and "}". Within these, individual maps are
+separated with comma or whitespace. </dd>
+
+<dt> <b>pgsql</b> (read-only) </dt>
+
+<dd> PostgreSQL database client. Configuration details are given
+in pgsql_table(5). </dd>
+
+<dt> <b>proxy</b> </dt>
+
+<dd> Postfix proxymap(8) client for shared access to Postfix
+databases. The lookup table name syntax is "proxy:type:table".
+</dd>
+
+<dt> <b>randmap</b> (read-only) </dt>
+
+<dd> An in-memory table that performs random selection. Example:
+"randmap:{<i>result<sub>1</sub>. ..., result<sub>n</sub></i>}".
+Each table query returns a random choice from the specified results.
+The first and last characters of the "randmap:" table name must be
+"{" and "}". Within these, individual maps are separated with comma
+or whitespace. To give a specific result more weight, specify it
+multiple times. </dd>
+
+<dt> <b>regexp</b> (read-only) </dt>
+
+<dd> A lookup table based on regular expressions. The file format
+is described in regexp_table(5). The lookup table name as used in
+"regexp:table" is the name of the regular expression file. </dd>
+
+<dt> <b>sdbm</b> </dt>
+
+<dd> An indexed file type based on hashing. This is available only
+on systems with support for SDBM databases. Public database files
+are created with the postmap(1) or postalias(1) command, and private
+databases are maintained by Postfix daemons. The lookup table name
+as used in "sdbm:table" is the database file name without the ".dir"
+or ".pag" suffix. </dd>
+
+<dt> <b>socketmap</b> (read-only) </dt>
+
+<dd> Sendmail-style socketmap client. The name of the table is
+either <b>inet</b>:<i>host</i>:<i>port</i>:<i>name</i> for a TCP/IP
+server, or <b>unix</b>:<i>pathname</i>:<i>name</i> for a UNIX-domain
+server. See socketmap_table(5) for details. </dd>
+
+<dt> <b>sqlite</b> (read-only) </dt>
+
+<dd> SQLite database. Configuration details are given in sqlite_table(5).
+</dd>
+
+<dt> <b>static</b> (read-only) </dt>
+
+<dd> A table that always returns its name as the lookup result.
+For example, "static:foobar" always returns the string "foobar" as
+lookup result. Specify "static:{ <i>text with whitespace</i> }"
+when the result contains whitespace; this form ignores whitespace
+after the opening "{" and before the closing "}". See also the
+inline: map type. </dd>
+
+<dt> <b>tcp</b> </dt>
+
+<dd> TCP/IP client. The protocol is described in tcp_table(5). The
+lookup table name is "tcp:host:port" where "host" specifies a
+symbolic hostname or a numeric IP address, and "port" specifies a
+symbolic service name or a numeric port number. </dd>
+
+<dt> <b>texthash</b> (read-only) </dt>
+
+<dd> A table that produces similar results as hash: files, except
+that you don't have to run the postmap(1) command before you can
+use the file, and that texthash: does not detect changes after the
+file is read. The lookup table name is "texthash:filename", where
+the file name is taken literally; no suffix is appended. </dd>
+
+<dt> <b>unionmap</b> (read-only) </dt>
+
+<dd> A table that sends each query to multiple lookup tables and
+that concatenates all found results, separated by comma. The table
+name syntax is the same as for pipemap tables. </dd>
+
+<dt> <b>unix</b> (read-only) </dt>
+
+<dd> A limited view of the UNIX authentication database. The following
+tables are implemented:
+
+<dl>
+
+<dt> <b>unix:passwd.byname</b> </dt>
+
+<dd>The table is the UNIX password database. The key is a login
+name. The result is a password file entry in passwd(5) format.
+</dd>
+
+<dt> <b>unix:group.byname</b> </dt>
+
+<dd> The table is the UNIX group database. The key is a group name.
+The result is a group file entry in group(5) format. </dd>
+
+</dl> </dd>
+
+</dl>
+
+</blockquote>
+
+<p> Other lookup table types may be available depending on how
+Postfix was built. With some Postfix distributions the list is
+dynamically extensible as support for lookup tables is dynamically
+linked into Postfix. </p>
+
+</body>
+
+</html>
diff --git a/proto/DB_README.html b/proto/DB_README.html
new file mode 100644
index 0000000..cca3e2b
--- /dev/null
+++ b/proto/DB_README.html
@@ -0,0 +1,246 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Berkeley DB Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Berkeley DB Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> Postfix uses databases of various kinds to store and look up
+information. Postfix databases are specified as "type:name".
+Berkeley DB implements the Postfix database type "hash" and
+"btree". The name of a Postfix Berkeley DB database is the name
+of the database file without the ".db" suffix. Berkeley DB databases
+are maintained with the postmap(1) command. </p>
+
+<p> Note: Berkeley DB version 4 is not supported by Postfix versions
+before 2.0. </p>
+
+<p> This document describes: </p>
+
+<ol>
+
+<li> <p> How to build Postfix <a href="#disable_db">without Berkeley
+DB support</a> even if the system comes with Berkeley DB. </p>
+
+<li> <p> How to build Postfix on <a href="#no_db">systems that
+normally have no Berkeley DB library</a>. </p>
+
+<li> <p> How to build Postfix on <a href="#bsd">BSD</a> or <a
+href="#linux">Linux</a> systems with multiple Berkeley DB
+versions. </p>
+
+<li> <p> How to <a href="#tweak">tweak</a> performance. </p>
+
+<li> <p> Missing <a href="#pthread">pthread</a> library trouble. </p>
+
+</ol>
+
+<h2><a name="disable_db">Building Postfix without Berkeley
+DB support even if the system comes with Berkeley DB</a></h2>
+
+<p> Note: The following instructions apply to Postfix 2.9 and later. </p>
+
+<p> Postfix will normally enable Berkeley DB support if the system
+is known to have it. To build Postfix without Berkeley DB support,
+build the makefiles as follows: </p>
+
+<blockquote>
+<pre>
+% make makefiles CCARGS="-DNO_DB"
+% make
+</pre>
+</blockquote>
+
+<p> This will disable support for "hash" and "btree" files. </p>
+
+<h2><a name="no_db">Building Postfix on systems that normally have
+no Berkeley DB library</a></h2>
+
+<p> Some UNIXes ship without Berkeley DB support; for historical
+reasons these use DBM files instead. A problem with DBM files is
+that they can store only limited amounts of data. To build Postfix
+with
+Berkeley DB support you need to download and install the source
+code from http://www.oracle.com/database/berkeley-db/. </p>
+
+<p> Warning: some Linux system libraries use Berkeley DB, as do
+some third-party libraries such as SASL. If you compile Postfix
+with a different Berkeley DB implementation, then every Postfix
+program will dump core because either the system library, the SASL
+library, or Postfix itself ends up using the wrong version. </p>
+
+<p>The more recent Berkeley DB versions have a compile-time switch,
+"--with-uniquename", which renames the symbols so that multiple
+versions of Berkeley DB can co-exist in the same application.
+Although wasteful, this may be the only way to keep things from
+falling apart. </p>
+
+<p> To build Postfix after you installed the Berkeley DB from
+source code, use something like: </p>
+
+<blockquote>
+<pre>
+% make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB/include" \
+ AUXLIBS="-L/usr/local/BerkeleyDB/lib -ldb"
+% make
+</pre>
+</blockquote>
+
+<p> If your Berkeley DB shared library is in a directory that the RUN-TIME
+linker does not know about, add a "-Wl,-R,/path/to/directory" option after
+"-ldb". </p>
+
+<p> Solaris needs this: </p>
+
+<blockquote>
+<pre>
+% make makefiles CCARGS="-DHAS_DB -I/usr/local/BerkeleyDB/include" \
+ AUXLIBS="-R/usr/local/BerkeleyDB/lib -L/usr/local/BerkeleyDB/lib -ldb"
+% make
+</pre>
+</blockquote>
+
+<p> The exact pathnames depend on the Berkeley DB version, and on
+how it was installed. </p>
+
+<p> Warning: the file format produced by Berkeley DB version 1 is
+not compatible with that of versions 2 and 3 (versions 2 and 3 have
+the same format). If you switch between DB versions, then you may
+have to rebuild all your Postfix DB files. </p>
+
+<p> Warning: if you use Berkeley DB version 2 or later, do not
+enable DB 1.85 compatibility mode. Doing so would break fcntl file
+locking. </p>
+
+<p> Warning: if you use Perl to manipulate Postfix's Berkeley DB
+files, then you need to use the same Berkeley DB version in Perl
+as in Postfix. </p>
+
+<h2><a name="bsd">Building Postfix on BSD systems with multiple
+Berkeley DB versions</a></h2>
+
+<p> Some BSD systems ship with multiple Berkeley DB implementations.
+Normally, Postfix builds with the default DB version that ships
+with the system. </p>
+
+<p> To build Postfix on BSD systems with a non-default DB version,
+use a variant of the following commands: </p>
+
+<blockquote>
+<pre>
+% make makefiles CCARGS=-I/usr/include/db3 AUXLIBS=-ldb3
+% make
+</pre>
+</blockquote>
+
+<p> Warning: the file format produced by Berkeley DB version 1 is
+not compatible with that of versions 2 and 3 (versions 2 and 3 have
+the same format). If you switch between DB versions, then you may
+have to rebuild all your Postfix DB files. </p>
+
+<p> Warning: if you use Berkeley DB version 2 or later, do not
+enable DB 1.85 compatibility mode. Doing so would break fcntl file
+locking. </p>
+
+<p> Warning: if you use Perl to manipulate Postfix's Berkeley DB
+files, then you need to use the same Berkeley DB version in Perl
+as in Postfix. </p>
+
+<h2><a name="linux">Building Postfix on Linux systems with multiple
+Berkeley DB versions</a></h2>
+
+<p> Some Linux systems ship with multiple Berkeley DB implementations.
+Normally, Postfix builds with the default DB version that ships
+with the system. </p>
+
+<p> Warning: some Linux system libraries use Berkeley DB. If you
+compile Postfix with a non-default Berkeley DB implementation, then
+every Postfix program will dump core because either the system
+library or Postfix itself ends up using the wrong version. </p>
+
+<p> On Linux, you need to edit the makedefs script in order to
+specify a non-default DB library. The reason is that the location
+of the default db.h include file changes randomly between vendors
+and between versions, so that Postfix has to choose the file for
+you. </p>
+
+<p> Warning: the file format produced by Berkeley DB version 1 is
+not compatible with that of versions 2 and 3 (versions 2 and 3 have
+the same format). If you switch between DB versions, then you may
+have to rebuild all your Postfix DB files. </p>
+
+<p> Warning: if you use Berkeley DB version 2 or later, do not
+enable DB 1.85 compatibility mode. Doing so would break fcntl file
+locking. </p>
+
+<p> Warning: if you use Perl to manipulate Postfix's Berkeley DB
+files, then you need to use the same Berkeley DB version in Perl
+as in Postfix. </p>
+
+<h2><a name="tweak">Tweaking performance</a></h2>
+
+<p> Postfix provides two configuration parameters that control how
+much buffering memory Berkeley DB will use. </p>
+
+<ul>
+
+<li> <p> berkeley_db_create_buffer_size (default: 16 MBytes per
+table). This setting is used by the commands that maintain Berkeley
+DB files: postalias(1) and postmap(1). For "hash" files, create
+performance degrades rapidly unless the memory pool is O(file size).
+For "btree" files, create performance is good with sorted input even
+for small memory pools, but with random input degrades rapidly
+unless the memory pool is O(file size). </p>
+
+<li> <p> berkeley_db_read_buffer_size (default: 128 kBytes per
+table). This setting is used by all other Postfix programs. The
+buffer size is adequate for reading. If the cache is smaller than
+the table, random read performance is hardly cache size dependent,
+except with btree tables, where the cache size must be large enough
+to contain the entire path from the root node. Empirical evidence
+shows that 64 kBytes may be sufficient. We double the size to play
+safe, and to anticipate changes in implementation and bloat. </p>
+
+</ul>
+
+<h2><a name="pthread">Missing pthread library trouble</a></h2>
+
+<p> When building Postfix fails with: </p>
+
+<blockquote>
+<pre>
+undefined reference to `pthread_condattr_setpshared'
+undefined reference to `pthread_mutexattr_destroy'
+undefined reference to `pthread_mutexattr_init'
+undefined reference to `pthread_mutex_trylock'
+</pre>
+</blockquote>
+
+<p> Add the "-lpthread" library to the "make makefiles" command. </p>
+
+<blockquote>
+<pre>
+% make makefiles .... AUXLIBS="... -lpthread"
+</pre>
+</blockquote>
+
+<p> More information is available at
+http://www.oracle.com/database/berkeley-db/. </p>
+
+</body>
+
+</html>
diff --git a/proto/DEBUG_README.html b/proto/DEBUG_README.html
new file mode 100644
index 0000000..ea62cdc
--- /dev/null
+++ b/proto/DEBUG_README.html
@@ -0,0 +1,597 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title> Postfix Debugging Howto </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Debugging Howto</h1>
+
+<hr>
+
+<h2>Purpose of this document</h2>
+
+<p> This document describes how to debug parts of the Postfix mail
+system when things do not work according to expectation. The methods
+vary from making Postfix log a lot of detail, to running some daemon
+processes under control of a call tracer or debugger. </p>
+
+<p> The text assumes that the Postfix main.cf and master.cf
+configuration files are stored in directory /etc/postfix. You can
+use the command "<b>postconf config_directory</b>" to find out the
+actual location of this directory on your machine. </p>
+
+<p> Listed in order of increasing invasiveness, the debugging
+techniques are as follows: </p>
+
+<ul>
+
+<li><a href="#logging">Look for obvious signs of trouble</a>
+
+<li><a href="#trace_mail">Debugging Postfix from inside</a>
+
+<li><a href="#no_chroot">Try turning off chroot operation in
+master.cf</a>
+
+<li><a href="#debug_peer">Verbose logging for specific SMTP
+connections</a>
+
+<li><a href="#sniffer">Record the SMTP session with a network
+sniffer</a>
+
+<li><a href="#verbose">Making Postfix daemon programs more verbose</a>
+
+<li><a href="#man_trace">Manually tracing a Postfix daemon process</a>
+
+<li><a href="#auto_trace">Automatically tracing a Postfix daemon
+process</a>
+
+<li><a href="#ddd">Running daemon programs with the interactive
+ddd debugger</a>
+
+<li><a href="#screen">Running daemon programs with the interactive
+gdb debugger</a>
+
+<li><a href="#gdb">Running daemon programs under a non-interactive
+debugger</a>
+
+<li><a href="#unreasonable">Unreasonable behavior</a>
+
+<li><a href="#mail">Reporting problems to postfix-users@postfix.org</a>
+
+</ul>
+
+<h2><a name="logging">Look for obvious signs of trouble</a></h2>
+
+<p> Postfix logs all failed and successful deliveries to a logfile. </p>
+
+<ul>
+
+<li> <p> When Postfix uses syslog logging (the default), the file
+is usually called /var/log/maillog, /var/log/mail, or something
+similar; the exact pathname is configured in a file called
+/etc/syslog.conf, /etc/rsyslog.conf, or something similar. </p>
+
+<li> <p> When Postfix uses its own logging system (see MAILLOG_README),
+the location of the logfile is configured with the Postfix maillog_file
+parameter. </p>
+
+</ul>
+
+<p> When Postfix does not receive or deliver mail, the first order
+of business is to look for errors that prevent Postfix from working
+properly: </p>
+
+<blockquote>
+<pre>
+% <b>egrep '(warning|error|fatal|panic):' /some/log/file | more</b>
+</pre>
+</blockquote>
+
+<p> Note: the most important message is near the BEGINNING of the
+output. Error messages that come later are less useful. </p>
+
+<p> The nature of each problem is indicated as follows: </p>
+
+<ul>
+
+<li> <p> "<b>panic</b>" indicates a problem in the software itself
+that only a programmer can fix. Postfix cannot proceed until this
+is fixed. </p>
+
+<li> <p> "<b>fatal</b>" is the result of missing files, incorrect
+permissions, incorrect configuration file settings that you can
+fix. Postfix cannot proceed until this is fixed. </p>
+
+<li> <p> "<b>error</b>" reports an error condition. For safety
+reasons, a Postfix process will terminate when more than 13 of these
+happen. </p>
+
+<li> <p> "<b>warning</b>" indicates a non-fatal error. These are
+problems that you may not be able to fix (such as a broken DNS
+server elsewhere on the network) but may also indicate local
+configuration errors that could become a problem later. </p>
+
+</ul>
+
+<h2><a name="trace_mail">Debugging Postfix from inside</a> </h2>
+
+<p> Postfix version 2.1 and later can
+produce mail delivery reports for debugging purposes. These reports
+not only show sender/recipient addresses after address rewriting
+and alias expansion or forwarding, they also show information about
+delivery to mailbox, delivery to non-Postfix command, responses
+from remote SMTP servers, and so on.
+</p>
+
+<p> Postfix can produce two types of mail delivery reports for
+debugging: </p>
+
+<ul>
+
+<li> <p> What-if: report what would happen, but do not actually
+deliver mail. This mode of operation is requested with: </p>
+
+<pre>
+% <b>/usr/sbin/sendmail -bv address...</b>
+Mail Delivery Status Report will be mailed to &lt;your login name&gt;.
+</pre>
+
+<li> <p> What happened: deliver mail and report successes and/or
+failures, including replies from remote SMTP servers. This mode
+of operation is requested with: </p>
+
+<pre>
+% <b>/usr/sbin/sendmail -v address...</b>
+Mail Delivery Status Report will be mailed to &lt;your login name&gt;.
+</pre>
+
+</ul>
+
+<p> These reports contain information that is generated by Postfix
+delivery agents. Since these run as daemon processes that cannot
+interact with users directly, the result is sent as mail to the
+sender of the test message. The format of these reports is practically
+identical to that of ordinary non-delivery notifications. </p>
+
+<p> For a detailed example of a mail delivery status report, see
+the <a href="ADDRESS_REWRITING_README.html#debugging"> debugging</a>
+section at the end of the ADDRESS_REWRITING_README document. </p>
+
+<h2><a name="no_chroot">Try turning off chroot operation in master.cf</a></h2>
+
+<p> A common mistake is to turn on chroot operation in the master.cf
+file without going through all the necessary steps to set up a
+chroot environment. This causes Postfix daemon processes to fail
+due to all kinds of missing files. </p>
+
+<p> The example below shows an SMTP server that is configured with
+chroot turned off: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ # =============================================================
+ # service type private unpriv <b>chroot</b> wakeup maxproc command
+ # (yes) (yes) <b>(yes)</b> (never) (100)
+ # =============================================================
+ smtp inet n - <b>n</b> - - smtpd
+</pre>
+</blockquote>
+
+<p> Inspect master.cf for any processes that have chroot operation
+not turned off. If you find any, save a copy of the master.cf file,
+and edit the entries in question. After executing the command
+"<b>postfix reload</b>", see if the problem has gone away. </p>
+
+<p> If turning off chrooted operation made the problem go away,
+then congratulations. Leaving Postfix running in this way is
+adequate for most sites. If you prefer chrooted operation, see
+the Postfix <a href="BASIC_CONFIGURATION_README.html#chroot_setup">
+BASIC_CONFIGURATION_README</a> file for information about how to
+prepare Postfix for chrooted operation. </p>
+
+<h2><a name="debug_peer">Verbose logging for specific SMTP
+connections</a></h2>
+
+<p> In /etc/postfix/main.cf, list the remote site name or address
+in the debug_peer_list parameter. For example, in order to make
+the software log a lot of information to the syslog daemon for
+connections from or to the loopback interface: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ debug_peer_list = 127.0.0.1
+</pre>
+</blockquote>
+
+<p> You can specify one or more hosts, domains, addresses or
+net/masks. To make the change effective immediately, execute the
+command "<b>postfix reload</b>". </p>
+
+<h2><a name="sniffer">Record the SMTP session with a network sniffer</a></h2>
+
+<p> This example uses <b>tcpdump</b>. In order to record a conversation
+you need to specify a large enough buffer with the "<b>-s</b>"
+option or else you will miss some or all of the packet payload.
+</p>
+
+<blockquote>
+<pre>
+# <b>tcpdump -w /file/name -s 0 host example.com and port 25</b>
+</pre>
+</blockquote>
+
+<p> Older tcpdump versions don't support "<b>-s 0</b>"; in that case,
+use "<b>-s 2000</b>" instead. </p>
+
+<p> Run this for a while, stop with Ctrl-C when done. To view the
+data use a binary viewer, <b>ethereal</b>, or good old <b>less</b>.
+</p>
+
+<h2><a name="verbose">Making Postfix daemon programs more verbose</a></h2>
+
+<p> Append one or more "<b>-v</b>" options to selected daemon
+definitions in /etc/postfix/master.cf and type "<b>postfix reload</b>".
+This will cause a lot of activity to be logged to the syslog daemon.
+For example, to make the Postfix SMTP server process more verbose: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - - smtpd -v
+</pre>
+</blockquote>
+
+<p> To diagnose problems with address rewriting specify a "<b>-v</b>"
+option for the cleanup(8) and/or trivial-rewrite(8) daemon, and to
+diagnose problems with mail delivery specify a "<b>-v</b>"
+option for the qmgr(8) or oqmgr(8) queue manager, or for the lmtp(8),
+local(8), pipe(8), smtp(8), or virtual(8) delivery agent. </p>
+
+<h2><a name="man_trace">Manually tracing a Postfix daemon process</a></h2>
+
+<p> Many systems allow you to inspect a running process with a
+system call tracer. For example: </p>
+
+<blockquote>
+<pre>
+# <b>trace -p process-id</b> (SunOS 4)
+# <b>strace -p process-id</b> (Linux and many others)
+# <b>truss -p process-id</b> (Solaris, FreeBSD)
+# <b>ktrace -p process-id</b> (generic 4.4BSD)
+</pre>
+</blockquote>
+
+<p> Even more informative are traces of system library calls.
+Examples: </p>
+
+<blockquote>
+<pre>
+# <b>ltrace -p process-id</b> (Linux, also ported to FreeBSD and BSD/OS)
+# <b>sotruss -p process-id</b> (Solaris)
+</pre>
+</blockquote>
+
+<p> See your system documentation for details. </p>
+
+<p> Tracing a running process can give valuable information about
+what a process is attempting to do. This is as much information as
+you can get without running an interactive debugger program, as
+described in a later section. </p>
+
+<h2><a name="auto_trace">Automatically tracing a Postfix daemon
+process</a></h2>
+
+<p> Postfix can attach a call tracer whenever a daemon process
+starts. Call tracers come in several kinds. </p>
+
+<ol>
+
+<li> <p> System call tracers such as <b>trace</b>, <b>truss</b>,
+<b>strace</b>, or <b>ktrace</b>. These show the communication
+between the process and the kernel. </p>
+
+<li> <p> Library call tracers such as <b>sotruss</b> and <b>ltrace</b>.
+These show calls of library routines, and give a better idea of
+what is going on within the process. </p>
+
+</ol>
+
+<p> Append a <b>-D</b> option to the suspect command in
+/etc/postfix/master.cf, for example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - - smtpd -D
+</pre>
+</blockquote>
+
+<p> Edit the debugger_command definition in /etc/postfix/main.cf
+so that it invokes the call tracer of your choice, for example:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ debugger_command =
+ PATH=/bin:/usr/bin:/usr/local/bin;
+ (truss -p $process_id 2&gt;&amp;1 | logger -p mail.info) &amp; sleep 5
+</pre>
+</blockquote>
+
+<p> Type "<b>postfix reload</b>" and watch the logfile. </p>
+
+<h2><a name="ddd">Running daemon programs with the interactive
+ddd debugger</a></h2>
+
+<p> If you have X Windows installed on the Postfix machine, then
+an interactive debugger such as <b>ddd</b> can be convenient.
+</p>
+
+<p> Edit the debugger_command definition in /etc/postfix/main.cf
+so that it invokes <b>ddd</b>: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ debugger_command =
+ PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
+ ddd $daemon_directory/$process_name $process_id &amp; sleep 5
+</pre>
+</blockquote>
+
+<p> Be sure that <b>gdb</b> is in the command search path, and
+export <b>XAUTHORITY</b> so that X access control works, for example:
+</p>
+
+<blockquote>
+<pre>
+% <b>setenv XAUTHORITY ~/.Xauthority</b> (csh syntax)
+$ <b>export XAUTHORITY=$HOME/.Xauthority</b> (sh syntax)
+</pre>
+</blockquote>
+
+<p> Append a <b>-D</b> option to the suspect daemon definition in
+/etc/postfix/master.cf, for example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - - smtpd -D
+</pre>
+</blockquote>
+
+<p> Stop and start the Postfix system. This is necessary so that
+Postfix runs with the proper <b>XAUTHORITY</b> and <b>DISPLAY</b>
+settings. </p>
+
+<p> Whenever the suspect daemon process is started, a debugger
+window pops up and you can watch in detail what happens. </p>
+
+<h2><a name="screen">Running daemon programs with the interactive
+gdb debugger</a></h2>
+
+<p> If you have the screen command installed on the Postfix machine, then
+you can run an interactive debugger such as <b>gdb</b> as follows. </p>
+
+<p> Edit the debugger_command definition in /etc/postfix/main.cf
+so that it runs <b>gdb</b> inside a detached <b>screen</b> session:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ debugger_command =
+ PATH=/bin:/usr/bin:/sbin:/usr/sbin; export PATH; HOME=/root;
+ export HOME; screen -e^tt -dmS $process_name gdb
+ $daemon_directory/$process_name $process_id &amp; sleep 2
+</pre>
+</blockquote>
+
+<p> Be sure that <b>gdb</b> is in the command search path. </p>
+
+<p> Append a <b>-D</b> option to the suspect daemon definition in
+/etc/postfix/master.cf, for example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - - smtpd -D
+</pre>
+</blockquote>
+
+<p> Execute the command "<b>postfix reload</b>" and wait until a
+daemon process is started (you can see this in the maillog file).
+</p>
+
+<p> Then attach to the screen, and debug away: </p>
+
+<blockquote>
+<pre>
+# HOME=/root screen -r
+gdb) continue
+gdb) where
+</pre>
+</blockquote>
+
+<h2><a name="gdb">Running daemon programs under a non-interactive
+debugger</a></h2>
+
+<p> If you do not have X Windows installed on the Postfix machine,
+or if you are not familiar with interactive debuggers, then you
+can try to run <b>gdb</b> in non-interactive mode, and have it
+print a stack trace when the process crashes. </p>
+
+<p> Edit the debugger_command definition in /etc/postfix/main.cf
+so that it invokes the <b>gdb</b> debugger: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ debugger_command =
+ PATH=/bin:/usr/bin:/usr/local/bin; export PATH; (echo cont; echo
+ where; sleep 8640000) | gdb $daemon_directory/$process_name
+ $process_id 2&gt&amp;1
+ &gt;$config_directory/$process_name.$process_id.log &amp; sleep 5
+</pre>
+</blockquote>
+
+<p> Append a <b>-D</b> option to the suspect daemon in
+/etc/postfix/master.cf, for example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - - smtpd -D
+</pre>
+</blockquote>
+
+<p> Type "<b>postfix reload</b>" to make the configuration changes
+effective. </p>
+
+<p> Whenever a suspect daemon process is started, an output file
+is created, named after the daemon and process ID (for example,
+smtpd.12345.log). When the process crashes, a stack trace (with
+output from the "<b>where</b>" command) is written to its logfile.
+</p>
+
+<h2><a name="unreasonable">Unreasonable behavior</a></h2>
+
+<p> Sometimes the behavior exhibited by Postfix just does not match the
+source code. Why can a program deviate from the instructions given
+by its author? There are two possibilities. </p>
+
+<ul>
+
+<li> <p> The compiler has erred. This rarely happens. </p>
+
+<li> <p> The hardware has erred. Does the machine have ECC memory? </p>
+
+</ul>
+
+<p> In both cases, the program being executed is not the program
+that was supposed to be executed, so anything could happen. </p>
+
+<p> There is a third possibility: </p>
+
+<ul>
+
+<li> <p> Bugs in system software (kernel or libraries). </p>
+
+</ul>
+
+<p> Hardware-related failures usually do not reproduce in exactly
+the same way after power cycling and rebooting the system. There's
+little Postfix can do about bad hardware. Be sure to use hardware
+that at the very least can detect memory errors. Otherwise, Postfix
+will just be waiting to be hit by a bit error. Critical systems
+deserve real hardware. </p>
+
+<p> When a compiler makes an error, the problem can be reproduced
+whenever the resulting program is run. Compiler errors are most
+likely to happen in the code optimizer. If a problem is reproducible
+across power cycles and system reboots, it can be worthwhile to
+rebuild Postfix with optimization disabled, and to see if optimization
+makes a difference. </p>
+
+<p> In order to compile Postfix with optimizations turned off: </p>
+
+<blockquote>
+<pre>
+% <b>make tidy</b>
+% <b>make makefiles OPT=</b>
+</pre>
+</blockquote>
+
+<p> This produces a set of Makefiles that do not request compiler
+optimization. </p>
+
+<p> Once the makefiles are set up, build the software: </p>
+
+<blockquote>
+<pre>
+% <b>make</b>
+% <b>su</b>
+Password:
+# <b>make install</b>
+</pre>
+</blockquote>
+
+<p> If the problem goes away, then it is time to ask your vendor
+for help. </p>
+
+<h2><a name="mail">Reporting problems to postfix-users@postfix.org</a></h2>
+
+<p> The people who participate on postfix-users@postfix.org
+are very helpful, especially if YOU provide them with sufficient
+information. Remember, these volunteers are willing to help, but
+their time is limited. </p>
+
+<p> When reporting a problem, be sure to include the following
+information. </p>
+
+<ul>
+
+<li> <p> A summary of the problem. Please do not just send some
+logging without explanation of what YOU believe is wrong. </p>
+
+<li> <p> Complete error messages. Please use cut-and-paste, or use
+attachments, instead of reciting information from memory.
+</p>
+
+<li> <p> Postfix logging. See the text at the top of the DEBUG_README
+document to find out where logging is stored. Please do not frustrate
+the helpers by word wrapping the logging. If the logging is more
+than a few kbytes of text, consider posting an URL on a web or ftp
+site. </p>
+
+<li> <p> Consider using a test email address so that you don't have
+to reveal email addresses or passwords of innocent people. </p>
+
+<li> <p> If you can't use a test email address, please anonymize
+email addresses and host names consistently. Replace each letter
+by "A", each digit
+by "D" so that the helpers can still recognize syntactical errors.
+</p>
+
+<li> <p> Command output from:</p>
+
+<ul>
+
+<li> <p> "<b>postconf -n</b>". Please do not send your main.cf file,
+or 1000+ lines of <b>postconf</b> command output. </p>
+
+<li> <p> "<b>postconf -Mf</b>" (Postfix 2.9 or later). </p>
+
+</ul>
+
+<li> <p> Better, provide output from the <b>postfinger</b> tool.
+This can be found at https://github.com/ford--prefect/postfinger. </p>
+
+<li> <p> If the problem is SASL related, consider including the
+output from the <b>saslfinger</b> tool. This can be found at
+https://packages.debian.org/search?keywords=sasl2-bin. </p>
+
+<li> <p> If the problem is about too much mail in the queue, consider
+including output from the <b>qshape</b> tool, as described in the
+QSHAPE_README file. </p>
+
+<li> <p> If the problem is protocol related (connections time out,
+or an SMTP server complains about syntax errors etc.) consider
+recording a session with <b>tcpdump</b>, as described in the <a
+href="#sniffer">DEBUG_README</a> document. </ul>
+
+</body>
+
+</html>
diff --git a/proto/DSN_README.html b/proto/DSN_README.html
new file mode 100644
index 0000000..f1ee0dc
--- /dev/null
+++ b/proto/DSN_README.html
@@ -0,0 +1,156 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix DSN Support </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+DSN Support </h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> Postfix version 2.3 introduces support for Delivery Status
+Notifications as described in RFC 3464. This gives senders control
+over successful and failed delivery notifications. </p>
+
+<p> Specifically, DSN support gives an email sender the ability to
+specify: </p>
+
+<ul>
+
+<li> <p> What notifications are sent: success, failure, delay, or
+none. Normally, Postfix informs the sender only when mail delivery
+is delayed or when delivery fails. </p>
+
+<li> <p> What content is returned in case of failure: only the
+message headers, or the full message. </p>
+
+<li> <p> An envelope ID that is returned as part of delivery status
+notifications. This identifies the message <i>submission</i>
+transaction, and must not be confused with the message ID, which
+identifies the message <i>content</i>. </p>
+
+</ul>
+
+<p> The implementation of DSN support involves extra parameters to
+the SMTP MAIL FROM and RCPT TO commands, as well as two Postfix
+sendmail command line options that provide a sub-set of the functions
+of the extra SMTP command parameters. </p>
+
+<p> This document has information on the following topics: </p>
+
+<ul>
+
+<li> <a href="#scope">Restricting the scope of "success" notifications</a>
+
+<li> <a href="#cli">Postfix sendmail command-line interface</a>
+
+<li> <a href="#compat">Postfix VERP support compatibility</a>
+
+</ul>
+
+<h2> <a name="scope">Restricting the scope of "success" notifications</a> </h2>
+
+<p> Just like reports of undeliverable mail, DSN reports of
+<i>successful</i> delivery can give away more information about the
+internal infrastructure than desirable. Unfortunately, disallowing
+"success" notification requests requires disallowing other DSN
+requests as well. The RFCs do not offer the option to negotiate
+feature subsets. </p>
+
+<p> This is not as bad as it sounds. When you turn off DSN for
+remote inbound mail, remote senders with DSN support will still be
+informed that their mail reached your Postfix gateway successfully;
+they just will not get successful delivery notices from your internal
+systems. Remote senders lose very little: they can no longer specify
+how Postfix should report delayed or failed delivery. </p>
+
+<p> Use the smtpd_discard_ehlo_keyword_address_maps feature if you
+wish to allow DSN requests from trusted clients but not from random
+strangers (see below for how to turn this off for all clients):
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_discard_ehlo_keyword_address_maps =
+ cidr:/etc/postfix/esmtp_access
+
+/etc/postfix/esmtp_access:
+ # Allow DSN requests from local subnet only
+ 192.168.0.0/28 silent-discard
+ 0.0.0.0/0 silent-discard, dsn
+ ::/0 silent-discard, dsn
+</pre>
+</blockquote>
+
+<p> If you want to disallow all use of DSN requests from the network,
+use the smtpd_discard_ehlo_keywords feature: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_discard_ehlo_keywords = silent-discard, dsn
+</pre>
+</blockquote>
+
+<h2> <a name="cli">Postfix sendmail command-line interface</a> </h2>
+
+<p> Postfix has two Sendmail-compatible command-line options for
+DSN support. </p>
+
+<ul>
+
+<li> <p> The first option specifies what notifications are sent
+for mail that is submitted via the Postfix sendmail(1) command line:
+</p>
+
+<blockquote>
+<pre>
+$ <b>sendmail -N success,delay,failure ...</b> (one or more of these)
+$ <b>sendmail -N never ...</b> (or just this by itself)
+</pre>
+</blockquote>
+
+<p> The built-in default corresponds with "delay,failure". </p>
+
+<li> <p> The second option specifies an envelope ID which is reported
+in delivery status notifications for mail that is submitted via the
+Postfix sendmail(1) command line: </p>
+
+<blockquote>
+<pre>
+$ <b>sendmail -V <i>envelope-id</i> ...</b>
+</pre>
+</blockquote>
+
+<p> Note: this conflicts with VERP support in older Postfix versions,
+as discussed in the next section. </p>
+
+</ul>
+
+<h2> <a name="compat">Postfix VERP support compatibility</a> </h2>
+
+<p> With Postfix versions before 2.3, the sendmail(1) command uses
+the -V command-line option to request VERP-style delivery. In order
+to request VERP style delivery with Postfix 2.3 and later, you must
+specify -XV instead of -V. </p>
+
+<p> The Postfix 2.3 sendmail(1) command will recognize if you try
+to use -V for VERP-style delivery. It will do the right thing and
+will remind you of the new syntax. </p>
+
+</body>
+
+</html>
diff --git a/proto/ETRN_README.html b/proto/ETRN_README.html
new file mode 100644
index 0000000..e3e36a4
--- /dev/null
+++ b/proto/ETRN_README.html
@@ -0,0 +1,374 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix ETRN Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix ETRN Howto</h1>
+
+<hr>
+
+<h2>Purpose of the Postfix fast ETRN service</h2>
+
+<p> The SMTP ETRN command was designed for sites that have intermittent
+Internet connectivity. With ETRN, a site can tell the mail server
+of its provider to "Please deliver all my mail now". The SMTP server
+searches the queue for mail to the customer, and delivers that mail
+<b>by connecting to the customer's SMTP server</b>. The mail is
+not delivered via the connection that was used for sending ETRN.
+</p>
+
+<p> As of version 1.0, Postfix has a fast ETRN implementation that
+does not require Postfix to examine every queue file. Instead,
+Postfix maintains a record of what queue files contain mail for
+destinations that are configured for ETRN service. ETRN service
+is no longer available for domains that aren't configured for the
+service. </p>
+
+<p> This document provides information on the following topics: </p>
+
+<ul>
+
+<li><a href="#using">Using the Postfix fast ETRN service</a>
+
+<li><a href="#how">How Postfix fast ETRN works</a>
+
+<li><a href="#dirty_secret">Postfix fast ETRN service limitations</a>
+
+<li><a href="#config">Configuring the Postfix fast ETRN service</a>
+
+<li><a href="#only">Configuring a domain for ETRN service only</a>
+
+<li><a href="#testing">Testing the Postfix fast ETRN service</a>
+
+</ul>
+
+<p> Other documents with information on this subject: </p>
+
+<ul>
+
+<li> flush(8), flush service implementation
+
+</ul>
+
+<h2><a name="using">Using the Postfix fast ETRN service</a> </h2>
+
+<p> The following is an example SMTP session that shows how an SMTP
+client requests the ETRN service. Client commands are shown in bold
+font. </p>
+
+<blockquote>
+<pre>
+220 my.server.tld ESMTP Postfix
+<b>HELO my.client.tld</b>
+250 Ok
+<b>ETRN some.customer.domain</b>
+250 Queuing started
+<b>QUIT</b>
+221 Bye
+</pre>
+</blockquote>
+
+<p> As mentioned in the introduction, the mail is delivered by
+connecting to the customer's SMTP server; it is not sent over
+the connection that was used to send the ETRN command. </p>
+
+<p> The Postfix operator can request delivery for a specific customer
+by using the command "sendmail -qR<i>destination</i>" and, with
+Postfix version 1.1 and later, "postqueue -s<i>destination</i>".
+Access to this feature is controlled with the authorized_flush_users
+configuration parameter (Postfix version 2.2 and later).
+</p>
+
+<h2><a name="how">How Postfix fast ETRN works</a></h2>
+
+<p> When a Postfix delivery agent decides that mail must be delivered
+later, it sends the destination domain name and the queue file name
+to the flush(8) daemon which maintains per-destination logfiles
+with file names of queued mail. These logfiles are kept below
+$queue_directory/flush. Per-destination logfiles are maintained
+only for destinations that are listed with the $fast_flush_domains
+parameter and that have syntactically valid domain names. </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> Postfix<br>
+delivery<br> agent</td>
+
+<td> <tt>-</tt>(domain, queue ID)<tt>-&gt;</tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> Postfix<br>
+flush<br> daemon</td>
+
+<td> <tt>-</tt>(queue ID)<tt>-&gt;</tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> One logfile <br>
+per eligible<br> domain </td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<p> When Postfix receives a request to "deliver mail for a domain
+now", the flush(8) daemon moves all deferred queue files that are
+listed for that domain to the incoming queue, and requests that
+the queue manager deliver them. In order to force delivery, the
+queue manager temporarily ignores the lists of undeliverable
+destinations: the volatile in-memory list of dead domains, and
+the list of message delivery transports specified with the
+defer_transports configuration parameter. </p>
+
+<h2><a name="dirty_secret">Postfix fast ETRN service limitations</a></h2>
+
+<p> The design of the flush(8) server and of the flush queue
+introduce a few limitations that should not be an issue unless you
+want to turn on fast ETRN service for every possible destination.
+</p>
+
+<ul>
+
+<li> <p> The flush(8) daemon maintains per-destination logfiles
+with queue file names. When a request to "deliver mail now" arrives,
+Postfix will attempt to deliver all recipients in the queue files
+that have mail for the destination in question. This does not
+perform well with queue files that have recipients in many different
+domains, such as queue files with outbound mailing list traffic.
+</p>
+
+<li> <p> The flush(8) daemon maintains per-destination logfiles
+only for destinations listed with $fast_flush_domains. With other
+destinations you cannot request delivery with "sendmail
+-qR<i>destination</i>" or, with Postfix version 1.1 and later,
+"postqueue -s<i>destination</i>". </p>
+
+<li> <p> Up to and including early versions of Postfix version 2.1,
+the "fast flush" service may not deliver some messages if the
+request to "deliver mail now" is received while a deferred queue
+scan is already in progress. The reason is that the queue manager
+does not ignore the volatile in-memory list of dead domains, and
+the list of message delivery transports specified with the
+defer_transports configuration parameter. </p>
+
+<li> <p> Up to and including Postfix version 2.3, the "fast flush"
+service may not deliver some messages if the request to "deliver
+mail now" arrives while an incoming queue scan is already in progress.
+</p>
+
+</ul>
+
+<h2><a name="config">Configuring the Postfix fast ETRN service</a></h2>
+
+<p> The behavior of the flush(8) daemon is controlled by parameters
+in the main.cf configuration file. </p>
+
+<p> By default, Postfix "fast ETRN" service is available only for
+destinations that Postfix is willing to relay mail to: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ fast_flush_domains = $relay_domains
+ smtpd_etrn_restrictions = permit_mynetworks, reject
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> The relay_domains parameter specifies what destinations
+Postfix will relay to. For destinations that are not eligible for
+the "fast ETRN" service, Postfix replies with an error message.
+</p>
+
+<li> <p> The smtpd_etrn_restrictions parameter limits what clients
+may execute the ETRN command. By default, any client has permission.
+</p>
+
+</ul>
+
+<p> To enable "fast ETRN" for some other destination, specify: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ fast_flush_domains = $relay_domains, some.other.domain
+</pre>
+</blockquote>
+
+<p> To disable "fast ETRN", so that Postfix rejects all ETRN requests
+and so that it maintains no per-destination logfiles, specify: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ fast_flush_domains =
+</pre>
+</blockquote>
+
+<h2><a name="only">Configuring a domain for ETRN service only</a></h2>
+
+<p> While an "ETRN" customer is off-line, Postfix will make
+spontaneous attempts to deliver mail to it. These attempts are
+separated in time by increasing time intervals, ranging from
+$minimal_backoff_time to $maximal_backoff_time, and should not be
+a problem unless a lot of mail is queued. </p>
+
+<p> To prevent Postfix from making spontaneous delivery attempts
+you can configure Postfix to always defer mail for the "ETRN"
+customer. Mail is delivered only after the ETRN command or with
+"sendmail -q", with "sendmail -qR<i>domain</i>", or with "postqueue
+-s<i>domain</i>"(Postfix version 1.1 and later only), </p>
+
+<p> In the example below we configure an "etrn-only" delivery
+transport which is simply a duplicate of the "smtp" and "relay"
+mail delivery transports. The only difference is that mail destined
+for this delivery transport is deferred as soon as it arrives.
+</p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/master.cf:
+ 2 # =============================================================
+ 3 # service type private unpriv chroot wakeup maxproc command
+ 4 # (yes) (yes) (yes) (never) (100)
+ 5 # =============================================================
+ 6 smtp unix - - n - - smtp
+ 7 relay unix - - n - - smtp
+ 8 etrn-only unix - - n - - smtp
+ 9
+10 /etc/postfix/main.cf:
+11 relay_domains = customer.tld ...other domains...
+12 defer_transports = etrn-only
+13 transport_maps = hash:/etc/postfix/transport
+14
+15 /etc/postfix/transport:
+16 customer.tld etrn-only:[mailhost.customer.tld]
+</pre>
+</blockquote>
+
+<p>Translation: </p>
+
+<ul>
+
+<li> <p> Line 8: The "etrn-only" mail delivery service is a copy of the
+"smtp" and "relay" service. </p>
+
+<li> <p> Line 11: Don't forget to authorize relaying for this
+customer, either via relay_domains or with the permit_mx_backup
+feature. </p>
+
+<li> <p> Line 12: The "etrn-only" mail delivery service is configured
+so that spontaneous mail delivery is disabled. </p>
+
+<li> <p> Lines 13-16: Mail for the customer is given to the
+"etrn-only" mail delivery service. </p>
+
+<li> <p> Line 16: The "[mailhost.customer.tld]" turns off MX record
+lookups; you must specify this if your Postfix server is the primary
+MX host for the customer's domain. </p>
+
+</ul>
+
+<h2><a name="testing">Testing the Postfix fast ETRN service</a></h2>
+
+<p> By default, "fast ETRN" service is enabled for all domains that
+match $relay_domains. If you run Postfix with "fast ETRN" service
+for the very first time, you need to run "sendmail -q" once
+in order to populate the per-site deferred mail logfiles. If you
+omit this step, no harm is done. The logfiles will eventually
+become populated as Postfix routinely attempts to deliver delayed
+mail, but that will take a couple hours. After the "sendmail
+-q" command has completed all delivery attempts (this can take
+a while), you're ready to test the "fast ETRN" service.
+
+<p> To test the "fast ETRN" service, telnet to the Postfix SMTP
+server from a client that is allowed to execute ETRN commands (by
+default, that's every client), and type the commands shown in
+boldface: </p>
+
+<blockquote>
+<pre>
+220 my.server.tld ESMTP Postfix
+<b>HELO my.client.tld</b>
+250 Ok
+<b>ETRN some.customer.domain</b>
+250 Queuing started
+</pre>
+</blockquote>
+
+<p> where "some.customer.domain" is the name of a domain that has
+a non-empty logfile somewhere under $queue_directory/flush. </p>
+
+<p> In the maillog file, you should immediately see a couple of
+logfile records, as evidence that the queue manager has opened
+queue files: </p>
+
+<blockquote>
+<pre>
+Oct 2 10:51:19 myhostname postfix/qmgr[51999]: 682E8440A4:
+ from=&lt;whatever&gt;, size=12345, nrcpt=1 (queue active)
+Oct 2 10:51:19 myhostname postfix/qmgr[51999]: 02249440B7:
+ from=&lt;whatever&gt;, size=4711, nrcpt=1 (queue active)
+</pre>
+</blockquote>
+
+<p> What happens next depends on whether the destination is reachable.
+If it's not reachable, the mail queue IDs will be added back to
+the some.customer.domain logfile under $queue_directory/flush.
+</p>
+
+<p> Repeat the exercise with some other destination that your server
+is willing to relay to (any domain listed in $relay_domains), but
+that has no mail queued. The text in bold face stands for the
+commands that you type: </p>
+
+<blockquote>
+<pre>
+220 my.server.tld ESMTP Postfix
+<b>HELO my.client.tld</b>
+250 Ok
+<b>ETRN some.other.customer.domain</b>
+250 Queuing started
+</pre>
+</blockquote>
+
+<p> This time, the "ETRN"" command should trigger NO mail deliveries
+at all. If this triggers delivery of all mail, then you used the
+wrong domain name, or "fast ETRN" service is turned off. </p>
+
+<p> Finally, repeat the exercise with a destination that your mail
+server is not willing to relay to. It does not matter if your
+server has mail queued for that destination. </p>
+
+<blockquote>
+<pre>
+220 my.server.tld ESMTP Postfix
+<b>HELO my.client.tld</b>
+250 Ok
+<b>ETRN not.a.customer.domain</b>
+459 &lt;not.a.customer.domain&gt;: service unavailable
+</pre>
+</blockquote>
+
+<p> In this case, Postfix should reject the request
+as shown above. </p>
+
+</body>
+
+</html>
diff --git a/proto/FILTER_README.html b/proto/FILTER_README.html
new file mode 100644
index 0000000..12120f0
--- /dev/null
+++ b/proto/FILTER_README.html
@@ -0,0 +1,980 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix After-Queue Content Filter </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix After-Queue Content Filter </h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> This document requires Postfix version 2.1 or later. </p>
+
+<p> Normally, Postfix receives mail, stores it in the mail queue
+and then delivers it. With the external content filter described
+here, mail is filtered AFTER it is queued. This approach decouples
+mail receiving processes from mail filtering processes, and gives
+you maximal control over how many filtering processes you are
+willing to run in parallel. </p>
+
+<p> The after-queue content filter is meant to be used as follows: </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Network or<br> local users </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Postfix<br> queue </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ <b>Content<br> filter</b> </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Postfix<br> queue </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ Network or<br> local mailbox </td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<p> This document describes implementations that use a single
+Postfix instance for everything: receiving, filtering and delivering
+mail. Applications that use two separate Postfix instances will
+be covered by a later version of this document. </p>
+
+<p> The after-queue content filter is not to be confused with the
+approaches described in the SMTPD_PROXY_README or MILTER_README
+documents,
+where incoming SMTP mail is filtered BEFORE it is stored into the
+Postfix queue. </p>
+
+<p> This document describes two approaches to content filter
+all email, as well as several options to filter mail selectively: </p>
+
+<ul>
+
+<li><a href="#principles">Principles of operation</a>
+
+<li>Simple content filter
+
+<ul>
+
+<li><a href="#simple_filter">Simple content filter example</a>
+
+<li><a href="#simple_performance">Simple content filter performance</a>
+
+<li><a href="#simple_limitations">Simple content filter limitations</a>
+
+<li><a href="#simple_turnoff">Turning off the simple content filter</a>
+
+</ul>
+
+<li>Advanced content filter
+
+<ul>
+
+<li><a href="#advanced_filter">Advanced content filter example</a>
+
+<li><a href="#performance">Advanced content filter performance</a>
+
+<li><a href="#advanced_turnoff">Turning off the advanced content filter</a>
+
+</ul>
+
+<li>Selective content filtering
+
+<ul>
+
+<li><a href="#remote_only">Filtering mail from outside users only</a>
+
+<li><a href="#domain_dependent">Different filters for different domains</a>
+
+<li><a href="#dynamic_filter">FILTER actions in access or header/body tables</a>
+
+</ul>
+
+</ul>
+
+
+<h2><a name="principles">Principles of operation</a> </h2>
+
+<p> An after-queue content filter receives unfiltered mail from Postfix
+(as described further below) and can do one of the following: </p>
+
+<ol>
+
+<li> <p> Re-inject the mail back into Postfix, perhaps after changing
+ content and/or destination. </p>
+
+<li> <p> Discard or quarantine the mail. </p>
+
+<li> <p> Reject the mail (by sending a suitable status code back to
+ Postfix). Postfix will send the mail back to the sender address. </p>
+
+</ol>
+
+<p> NOTE: in this time of mail worms and forged spam, it is a VERY
+BAD IDEA to send viruses back to the sender address, because the
+sender address is almost certainly not the originator. It is better
+to discard known viruses, and to quarantine material that is
+suspect so that a human can decide what to do with it. </p>
+
+<h2><a name="simple_filter">Simple content filter example</a></h2>
+
+<p> The first example is simple to set up, but has major limitations
+that will be addressed in a second example. Postfix receives
+unfiltered mail from the network with the smtpd(8) server, and
+delivers unfiltered mail to a content filter with the Postfix
+pipe(8) delivery agent. The content filter injects filtered mail
+back into Postfix with the Postfix sendmail(1) command, so that
+Postfix can deliver it to the final destination. </p>
+
+<p> This means that mail submitted via the Postfix sendmail(1)
+command cannot be content filtered. </p>
+
+<p> In the figure below, names followed by a number represent
+Postfix commands or daemon programs. See the OVERVIEW
+document for an introduction to the Postfix architecture. </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+ <td align="center" valign="top"> Unfiltered<br> <br> </td>
+
+ <td align="center" valign="top"> <tt> -&gt;</tt><br> <br> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ smtpd(8)<br> <br> pickup(8) </td>
+
+ <td align="center" valign="middle"> <tt> &gt;- </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ cleanup(8) </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ qmgr(8)<br> Postfix <br> queue </td>
+
+ <td align="center" valign="middle"> <tt> -&lt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ local(8)<br> smtp(8)<br> pipe(8) </td>
+
+ <td align="center" valign="top"> <tt> -&gt;</tt><br> <tt>
+ -&gt;</tt><br> </td>
+
+ <td align="center" valign="top"> Filtered<br> Filtered<br>
+ </td>
+
+</tr>
+
+<tr>
+
+ <td colspan="2"> </td>
+
+ <td align="center" valign="middle"> ^<br> <tt> | </tt> </td>
+
+ <td colspan="5"> </td>
+
+ <td align="center" valign="middle"> <tt> |<br> v </tt> </td>
+
+ <td colspan="2"> </td>
+
+</tr>
+
+<tr>
+
+ <td colspan="2"> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ <a href="QSHAPE_README.html#maildrop_queue"> maildrop <br>
+ queue </a> </td>
+
+ <td align="center" valign="middle"> <tt> &lt;- </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">Postfix<br>
+ postdrop(1) </td>
+
+ <td align="center" valign="middle"> <tt> &lt;- </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">Postfix<br>
+ sendmail(1) </td>
+
+ <td align="center" valign="middle"> <tt> &lt;- </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">Content
+ <br> filter </td>
+
+ <td colspan="2"> </td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<p> The content filter can be a simple shell script like this: </p>
+
+<blockquote>
+<pre>
+ 1 #!/bin/sh
+ 2
+ 3 # Simple shell-based filter. It is meant to be invoked as follows:
+ 4 # /path/to/script -f sender recipients...
+ 5
+ 6 # Localize these. The -G option does nothing before Postfix 2.3.
+ 7 INSPECT_DIR=/var/spool/filter
+ 8 SENDMAIL="/usr/sbin/sendmail -G -i" # NEVER NEVER NEVER use "-t" here.
+ 9
+10 # Exit codes from &lt;sysexits.h&gt;
+11 EX_TEMPFAIL=75
+12 EX_UNAVAILABLE=69
+13
+14 # Clean up when done or when aborting.
+15 trap "rm -f in.$$" 0 1 2 3 15
+16
+17 # Start processing.
+18 cd $INSPECT_DIR || {
+19 echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
+20
+21 cat &gt;in.$$ || {
+22 echo Cannot save mail to file; exit $EX_TEMPFAIL; }
+23
+24 # Specify your content filter here.
+25 # filter &lt;in.$$ || {
+26 # echo Message content rejected; exit $EX_UNAVAILABLE; }
+27
+28 $SENDMAIL "$@" &lt;in.$$
+29
+30 exit $?
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Line 8: The -G option says the filter output is not a local
+mail submission: don't do silly things like appending the local
+domain name to addresses in message headers. This option does
+nothing before Postfix version 2.3. </p>
+
+<li> <p> Line 8: The -i option says don't stop reading input when
+a line contains "." only. </p>
+
+<li> <p> Line 8: NEVER NEVER NEVER use the "-t" command-line option
+here. It will mis-deliver mail, like sending messages from a mailing
+list back to the mailing list. </p>
+
+<li> <p> Line 21: The idea is to first capture the message to
+file and then run the content through a third-party content filter
+program. </p>
+
+<li> <p> Line 22: If the message cannot be captured to file, mail
+delivery is deferred by terminating with exit status 75 (EX_TEMPFAIL).
+Postfix places the message in the deferred mail queue and tries
+again later. </p>
+
+<li> <p> Line 25: You will need to specify a real content filter
+program here that receives the content on standard input. </p>
+
+<li> <p> Line 26: If the content filter program finds a problem,
+the mail is bounced by terminating with exit status 69 (EX_UNAVAILABLE).
+Postfix will send the message back to the sender as undeliverable
+mail.
+</p>
+
+<li> <p> NOTE: in this time of mail worms and spam, it is a BAD
+IDEA to send known viruses or spam back to the sender, because that
+address is likely to be forged. It is safer to discard known viruses
+and to quarantine suspicious content so that it can
+be inspected by a human being. </p>
+
+<li> <p> Line 28: If the content is OK, it is given as input to
+the Postfix sendmail command, and the exit status of the filter
+command is whatever exit status the Postfix sendmail command
+produces. Postfix will deliver the message as usual. </p>
+
+<li> <p> Line 30: Postfix returns the exit status of the Postfix
+sendmail command. </p>
+
+</ul>
+
+<p> I suggest that you first run this script by hand until you are
+satisfied with the results. Run it with a real message (headers+body)
+as input: </p>
+
+<blockquote>
+<pre>
+% /path/to/script -f sender -- recipient... &lt;message-file
+</pre>
+</blockquote>
+
+<p> Once you're satisfied with the content filtering script: </p>
+
+<ul>
+
+<li> <p> Create a dedicated local user account called "filter". This
+user handles all potentially dangerous mail content - that is
+why it should be a separate account. Do not use "nobody", and
+most certainly do not use "root" or "postfix". </p>
+
+<li> <p> Create a directory /var/spool/filter that is accessible only
+to the "filter" user. This is where the content filtering script
+is supposed to store its temporary files. </p>
+
+<li> <p> Configure Postfix to deliver mail to the content filter
+with the pipe(8) delivery agent (see the pipe(8) manpage for a
+description of the command syntax below). </p>
+
+<pre>
+/etc/postfix/master.cf:
+ # =============================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =============================================================
+ filter unix - n n - 10 pipe
+ flags=Rq user=filter null_sender=
+ argv=/path/to/script -f ${sender} -- ${recipient}
+</pre>
+
+<p> This runs up to 10 content filters in parallel. Instead of a
+limit of 10 concurrent processes, use whatever process limit is
+feasible for your machine. Content inspection software can gobble
+up a lot of system resources, so you don't want to have too much
+of it running at the same time. The empty null_sender setting is
+required with Postfix 2.3 and later. </p>
+
+<li> <p> To turn on content filtering for mail arriving via SMTP
+only, append "-o content_filter=filter:dummy" to the master.cf
+entry that defines the Postfix SMTP server: </p>
+
+<pre>
+/etc/postfix/master.cf:
+ # =============================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =============================================================
+ smtp inet ...other stuff here, do not change... smtpd
+ -o content_filter=filter:dummy
+</pre>
+
+<p> The "-o content_filter" line causes Postfix to add one content
+filter request record to each incoming mail message, with content
+"filter:dummy". This record overrides the normal mail routing
+and causes mail to be given to the content filter instead. </p>
+
+<p> The content_filter configuration parameter expects a value of
+the form <i>transport:destination</i>. The <i>transport</i> name
+specifies the first field of a mail delivery agent definition in
+master.cf; the syntax of the next-hop <i>destination</i> is described
+in the manual page of the corresponding delivery agent. </p>
+
+<p> The meaning of an empty next-hop filter <i>destination</i> is
+version dependent. Postfix 2.7 and later will use the recipient
+domain; earlier versions will use $myhostname. Specify
+"default_filter_nexthop = $myhostname" for compatibility with Postfix
+2.6 or earlier, or specify a non-empty next-hop filter <i>destination</i>.
+</p>
+
+<p> The content_filter setting has lower precedence than a FILTER
+action that is specified in an access(5), header_checks(5) or
+body_checks(5) table. </p>
+
+<li> <p> Execute "<b>postfix reload</b>" to complete the change.
+</p>
+
+</ul>
+
+<h2> <a name="simple_performance">Simple content filter performance</a> </h2>
+
+<p> With the shell script as shown above you will lose a factor of
+four in Postfix performance for transit mail that arrives and leaves
+via SMTP. You will lose another factor in transit performance for
+each additional temporary file that is created and deleted in the
+process of content filtering. The performance impact is less for
+mail that is submitted or delivered locally, because such deliveries
+are already slower than SMTP transit mail. </p>
+
+<h2><a name="simple_limitations">Simple content filter limitations</a></h2>
+
+<p> The problem with content filters like the one above is that
+they are not very robust. The reason is that the software does not
+talk a well-defined protocol with Postfix. If the filter shell
+script aborts because the shell runs into some memory allocation
+problem, the script will not produce a nice exit status as defined
+in the file /usr/include/sysexits.h. Instead of going to the
+deferred queue, mail will bounce. The same lack of robustness can
+happen when the content filtering software itself runs into a
+resource problem. </p>
+
+<p> The simple content filter method is not suitable for content
+filter actions that are invoked via header_checks or body_checks
+patterns. These patterns will be applied again after mail is
+re-injected with the Postfix sendmail command, resulting in a mail
+filtering loop. The advanced content filtering method (see below)
+makes it possible to turn off header_checks or body_checks patterns
+for filtered mail. </p>
+
+<h2><a name="simple_turnoff">Turning off the simple content filter</a> </h2>
+
+<p> To turn off "simple" content filtering: </p>
+
+<ul> <li> <p> Edit the master.cf file, remove the "-o
+content_filter=filter:dummy" text from the entry that defines the
+Postfix SMTP server. </p>
+
+<li> <p> Execute "<b>postsuper -r ALL</b>" to remove content
+filter request records from existing queue files. </p>
+
+<li> <p> Execute another "<b>postfix reload</b>". </p>
+
+</ul>
+
+<h2><a name="advanced_filter">Advanced content filter example</a></h2>
+
+<p> The second example is more complex, but can give better
+performance, and is less likely to bounce mail when the machine
+runs into some resource problem. This content filter receives
+unfiltered mail with SMTP on localhost port 10025, and sends filtered
+mail back into Postfix with SMTP on localhost port 10026. </p>
+
+<p> For non-SMTP capable content filtering software, Bennett Todd's
+SMTP proxy implements a nice PERL/SMTP content filtering framework.
+See: https://web.archive.org/web/20151022025756/http://bent.latency.net/smtpprox/. </p>
+
+<p> In the figure below, names followed by a number represent
+Postfix commands or daemon programs. See the OVERVIEW
+document for an introduction to the Postfix architecture. </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+ <td align="center" valign="middle"> Unfiltered<br> <br>
+ Unfiltered</td>
+
+ <td align="center" valign="middle"> <tt> -&gt;</tt><br> <br>
+ <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ smtpd(8)<br> <br> pickup(8) </td>
+
+ <td align="center" valign="middle"> <tt> &gt;- </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ cleanup(8) </td>
+
+ <td align="center" valign="middle"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ qmgr(8)<br> Postfix <br> queue </td>
+
+ <td align="center" valign="middle"> <tt> -&lt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ smtp(8)<br> <br> local(8) </td>
+
+ <td align="center" valign="middle"> <tt> -&gt;</tt><br> <br>
+ <tt> -&gt; </tt></td>
+
+ <td align="center" valign="middle"> Filtered<br> <br>
+ Filtered</td>
+
+</tr>
+
+<tr>
+
+ <td colspan="4"> </td>
+
+ <td align="center" valign="middle"> ^<br> <tt> | </tt> </td>
+
+ <td> </td>
+
+ <td align="center" valign="middle"> <tt> |<br> v </tt> </td>
+
+ <td colspan="4"> </td>
+
+</tr>
+
+<tr>
+
+ <td colspan="4"> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ smtpd(8)<br> 10026 </td>
+
+ <td> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle">
+ smtp(8)<br> </td>
+
+ <td colspan="4"> </td>
+
+</tr>
+
+<tr>
+
+ <td colspan="4"> </td>
+
+ <td align="center" valign="middle"> ^<br> <tt> | </tt> </td>
+
+ <td> </td>
+
+ <td align="center" valign="middle"> <tt> |<br> v </tt> </td>
+
+ <td colspan="4"> </td>
+
+</tr>
+
+<tr>
+
+ <td colspan="4"> </td>
+
+ <td colspan="3" bgcolor="#f0f0ff" align="center"
+ valign="middle">content filter 10025</td>
+
+ <td colspan="4"> </td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<p> The example given here filters all mail, including mail that
+arrives via SMTP and mail that is locally submitted via the Postfix
+sendmail command (local submissions enter Postfix via the pickup(8)
+server; to keep the figure simple we omit local submission details).
+See examples near the end of this document for
+how to exclude local users from filtering, or how to configure a
+destination dependent content filter. </p>
+
+<p> You can expect to lose about a factor of two in Postfix
+performance for mail that arrives and leaves via SMTP, provided
+that the content filter creates no temporary files. Each temporary
+file created by the content filter adds another factor to the
+performance loss. </p>
+
+<h3>Advanced content filter: requesting that all mail is filtered</h3>
+
+<p> To enable the advanced content filter method for all mail,
+specify in main.cf: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ content_filter = scan:localhost:10025
+ receive_override_options = no_address_mappings
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> The "receive_override_options" line disables address
+manipulation before the content filter, so that the content filter
+sees the original mail addresses instead of the result of virtual
+alias expansion, canonical mapping, automatic bcc, address
+masquerading, etc. </p>
+
+<li> <p> The "content_filter" line causes Postfix to add one content
+filter request record to each incoming mail message, with content
+"scan:localhost:10025". The content filter request records are
+added by the smtpd(8) and pickup(8) servers (and qmqpd(8) if you
+decide to enable this service). </p>
+
+<li> <p> Content filter requests are stored in queue files; this
+is how Postfix keeps track of what mail needs filtering. When a
+queue file contains a content filter request, the queue manager
+will deliver the mail to the specified content filter regardless
+of its final destination. </p>
+
+<li> <p> The content_filter configuration parameter expects a value
+of the form <i>transport:destination</i>. The <i>transport</i> name
+specifies the first field of a mail delivery agent definition in
+master.cf; the syntax of the next-hop <i>destination</i> is described
+in the manual page of the corresponding delivery agent. </p>
+
+<li> <p> The meaning of an empty next-hop filter <i>destination</i>
+is version dependent. Postfix 2.7 and later will use the recipient
+domain; earlier versions will use $myhostname. Specify
+"default_filter_nexthop = $myhostname" for compatibility with Postfix
+2.6 or earlier, or specify a non-empty next-hop filter <i>destination</i>.
+
+<li> <p> The content_filter setting has lower precedence than a
+FILTER action that is specified in an access(5), header_checks(5)
+or body_checks(5) table. </p>
+
+</ul>
+
+<h3> Advanced content filter: sending unfiltered mail to the content
+filter</h3>
+
+<p> In this example, "scan" is an instance of the Postfix SMTP
+client with slightly different configuration parameters. This is
+how one would set up the service in the Postfix master.cf file:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ # =============================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =============================================================
+ scan unix - - n - 10 smtp
+ -o smtp_send_xforward_command=yes
+ -o disable_mime_output_conversion=yes
+ -o smtp_generic_maps=
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> This runs up to 10 content filters in parallel. Instead
+of a limit of 10 concurrent processes, use whatever process limit
+is feasible for your machine. Content inspection software can
+gobble up a lot of system resources, so you don't want to have too
+much of it running at the same time. </p>
+
+<li> <p> With "-o smtp_send_xforward_command=yes", the scan transport
+will try to forward the original client name and IP address
+through the content filter to the
+after-filter smtpd process, so that filtered mail is logged with
+the real client name IP address. See smtp(8) and XFORWARD_README
+for more information. </p>
+
+<li> <p> The "-o disable_mime_output_conversion=yes" is a workaround
+that prevents the breaking of domainkeys and other digital signatures.
+This is needed because some SMTP-based content filters don't announce
+8BITMIME support, even though they can handle 8-bit mail. </p>
+
+<li> <p> The "-o smtp_generic_maps=" is a workaround that prevents
+local address rewriting with generic(5) maps. Such rewriting should
+happen only when mail is sent out to the Internet. </p>
+
+</ul>
+
+<h3>Advanced content filter: running the content filter</h3>
+
+<p> The content filter can be set up with the Postfix spawn service,
+which is the Postfix equivalent of inetd. For example, to instantiate
+up to 10 content filtering processes on localhost port 10025: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ # ===================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # ===================================================================
+ localhost:10025 inet n n n - 10 spawn
+ user=filter argv=/path/to/filter localhost 10026
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> "filter" is a dedicated local user account. The user will
+never log in, and can be given a "*" password and non-existent
+shell and home directory. This user handles all potentially
+dangerous mail content - that is why it should be a separate account.
+</p>
+
+<li> <p> By default, Postfix will terminate a command that runs
+longer than command_time_limit seconds (default: 1000s). This is a
+safety measure that prevents filters from running forever. </p>
+
+</ul>
+
+<p> If you want to have your filter listening on port localhost:10025
+instead of Postfix, then you must run your filter as a stand-alone
+program, and must not use the Postfix spawn service. </p>
+
+<h3>Advanced filter: injecting mail back into Postfix</h3>
+
+<p> The job of the content filter is to either bounce mail with a
+suitable diagnostic, or to feed the mail back into Postfix through
+a dedicated listener on port localhost 10026. </p>
+
+<p> The simplest content filter just copies SMTP commands and data
+between its inputs and outputs. If it has a problem, all it has to
+do is to reply to an input of `.' from Postfix with `550 content
+rejected', and to disconnect without sending `.' on the connection
+that injects mail back into Postfix. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ # ===================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # ===================================================================
+ localhost:10026 inet n - n - 10 smtpd
+ -o content_filter=
+ -o receive_override_options=no_unknown_recipient_checks,no_header_body_checks,no_milters
+ -o smtpd_helo_restrictions=
+ -o smtpd_client_restrictions=
+ -o smtpd_sender_restrictions=
+ # Postfix 2.10 and later: specify empty smtpd_relay_restrictions.
+ -o smtpd_relay_restrictions=
+ -o smtpd_recipient_restrictions=permit_mynetworks,reject
+ -o mynetworks=127.0.0.0/8
+ -o smtpd_authorized_xforward_hosts=127.0.0.0/8
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> NOTE: do not use spaces around the "=" or "," characters. </p>
+
+<li> <p> NOTE: the SMTP server must not have a smaller process
+limit than the "filter" master.cf entry. </p>
+
+<li> <p> The "-o content_filter=" overrides main.cf settings, and
+requests no content filtering for mail from the content filter.
+This is required or else mail will loop. </p>
+
+<li> <p> The "-o receive_override_options" overrides main.cf settings
+to avoid duplicating work that was already done before the content
+filter. These options are complementary to the options that are
+specified in main.cf: </p>
+
+<ul>
+
+ <li> <p> We specify "no_unknown_recipient_checks" to disable
+ attempts to find out if a recipient is unknown. </p>
+
+ <li> <p> We specify "no_header_body_checks" to disable header/body
+ checks. </p>
+
+ <li> <p> We specify "no_milters" to disable Milter applications
+ (this option is available only in Postfix 2.3 and later). </p>
+
+ <li> <p> We don't specify "no_address_mappings" here. This
+ enables virtual alias expansion, canonical mappings, address
+ masquerading, and other address mappings after the content
+ filter. The main.cf setting of "receive_override_options"
+ disables these mappings before the content filter. </p>
+
+</ul>
+
+ <p> These receive override options are either implemented by the
+ SMTP server itself, or they are passed on to the cleanup server.
+ </p>
+
+<li> <p> The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
+override main.cf settings. They turn off junk mail controls that
+would only waste time here.
+
+<li> <p> With "-o smtpd_authorized_xforward_hosts=127.0.0.0/8",
+the scan transport will try to forward the original client name
+and IP address to the after-filter smtpd process, so that filtered
+mail is logged with the real client name and IP address. See
+XFORWARD_README and smtpd(8). </p>
+
+</ul>
+
+<h2><a name="performance">Advanced content filter performance</a></h2>
+
+<p> With the "sandwich" approach to content filtering described
+here, it is important to match the filter concurrency to the
+available CPU, memory and I/O resources. Too few content filter
+processes and mail accumulates in the active queue even with low
+traffic volume; too much concurrency and Postfix ends up deferring
+mail destined for the content filter because processes fail due to
+insufficient resources. </p>
+
+<p> Currently, content filter performance tuning is a process of
+trial and error; analysis is handicapped because filtered and
+unfiltered messages share the same queue. As mentioned in the
+introduction of this document, content filtering with multiple
+Postfix instances will be covered in a future version. </p>
+
+<h2><a name="advanced_turnoff">Turning off the advanced content filter</a> </h2>
+
+<p> To turn off "advanced" content filtering: </p>
+
+<ul> <li> <p> Delete or comment out the two following main.cf lines.
+The other changes made for advanced content filtering have no effect
+when content filtering is turned off. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ content_filter = scan:localhost:10025
+ receive_override_options = no_address_mappings
+</pre>
+</blockquote>
+
+<li> <p> Execute "<b>postsuper -r ALL</b>" to remove content
+filter request records from existing queue files. </p>
+
+<li> <p> Execute another "<b>postfix reload</b>". </p>
+
+</ul>
+
+<h2><a name="remote_only">Filtering mail from outside users only</a></h2>
+
+<p> The easiest approach is to configure ONE Postfix instance with
+multiple SMTP server IP addresses in master.cf: </p>
+
+<ul>
+
+<li> <p> Two SMTP server IP addresses for mail from inside users only,
+with content filtering turned off. </p>
+
+<pre>
+/etc/postfix.master.cf:
+ # ==================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # ==================================================================
+ 1.2.3.4:smtp inet n - n - - smtpd
+ -o smtpd_client_restrictions=permit_mynetworks,reject
+ 127.0.0.1:smtp inet n - n - - smtpd
+ -o smtpd_client_restrictions=permit_mynetworks,reject
+</pre>
+
+<li> <p> One SMTP server address for mail from outside users with
+content filtering turned on. </p>
+
+<pre>
+/etc/postfix.master.cf:
+ # =================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =================================================================
+ 1.2.3.5:smtp inet n - n - - smtpd
+ -o content_filter=filter-service:filter-destination
+ -o receive_override_options=no_address_mappings
+</pre>
+
+</ul>
+
+<p> After this, you can follow the same procedure as outlined in
+the "advanced" or "simple" content filtering examples above, except
+that you must not specify "content_filter" or "receive_override_options"
+in the main.cf file. </p>
+
+<h2><a name="domain_dependent">Different filters for different
+domains</a></h2>
+
+<p> If you are an MX service provider and want to apply different
+content filters for different domains, you can configure ONE Postfix
+instance with multiple SMTP server IP addresses in master.cf. Each
+address provides a different content filter service. </p>
+
+<blockquote>
+<pre>
+/etc/postfix.master.cf:
+ # =================================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =================================================================
+ # SMTP service for domains that are filtered with service1:dest1
+ 1.2.3.4:smtp inet n - n - - smtpd
+ -o content_filter=service1:dest1
+ -o receive_override_options=no_address_mappings
+
+ # SMTP service for domains that are filtered with service2:dest2
+ 1.2.3.5:smtp inet n - n - - smtpd
+ -o content_filter=service2:dest2
+ -o receive_override_options=no_address_mappings
+</pre>
+</blockquote>
+
+<p> After this, you can follow the same procedure as outlined in
+the "advanced" or "simple" content filtering examples above, except
+that you must not specify "content_filter" or "receive_override_options"
+in the main.cf file. </p>
+
+<p> Set up MX records in the DNS that route each domain to the
+proper SMTP server instance. </p>
+
+<h2><a name="dynamic_filter">FILTER actions in access or header/body
+tables</a></h2>
+
+<p> The above filtering configurations are static. Mail that follows
+a given path is either always filtered or it is never filtered. As
+of Postfix 2.0 you can also turn on content filtering on the fly.
+</p>
+
+<p> To turn on content filtering with an access(5) table rule: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/access:
+ <i>whatever</i> FILTER foo:bar
+</pre>
+</blockquote>
+
+<p> To turn on content filtering with a header_checks(5) or
+body_checks(5) table pattern: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/header_checks:
+ /<i>whatever</i>/ FILTER foo:bar
+</pre>
+</blockquote>
+
+<p> You can do this in smtpd access maps as well as the cleanup
+server's header/body_checks. This feature must be used with great
+care: you must disable all the UCE features in the after-filter
+smtpd and cleanup daemons or else you will have a content filtering
+loop. </p>
+
+<p> Limitations: </p>
+
+<ul>
+
+<li> <p> FILTER actions from smtpd access maps and header/body_checks
+take precedence over filters specified with the main.cf content_filter
+parameter. </p>
+
+<li> <p> If a message triggers more than one filter action, only
+the last one takes effect. </p>
+
+<li> <p> The same content filter is applied to all the recipients
+of a given message. </p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/FORWARD_SECRECY_README.html b/proto/FORWARD_SECRECY_README.html
new file mode 100644
index 0000000..0ed87d6
--- /dev/null
+++ b/proto/FORWARD_SECRECY_README.html
@@ -0,0 +1,727 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>TLS Forward Secrecy in Postfix</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">
+TLS Forward Secrecy in Postfix
+</h1>
+
+<hr>
+
+<h2> Warning </h2>
+
+<p> Forward secrecy does not protect against active attacks such
+as forged DNS replies or forged TLS server certificates. If such
+attacks are a concern, then the SMTP client will need to authenticate
+the remote SMTP server in a sufficiently-secure manner. For example,
+by the fingerprint of a (CA or leaf) public key or certificate.
+Conventional PKI relies on many trusted parties and is easily
+subverted by a state-funded adversary. </p>
+
+<h2> Overview </h2>
+
+<p> Postfix supports forward secrecy of TLS network communication
+since version 2.2. This support was adopted from Lutz J&auml;nicke's
+"Postfix TLS patch" for earlier Postfix versions. This document
+will focus on TLS Forward Secrecy in the Postfix SMTP client and
+server. See <a href="TLS_README.html">TLS_README</a> for a general
+description of Postfix TLS support. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li> <p> Give me some background on forward secrecy in Postfix </p>
+
+<ul>
+
+<li><a href="#dfn_fs">What is Forward Secrecy</a>
+
+<li><a href="#tls_fs">Forward Secrecy in TLS</a>
+
+<li><a href="#server_fs">Forward Secrecy in the Postfix SMTP Server</a>
+
+<li><a href="#client_fs">Forward Secrecy in the Postfix SMTP Client</a>
+
+</ul>
+
+<li> <p> Never mind, just show me what it takes to get forward
+secrecy </p>
+
+<ul>
+
+<li><a href="#quick-start">Getting started, quick and dirty</a>
+
+<li><a href="#test">How can I see that a connection has forward secrecy?</a>
+
+<li><a href="#ciphers"> What ciphers provide forward secrecy? </a>
+
+<li><a href="#status"> What do "Anonymous", "Untrusted", etc. in
+Postfix logging mean? </a>
+
+</ul>
+
+<li> <p> <a href="#credits"> Credits </a> </p>
+
+</ul>
+
+<h2><a name="dfn_fs">What is Forward Secrecy</a></h2>
+
+<p> The term "Forward Secrecy" (or sometimes "Perfect Forward Secrecy")
+is used to describe security protocols in which the confidentiality
+of past traffic is not compromised when long-term keys used by either
+or both sides are later disclosed. </p>
+
+<p> Forward secrecy is accomplished by negotiating session keys
+using per-session cryptographically-strong random numbers that are
+not saved, and signing the exchange with long-term authentication
+keys. Later disclosure of the long-term keys allows impersonation
+of the key holder from that point on, but not recovery of prior
+traffic, since with forward secrecy, the discarded random key
+agreement inputs are not available to the attacker. </p>
+
+<p> Forward secrecy is only "perfect" when brute-force attacks on
+the key agreement algorithm are impractical even for the best-funded
+adversary and the random-number generators used by both parties are
+sufficiently strong. Otherwise, forward secrecy leaves the attacker
+with the challenge of cracking the key-agreement protocol, which
+is likely quite computationally intensive, but may be feasible for
+sessions of sufficiently high value. Thus forward secrecy places
+cost constraints on the efficacy of bulk surveillance, recovering
+all past traffic is generally infeasible, and even recovery of
+individual sessions may be infeasible given a sufficiently-strong
+key agreement method. </p>
+
+<h2><a name="tls_fs">Forward Secrecy in TLS</a></h2>
+
+<p> Early implementations of the SSL protocol do not provide forward
+secrecy (some provide it only with artificially-weakened "export"
+cipher suites, but we will ignore those here). The client
+sends a random "pre-master secret" to the server encrypted with the
+server's RSA public key. The server decrypts this with its private
+key, and uses it together with other data exchanged in the clear
+to generate the session key. An attacker with access to the server's
+private key can perform the same computation at any later time.
+The TLS library in Windows XP and Windows Server 2003 only supported
+cipher suites of this type, and Exchange 2003 servers largely do
+not support forward secrecy. </p>
+
+<p> Later revisions to the TLS protocol introduced forward-secrecy
+cipher suites in which the client and server implement a key exchange
+protocol based on ephemeral secrets. Sessions encrypted with one
+of these newer cipher suites are not compromised by future disclosure
+of long-term authentication keys. </p>
+
+<p> The key-exchange algorithms used for forward secrecy require
+the TLS server to designate appropriate "parameters" consisting of a
+mathematical "group" and an element of that group called a "generator".
+Presently, there are two flavors of "groups" that work with PFS: </p>
+
+<ul>
+
+<li> <p> <b> Prime-field groups (EDH):</b> The server needs to be
+configured with a suitably-large prime and a corresponding "generator".
+The acronym for forward secrecy over prime fields is EDH for Ephemeral
+Diffie-Hellman (also abbreviated as DHE).
+</p>
+
+<li> <p> <b> Elliptic-curve groups (EECDH): </b> The server needs
+to be configured with a "named curve". These offer better security
+at lower computational cost than prime field groups, but are not
+as widely implemented. The acronym for the elliptic curve version
+is EECDH which is short for Ephemeral Elliptic Curve Diffie-Hellman
+(also abbreviated as ECDHE). </p>
+
+</ul>
+
+<p> It is not essential to know what these are, but one does need
+to know that OpenSSL supports EECDH with version 1.0.0 or later.
+Thus the configuration parameters related to Elliptic-Curve forward
+secrecy are available when Postfix is linked with OpenSSL &ge; 1.0.0
+(provided EC support has not been disabled by the vendor, as in
+some versions of RedHat Linux). </p>
+
+<p> Elliptic curves used in cryptography are typically identified
+by a "name" that stands for a set of well-known parameter values,
+and it is these "names" (or associated ASN.1 object identifiers)
+that are used in the TLS protocol. On the other hand, with TLS there
+are no specially designated prime field groups, so each server is
+free to select its own suitably-strong prime and generator. </p>
+
+<h2><a name="server_fs">Forward Secrecy in the Postfix SMTP Server</a></h2>
+
+<p> The Postfix &ge; 2.2 SMTP server supports forward secrecy in
+its default configuration. If the remote SMTP client prefers cipher
+suites with forward secrecy, then the traffic between the server
+and client will resist decryption even if the server's long-term
+authentication keys are <i>later</i> compromised. </p>
+
+<p> Some remote SMTP clients may support forward secrecy, but prefer
+cipher suites <i>without</i> forward secrecy. In that case, Postfix
+&ge; 2.8 could be configured to ignore the client's preference with
+the main.cf setting "tls_preempt_cipherlist = yes". However, this
+will likely cause interoperability issues with older Exchange servers
+and is not recommended for now. </p>
+
+<h3> EDH Server support </h3>
+
+<p> Postfix &ge; 2.2 supports 1024-bit-prime EDH out of the box,
+with no additional configuration, but you may want to override the
+default prime to be 2048 bits long, and you may want to regenerate
+your primes periodically. See the <a href="#quick-start">quick-start</a>
+section for details. With Postfix &ge; 3.1 the out of the box
+(compiled-in) EDH prime size is 2048 bits. </p>
+
+<p> With prime-field EDH, OpenSSL wants the server to provide
+two explicitly-selected (prime, generator) combinations. One for
+the now long-obsolete "export" cipher suites, and another for
+non-export cipher suites. Postfix has two such default combinations
+compiled in, but also supports explicitly-configured overrides.
+</p>
+
+<ul>
+
+<li> <p> The "export" EDH parameters are used only with the obsolete
+"export" ciphers. To use a non-default prime, generate a 512-bit
+DH parameter file and set smtpd_tls_dh512_param_file to the filename
+(see the <a href="#quick-start">quick-start</a> section for details).
+With Postfix releases after the middle of 2015 the default opportunistic
+TLS cipher grade (smtpd_tls_ciphers) is "medium" or stronger, and
+export ciphers are no longer used. </p>
+
+<li> <p> The non-export EDH parameters are used for all other EDH
+cipher suites. To use a non-default prime, generate a 1024-bit or
+2048-bit DH parameter file and set smtpd_tls_dh1024_param_file to
+the filename. Despite the name this is simply the non-export
+parameter file and the prime need not actually be 1024 bits long
+(see the <a href="#quick-start">quick-start</a> section for details).
+</p>
+
+</ul>
+
+<p> As of mid-2015, SMTP clients are starting to reject TLS
+handshakes with primes smaller than 2048 bits. Each site needs to
+determine which prime size works best for the majority of its
+clients. See the <a href="#quick-start">quick-start</a> section
+for the recommended configuration to work around this issue. </p>
+
+<h3> EECDH Server support </h3>
+
+<p> Postfix &ge; 2.6 supports NIST P-256 EECDH when built with OpenSSL
+&ge; 1.0.0. When the remote SMTP client also supports EECDH and
+implements the P-256 curve, forward secrecy just works. </p>
+
+<blockquote> <p> Note: With Postfix 2.6 and 2.7, enable EECDH by
+setting the main.cf parameter smtpd_tls_eecdh_grade to "strong".
+</p> </blockquote>
+
+<p> The elliptic curve standards are evolving, with new curves
+introduced in RFC 8031 to augment or replace the NIST curves tarnished
+by the Snowden revelations. Fortunately, TLS clients advertise
+their list of supported curves to the server so that servers can
+choose newer stronger curves when mutually supported. OpenSSL 1.0.2
+released in January 2015 was the first release to implement negotiation
+of supported curves in TLS servers. In older OpenSSL releases, the
+server is limited to selecting a single widely supported curve. </p>
+
+<p> With Postfix prior to 3.2 or OpenSSL prior to 1.0.2, only a
+single server-side curve can be configured, by specifying a suitable
+EECDH "grade": </p>
+
+<blockquote>
+<pre>
+ smtpd_tls_eecdh_grade = strong | ultra
+ # Underlying curves, best not changed:
+ # tls_eecdh_strong_curve = prime256v1
+ # tls_eecdh_ultra_curve = secp384r1
+</pre>
+</blockquote>
+
+<p> Postfix &ge; 3.2 supports the curve negotiation API of OpenSSL
+&ge; 1.0.2. When using this software combination, the default setting
+of "smtpd_tls_eecdh_grade" changes to "auto", which selects a curve
+that is supported by both the server and client. The list of
+candidate curves can be configured via "tls_eecdh_auto_curves",
+which can be used to configure a prioritized list of supported
+curves (most preferred first) on both the server and client.
+The default list is suitable for most users. </p>
+
+<h2> <a name="client_fs">Forward Secrecy in the Postfix SMTP Client</a> </h2>
+
+<p> The Postfix &ge; 2.2 SMTP client supports forward secrecy in
+its default configuration. All supported OpenSSL releases support
+EDH key exchange. OpenSSL releases &ge; 1.0.0 also support EECDH
+key exchange (provided elliptic-curve support has not been disabled
+by the vendor as in some versions of RedHat Linux). If the
+remote SMTP server supports cipher suites with forward secrecy (and
+does not override the SMTP client's cipher preference), then the
+traffic between the server and client will resist decryption even
+if the server's long-term authentication keys are <i>later</i>
+compromised. </p>
+
+<p> Postfix &ge; 3.2 supports the curve negotiation API of OpenSSL
+&ge; 1.0.2. The list of candidate curves can be changed via the
+"tls_eecdh_auto_curves" configuration parameter, which can be used
+to select a prioritized list of supported curves (most preferred
+first) on both the Postfix SMTP server and SMTP client. The default
+list is suitable for most users. </p>
+
+<p> The default Postfix SMTP client cipher lists are correctly
+ordered to prefer EECDH and EDH cipher suites ahead of similar
+cipher suites that don't implement forward secrecy. Administrators
+are strongly discouraged from changing the cipher list definitions. </p>
+
+<p> The default minimum cipher grade for opportunistic TLS is
+"medium" for Postfix releases after the middle of 2015, "export"
+for older releases. Changing the minimum cipher grade does not
+change the cipher preference order. Note that cipher grades higher
+than "medium" exclude Exchange 2003 and likely other MTAs, thus a
+"high" cipher grade should be chosen only on a case-by-case basis
+via the <a href="TLS_README.html#client_tls_policy">TLS policy</a>
+table. </p>
+
+<h2><a name="quick-start">Getting started, quick and dirty</a></h2>
+
+<h3> EECDH Client support (Postfix &ge; 2.2 with OpenSSL &ge; 1.0.0) </h3>
+
+<p> This works "out of the box" with no need for additional
+configuration. </p>
+
+<p> Postfix &ge; 3.2 supports the curve negotiation API of OpenSSL
+&ge; 1.0.2. The list of candidate curves can be changed via the
+"tls_eecdh_auto_curves" configuration parameter, which can be used
+to select a prioritized list of supported curves (most preferred
+first) on both the Postfix SMTP server and SMTP client. The default
+list is suitable for most users. </p>
+
+<h3> EECDH Server support (Postfix &ge; 2.6 with OpenSSL &ge; 1.0.0) </h3>
+
+<p> With Postfix 2.6 and 2.7, enable elliptic-curve support in the
+Postfix SMTP server. This is the default with Postfix
+&ge; 2.8. Note, however, that elliptic-curve support may be disabled
+by the vendor, as in some versions of RedHat Linux. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Postfix 2.6 &amp; 2.7 only. EECDH is on by default with Postfix &ge; 2.8.
+ # The default grade is "auto" with Postfix &ge; 3.2.
+ smtpd_tls_eecdh_grade = strong
+</pre>
+</blockquote>
+
+<h3> EDH Client support (Postfix &ge; 2.2, all supported OpenSSL
+versions) </h3>
+
+<p> This works "out of the box" without additional configuration. </p>
+
+<h3> EDH Server support (Postfix &ge; 2.2, all supported OpenSSL
+versions) </h3>
+
+<p> Optionally generate non-default Postfix SMTP server EDH parameters
+for improved security against pre-computation attacks and for
+compatibility with Debian-patched Exim SMTP clients that require a
+&ge; 2048-bit length for the non-export prime. </p>
+
+<p> With Postfix &ge; 3.7 built against OpenSSL version is 3.0.0 or later, when
+the value of smtpd_tls_dh1024_param_file is either empty or "<b>auto</b>", the
+EDH parameter selection is delegated to the OpenSSL library, which selects
+appropriate parameters based on the TLS handshake. This choice is likely to be
+the most interoperable with SMTP clients using various TLS libraries, and
+custom local parameters are no longer recommended when using Postfix &ge; 3.7
+built against OpenSSL 3.0.0. Just leave smtpd_tls_dh1024_param_file at its
+default value (both in main.cf(5) and any master.cf(5) overrides, and let
+OpenSSL do the work. </p>
+
+<p> Otherwise, execute as root (prime group generation can take a
+few seconds to a few minutes): </p>
+
+<blockquote>
+<pre>
+# cd /etc/postfix
+# umask 022
+# openssl dhparam -out dh512.tmp 512 &amp;&amp; mv dh512.tmp dh512.pem
+# openssl dhparam -out dh1024.tmp 1024 &amp;&amp; mv dh1024.tmp dh1024.pem
+# openssl dhparam -out dh2048.tmp 2048 &amp;&amp; mv dh2048.tmp dh2048.pem
+# chmod 644 dh512.pem dh1024.pem dh2048.pem
+</pre>
+</blockquote>
+
+<p> The Postfix SMTP server EDH parameter files are not secret,
+after all these parameters are sent to all remote SMTP clients in
+the clear. Mode 0644 is appropriate. </p>
+
+<p> You can improve security against pre-computation attacks further
+by regenerating the Postfix SMTP server EDH parameters periodically
+(an hourly or daily cron job running the above commands as root can
+automate this task). </p>
+
+<p> Once the parameters are in place, update main.cf as follows: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_dh1024_param_file = ${config_directory}/dh2048.pem
+ smtpd_tls_dh512_param_file = ${config_directory}/dh512.pem
+</pre>
+</blockquote>
+
+<p> If some of your MSA clients don't support 2048-bit EDH, you may
+need to adjust the submission entry in master.cf accordingly: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ submission inet n - n - - smtpd
+ # Some submission clients may not yet do 2048-bit EDH, if such
+ # clients use your MSA, configure 1024-bit EDH instead. However,
+ # as of mid-2015, many submission clients no longer accept primes
+ # with less than 2048-bits. Each site needs to determine which
+ # type of client is more important to support.
+ -o smtpd_tls_dh1024_param_file=${config_directory}/dh1024.pem
+ -o smtpd_tls_security_level=encrypt
+ -o smtpd_sasl_auth_enable=yes
+ ...
+</pre>
+</blockquote>
+
+<h2><a name="test">How can I see that a connection has forward
+secrecy? </a> </h2>
+
+<p> Postfix can be configured to report information about the
+negotiated cipher, the corresponding key lengths, and the remote
+peer certificate or public-key verification status. </p>
+
+<ul>
+
+<li> <p> With "smtp_tls_loglevel = 1" and "smtpd_tls_loglevel = 1",
+the Postfix SMTP client and server will log TLS connection information
+to the maillog file. The general logfile format is shown below.
+With TLS 1.3 there may be additional properties logged after the
+cipher name and bits. </p>
+
+<blockquote>
+<pre>
+postfix/smtp[<i>process-id</i>]: Untrusted TLS connection established
+to host.example.com[192.168.0.2]:25: TLSv1 with cipher <i>cipher-name</i>
+(<i>actual-key-size</i>/<i>raw-key-size</i> bits)
+
+postfix/smtpd[<i>process-id</i>]: Anonymous TLS connection established
+from host.example.com[192.168.0.2]: TLSv1 with cipher <i>cipher-name</i>
+(<i>actual-key-size</i>/<i>raw-key-size</i> bits)
+</pre>
+</blockquote>
+
+<li> <p> With "smtpd_tls_received_header = yes", the Postfix SMTP
+server will record TLS connection information in the Received:
+header in the form of comments (text inside parentheses). The general
+format depends on the smtpd_tls_ask_ccert setting. With TLS 1.3 there
+may be additional properties logged after the cipher name and bits. </p>
+
+<blockquote>
+<pre>
+Received: from host.example.com (host.example.com [192.168.0.2])
+ (using TLSv1 with cipher <i>cipher-name</i>
+ (<i>actual-key-size</i>/<i>raw-key-size</i> bits))
+ (Client CN "host.example.com", Issuer "John Doe" (not verified))
+
+Received: from host.example.com (host.example.com [192.168.0.2])
+ (using TLSv1 with cipher <i>cipher-name</i>
+ (<i>actual-key-size</i>/<i>raw-key-size</i> bits))
+ (No client certificate requested)
+</pre>
+</blockquote>
+
+<p> TLS 1.3 examples. Some of the new attributes may not appear when not
+applicable or not available in older versions of the OpenSSL library. </p>
+
+<blockquote>
+<pre>
+Received: from localhost (localhost [127.0.0.1])
+ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256)
+ (No client certificate requested)
+
+Received: from localhost (localhost [127.0.0.1])
+ (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256)
+ (Client CN "example.org", Issuer "example.org" (not verified))
+</pre>
+</blockquote>
+
+<ul>
+<li> <p> The "key-exchange" attribute records the type of "Diffie-Hellman"
+group used for key agreement. Possible values include "DHE", "ECDHE", "X25519"
+and "X448". With "DHE", the bit size of the prime will be reported in
+parentheses after the algorithm name, with "ECDHE", the curve name. </p>
+
+<li> <p> The "server-signature" attribute shows the public key signature
+algorithm used by the server. With "RSA-PSS", the bit size of the modulus will
+be reported in parentheses. With "ECDSA", the curve name. If, for example,
+the server has both an RSA and an ECDSA private key and certificate, it will be
+possible to track which one was used for a given connection. </p>
+
+<li> <p> The new "server-digest" attribute records the digest algorithm used by
+the server to prepare handshake messages for signing. The Ed25519 and Ed448
+signature algorithms do not make use of such a digest, so no "server-digest"
+will be shown for these signature algorithms. </p>
+
+<li> <p> When a client certificate is requested with "smtpd_tls_ask_ccert" and
+the client uses a TLS client-certificate, the "client-signature" and
+"client-digest" attributes will record the corresponding properties of the
+client's TLS handshake signature. </p> </ul>
+
+</ul>
+
+<p> The next sections will explain what <i>cipher-name</i>,
+<i>key-size</i>, and peer verification status information to expect.
+</p>
+
+<h2><a name="ciphers"> What ciphers provide forward secrecy? </a> </h2>
+
+<p> There are dozens of ciphers that support forward secrecy. What
+follows is the beginning of a list of 51 ciphers available with
+OpenSSL 1.0.1e. The list is sorted in the default Postfix preference
+order. It excludes null ciphers that only authenticate and don't
+encrypt, together with export and low-grade ciphers whose encryption
+is too weak to offer meaningful secrecy. The first column shows the
+cipher name, and the second shows the key exchange method. </p>
+
+<blockquote>
+<pre>
+$ openssl ciphers -v \
+ 'aNULL:-aNULL:kEECDH:kEDH:+RC4:!eNULL:!EXPORT:!LOW:@STRENGTH' |
+ awk '{printf "%-32s %s\n", $1, $3}'
+AECDH-AES256-SHA Kx=ECDH
+ECDHE-RSA-AES256-GCM-SHA384 Kx=ECDH
+ECDHE-ECDSA-AES256-GCM-SHA384 Kx=ECDH
+ECDHE-RSA-AES256-SHA384 Kx=ECDH
+ECDHE-ECDSA-AES256-SHA384 Kx=ECDH
+ECDHE-RSA-AES256-SHA Kx=ECDH
+ECDHE-ECDSA-AES256-SHA Kx=ECDH
+ADH-AES256-GCM-SHA384 Kx=DH
+ADH-AES256-SHA256 Kx=DH
+ADH-AES256-SHA Kx=DH
+ADH-CAMELLIA256-SHA Kx=DH
+DHE-DSS-AES256-GCM-SHA384 Kx=DH
+DHE-RSA-AES256-GCM-SHA384 Kx=DH
+DHE-RSA-AES256-SHA256 Kx=DH
+...
+</pre>
+</blockquote>
+
+<p> To date, all ciphers that support forward secrecy have one of
+five values for the first component of their OpenSSL name: "AECDH",
+"ECDHE", "ADH", "EDH" or "DHE". Ciphers that don't implement forward
+secrecy have names that don't start with one of these prefixes.
+This pattern is likely to persist until some new key-exchange
+mechanism is invented that also supports forward secrecy. </p>
+
+<p> The actual key length and raw algorithm key length
+are generally the same with non-export ciphers, but they may
+differ for the legacy export ciphers where the actual key
+is artificially shortened. </p>
+
+<p> Starting with TLS 1.3 the cipher name no longer contains enough
+information to determine which forward-secrecy scheme was employed,
+but TLS 1.3 <b>always</b> uses forward-secrecy. On the client side,
+up-to-date Postfix releases log additional information for TLS 1.3
+connections, reporting the signature and key exchange algorithms.
+Two examples below (the long single line messages are folded across
+multiple lines for readability): </p>
+
+<blockquote>
+<pre>
+postfix/smtp[<i>process-id</i>]:
+ Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+
+postfix/smtp[<i>process-id</i>]:
+ Untrusted TLS connection established to 127.0.0.1[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange ECDHE (P-256) server-signature ECDSA (P-256) server-digest SHA256
+</pre>
+</blockquote>
+
+<p> In the above connections, the "key-exchange" value records the
+"Diffie-Hellman" algorithm used for key agreement. The "server-signature" value
+records the public key algorithm used by the server to sign the key exchange.
+The "server-digest" value records any hash algorithm used to prepare the data
+for signing. With "ED25519" and "ED448", no separate hash algorithm is used.
+</p>
+
+<p> Examples of Postfix SMTP server logging: </p>
+
+<blockquote>
+<pre>
+postfix/smtpd[<i>process-id</i>]:
+ Untrusted TLS connection established from localhost[127.0.0.1]:25:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+
+postfix/smtpd[<i>process-id</i>]:
+ Anonymous TLS connection established from localhost[127.0.0.1]:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ server-signature RSA-PSS (2048 bits) server-digest SHA256
+
+postfix/smtpd[<i>process-id</i>]:
+ Anonymous TLS connection established from localhost[127.0.0.1]:
+ TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ server-signature ED25519
+</pre>
+</blockquote>
+
+<p> Note that Postfix &ge; 3.4 server logging may also include a
+"to <i>sni-name</i>" element to record the use of an alternate
+server certificate chain for the connection in question. This happens
+when the client uses the TLS SNI extension, and the server selects
+a non-default certificate chain based on the client's SNI value:
+</p>
+
+<blockquote>
+<pre>
+postfix/smtpd[<i>process-id</i>]:
+ Untrusted TLS connection established from client.example[192.0.2.1]
+ to server.example: TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits)
+ key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256
+ client-signature ECDSA (P-256) client-digest SHA256
+</pre>
+</blockquote>
+
+<h2><a name="status"> What do "Anonymous", "Untrusted", etc. in
+Postfix logging mean? </a> </h2>
+
+<p> The verification levels below are subject to man-in-the-middle
+attacks to different degrees. If such attacks are a concern, then
+the SMTP client will need to authenticate the remote SMTP server
+in a sufficiently-secure manner. For example, by the fingerprint
+of a (CA or leaf) public key or certificate. Remember that
+conventional PKI relies on many trusted parties and is easily
+subverted by a state-funded adversary. </p>
+
+<dl>
+
+<dt><b>Anonymous</b> (no peer certificate)</dt>
+
+<dd> <p> <b> Postfix SMTP client:</b> With opportunistic TLS (the "may" security level) the Postfix
+SMTP client does not verify any information in the peer certificate.
+In this case it enables and prefers anonymous cipher suites in which
+the remote SMTP server does not present a certificate (these ciphers
+offer forward secrecy of necessity). When the remote SMTP server
+also supports anonymous TLS, and agrees to such a cipher suite, the
+verification status will be logged as "Anonymous". </p> </dd>
+
+<dd> <p> <b> Postfix SMTP server:</b> This is by far most common,
+as client certificates are optional, and the Postfix SMTP server
+does not request client certificates by default (see smtpd_tls_ask_ccert).
+Even when client certificates are requested, the remote SMTP client
+might not send a certificate. Unlike the Postfix SMTP client, the
+Postfix SMTP server "anonymous" verification status does not imply
+that the cipher suite is anonymous, which corresponds to the
+<i>server</i> not sending a certificate. </p> </dd>
+
+<dt><b>Untrusted</b> (peer certificate not signed by trusted CA)</dt>
+
+<dd>
+
+<p> <b> Postfix SMTP client:</b> The remote SMTP server presented
+a certificate, but the Postfix SMTP client was unable to check the
+issuing CA signature. With opportunistic TLS this is common with
+remote SMTP servers that don't support anonymous cipher suites.
+</p>
+
+<p> <b> Postfix SMTP server:</b> The remote SMTP client presented
+a certificate, but the Postfix SMTP server was unable to check the
+issuing CA signature. This can happen when the server is configured
+to request client certificates (see smtpd_tls_ask_ccert). </p>
+
+</dd>
+
+<dt><b>Trusted</b> (peer certificate signed by trusted CA, unverified
+peer name)</dt>
+
+<dd>
+
+<p> <b> Postfix SMTP client:</b> The remote SMTP server's certificate
+was signed by a CA that the Postfix SMTP client trusts, but either
+the client was not configured to verify the destination server name
+against the certificate, or the server certificate did not contain
+any matching names. This is common with opportunistic TLS
+(smtp_tls_security_level is "may" or else "dane" with no usable
+TLSA DNS records) when the Postfix SMTP client's trusted CAs can
+verify the authenticity of the remote SMTP server's certificate,
+but the client is not configured or unable to verify the server
+name. </p>
+
+<p> <b> Postfix SMTP server:</b> The remote SMTP client certificate
+was signed by a CA that the Postfix SMTP server trusts. The Postfix
+SMTP server never verifies the remote SMTP client name against the
+names in the client certificate. Since the client chooses to connect
+to the server, the Postfix SMTP server has no expectation of a
+particular client hostname. </p>
+
+</dd>
+
+<dt><b>Verified</b> (peer certificate signed by trusted CA and
+verified peer name; or: peer certificate with expected public-key
+or certificate fingerprint)</dt>
+
+<dd>
+
+<p> <b> Postfix SMTP client:</b> The remote SMTP server's certificate
+was signed by a CA that the Postfix SMTP client trusts, and the
+certificate name matches the destination or server name(s). The
+Postfix SMTP client was configured to require a verified name,
+otherwise the verification status would have been just "Trusted".
+</p>
+
+<p> <b> Postfix SMTP client:</b> The "Verified" status may also
+mean that the Postfix SMTP client successfully matched the expected
+fingerprint against the remote SMTP server public key or certificate.
+The expected fingerprint may come from smtp_tls_policy_maps or from
+TLSA (secure) DNS records. The Postfix SMTP client ignores the CA
+signature. </p>
+
+<p> <b> Postfix SMTP server:</b> The status is never "Verified",
+because the Postfix SMTP server never verifies the remote SMTP
+client name against the names in the client certificate, and because
+the Postfix SMTP server does not expect a specific fingerprint in
+the client public key or certificate. </p>
+
+</dd>
+
+</dl>
+
+<h2><a name="credits">Credits </a> </h2>
+
+<ul>
+
+<li> TLS support for Postfix was originally developed by Lutz
+J&auml;nicke at Cottbus Technical University.
+
+<li> Wietse Venema adopted and restructured the code and documentation.
+
+<li> Viktor Dukhovni implemented support for many subsequent TLS
+features, including EECDH, and authored the initial version of this
+document.
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/INSTALL.html b/proto/INSTALL.html
new file mode 100644
index 0000000..71bcc4f
--- /dev/null
+++ b/proto/INSTALL.html
@@ -0,0 +1,1676 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Installation From Source Code </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Installation From Source Code </h1>
+
+<hr>
+
+<h2> <a name="1">1 - Purpose of this document</a> </h2>
+
+<p> If you are using a pre-compiled version of Postfix, you should
+start with BASIC_CONFIGURATION_README and the general documentation
+referenced by it. INSTALL is only a bootstrap document to get
+Postfix up and running from scratch with the minimal number of
+steps; it should not be considered part of the general documentation.
+</p>
+
+<p> This document describes how to build, install and configure a
+Postfix system so that it can do one of the following: </p>
+
+<ul>
+
+<li> Send mail only, without changing an existing Sendmail
+installation.
+
+<li> Send and receive mail via a virtual host interface, still
+without any change to an existing Sendmail installation.
+
+<li> Run Postfix instead of Sendmail.
+
+</ul>
+
+<p> Topics covered in this document: </p>
+
+<ol>
+
+<li> <a href="#1">Purpose of this document</a>
+
+<li> <a href="#2">Typographical conventions</a>
+
+<li> <a href="#3">Documentation</a>
+
+<li> <a href="#4">Building on a supported system</a>
+
+<li> <a href="#5">Porting Postfix to an unsupported system</a>
+
+<li> <a href="#install">Installing the software after successful
+compilation </a>
+
+<li> <a href="#send_only">Configuring Postfix to send mail
+only </a>
+
+<li> <a href="#send_receive">Configuring Postfix to send and
+receive mail via virtual interface </a>
+
+<li> <a href="#replace">Running Postfix instead of Sendmail</a>
+
+<li> <a href="#mandatory">Mandatory configuration file edits</a>
+
+<li> <a href="#hamlet">To chroot or not to chroot</a>
+
+<li> <a href="#care">Care and feeding of the Postfix system</a>
+
+</ol>
+
+<h2> <a name="2">2 - Typographical conventions</a> </h2>
+
+<p> In the instructions below, a command written as </p>
+
+<blockquote>
+<pre>
+# command
+</pre>
+</blockquote>
+
+<p> should be executed as the superuser. </p>
+
+<p> A command written as </p>
+
+<blockquote>
+<pre>
+$ command
+</pre>
+</blockquote>
+
+<p> should be executed as an unprivileged user. </p>
+
+<h2> <a name="3">3 - Documentation</a> </h2>
+
+<p> Documentation is available as README files (start with the file
+README_FILES/AAAREADME), as HTML web pages (point your browser to
+"html/index.html") and as UNIX-style manual pages. </p>
+
+<p> You should view the README files with a pager such as more(1)
+or less(1), because the files use backspace characters in order to
+produce <b>bold</b> font. To print a README file without backspace
+characters, use the col(1) command. For example: </p>
+
+<blockquote>
+<pre>
+$ col -bx &lt;file | lpr
+</pre>
+</blockquote>
+
+<p> In order to view the manual pages before installing Postfix,
+point your MANPATH environment variable to the "man" subdirectory;
+be sure to use an absolute path. </p>
+
+<blockquote>
+<pre>
+$ export MANPATH; MANPATH="`pwd`/man:$MANPATH"
+$ setenv MANPATH "`pwd`/man:$MANPATH"
+</pre>
+</blockquote>
+
+<p> Of particular interest is the postconf(5) manual page that
+lists all the 500+ configuration parameters. The HTML version of
+this text makes it easy to navigate around. </p>
+
+<p> All Postfix source files have their own built-in manual page.
+Tools to extract those embedded manual pages are available in the
+mantools directory. </p>
+
+<h2> <a name="4">4 - Building on a supported system</a> </h2>
+
+<p> Postfix development happens on FreeBSD and MacOS X, with regular
+tests on Linux (Fedora, Ubuntu) and Solaris. Support for other
+systems relies on feedback from their users, and may not always be
+up-to-date. </p>
+
+<p> OpenBSD is partially supported. The libc resolver does not
+implement the documented "internal resolver options which are [...]
+set by changing fields in the _res structure" (documented in the
+OpenBSD 5.6 resolver(3) manpage). This results in too many DNS
+queries, and false positives for queries that should fail. </p>
+
+<!--
+
+<p> At some point in time, a version of Postfix was supported on: </p>
+
+<blockquote>
+<p>
+AIX 3.2.5, 4.1.x, 4.2.0, 4.3.x, 5.2 <br>
+BSD/OS 2.x, 3.x, 4.x <br>
+FreeBSD 2.x .. 9.x <br>
+HP-UX 9.x, 10.x, 11.x <br>
+IRIX 5.x, 6.x <br>
+Linux Debian 1.3.1 and later <br>
+Linux RedHat 3.x (January 2004) and later <br>
+Linux Slackware 3.x and later <br>
+Linux SuSE 5.x and later <br>
+Linux Ubuntu 4.10 and later<br>
+Mac OS X <br>
+NEXTSTEP 3.x <br>
+NetBSD 1.x and later <br>
+OPENSTEP 4.x <br>
+OSF1.V3 - OSF1.V5 (Digital UNIX) <br>
+Reliant UNIX 5.x <br>
+SunOS 4.1.4 (March 2007) <br>
+SunOS 5.4 - 5.10 (Solaris 2.4..10) <br>
+Ultrix 4.x (well, that was long ago) <br>
+</p>
+</blockquote>
+
+<p> or something closely resemblant. </p>
+
+-->
+
+<p> Overview of topics: </p>
+
+<ul>
+
+<li><a href="#build_first">4.1 - Getting started</a>
+
+<li><a href="#build_cc">4.2 - What compiler to use</a>
+
+<li><a href="#build_pie">4.3 - Building with Postfix position-independent
+executables (Postfix &ge; 3.0)</a>
+
+<li><a href="#build_dll">4.4 - Building with Postfix dynamically-linked
+libraries and database plugins (Postfix &ge; 3.0)</a>
+
+<li><a href="#build_opt">4.5 - Building with optional features</a>
+
+<li><a href="#build_over">4.6 - Overriding built-in parameter default
+settings</a>
+
+<li><a href="#build_other">4.7 - Overriding other compile-time
+features</a>
+
+<li><a href="#build_proc">4.8 - Support for thousands of processes</a>
+
+<li><a href="#build_final">4.9 - Compiling Postfix, at last</a>
+
+</ul>
+
+
+<h3><a name="build_first">4.1 - Getting started</a> </h3>
+
+<p> On Solaris, the "make" command and other development utilities
+are in /usr/ccs/bin, so you MUST have /usr/ccs/bin in your command
+search path. If these files do not exist, you need to install the
+development packages first. </p>
+
+<p> If you need to build Postfix for multiple architectures from a
+single source-code tree, use the "lndir" command to build a shadow
+tree with symbolic links to the source files. </p>
+
+<p> If at any time in the build process you get messages like: "make:
+don't know how to ..." you should be able to recover by running
+the following command from the Postfix top-level directory: </p>
+
+<blockquote>
+<pre>
+$ make -f Makefile.init makefiles
+</pre>
+</blockquote>
+
+<p> If you copied the Postfix source code after building it on another
+machine, it is a good idea to cd into the top-level directory and
+first do this:</p>
+
+<blockquote>
+<pre>
+$ make tidy
+</pre>
+</blockquote>
+
+<p> This will get rid of any system dependencies left over from
+compiling the software elsewhere. </p>
+
+<h3><a name="build_cc">4.2 - What compiler to use</a></h3>
+
+<p> To build with GCC, or with the native compiler if people told me
+that is better for your system, just cd into the top-level Postfix
+directory of the source tree and type: </p>
+
+<blockquote>
+<pre>
+$ make
+</pre>
+</blockquote>
+
+<p> To build with a non-default compiler, you need to specify the name
+of the compiler. Here are a few examples: </p>
+
+<blockquote>
+<pre>
+$ make makefiles CC=/opt/SUNWspro/bin/cc (Solaris)
+$ make
+
+$ make makefiles CC="/opt/ansic/bin/cc -Ae" (HP-UX)
+$ make
+
+$ make makefiles CC="purify cc"
+$ make
+</pre>
+</blockquote>
+
+<p> and so on. In some cases, optimization will be turned off
+automatically. </p>
+
+<h3><a name="build_pie">4.3 - Building with Postfix position-independent
+executables (Postfix &ge; 3.0)</a> </h3>
+
+<p> On some systems Postfix can be built with Position-Independent
+Executables. PIE is used by the ASLR exploit mitigation technique
+(ASLR = Address-Space Layout Randomization): </p>
+
+<blockquote>
+<pre>
+$ make makefiles pie=yes ...other arguments...
+</pre>
+</blockquote>
+
+<p> (Specify "make makefiles pie=no" to explicitly disable Postfix
+position-independent executable support). </p>
+
+<p> Postfix PIE support appears to work on Fedora Core 20, Ubuntu
+14.04, FreeBSD 9 and 10, and NetBSD 6 (all with the default system
+compilers). </p>
+
+<p> Whether the "pie=yes" above has any effect depends on the
+compiler. Some compilers always produce PIE executables, and some
+may even complain that the Postfix build option is redundant. </p>
+
+<h3><a name="build_dll">4.4 - Building with Postfix dynamically-linked
+libraries and database plugins (Postfix &ge; 3.0)</a> </h3>
+
+<p> Postfix dynamically-linked library and database plugin support
+exists for recent versions of Linux, FreeBSD and MacOS X.
+Dynamically-linked library builds may become the default at some
+point in the future. </p>
+
+<p> Overview of topics: </p>
+
+<ul>
+
+<li><a href="#shared_enable">4.4.1 Turning on Postfix dynamically-linked
+library support</a>
+
+<li><a href="#dynamicmaps_enable">4.4.2 Turning on Postfix database-plugin
+support</a>
+
+<li><a href="#shared_custom">4.4.3 Customizing Postfix dynamically-linked
+libraries and database plugins</a>
+
+<li><a href="#shared_tips">4.4.4 Tips for distribution maintainers</a>
+
+</ul>
+
+<p> Note: directories with Postfix dynamically-linked libraries
+or database plugins should contain only postfix-related files.
+Postfix dynamically-linked libraries and database plugins should
+not be installed in a "public" system directory such as /usr/lib
+or /usr/local/lib. Linking Postfix dynamically-linked library or
+database-plugin files into non-Postfix programs is not supported.
+Postfix dynamically-linked libraries and database plugins implement
+a Postfix-internal API that changes without maintaining compatibility.
+</p>
+
+<h4><a name="shared_enable"> 4.4.1 Turning on Postfix dynamically-linked
+library support </a></h4>
+
+<p> Postfix can be built with Postfix dynamically-linked libraries
+(files typically named <tt>libpostfix-*.so</tt>). Postfix
+dynamically-linked libraries add minor run-time overhead and result
+in significantly-smaller Postfix executable files. </p>
+
+<p> Specify "shared=yes" on the "make makefiles" command line to
+build Postfix with dynamically-linked library support. </p>
+
+<blockquote>
+<pre>
+$ make makefiles shared=yes ...other arguments...
+$ make
+</pre>
+</blockquote>
+
+<p> (Specify "make makefiles shared=no" to explicitly disable Postfix
+dynamically-linked library support). </p>
+
+<p> This installs dynamically-linked libraries in $shlib_directory,
+typically /usr/lib/postfix or /usr/local/lib/postfix, with file
+names libpostfix-<i>name</i>.so, where the <i>name</i> is a source-code
+directory name such as "util" or "global". </p>
+
+<p> See section 4.4.3 "<a href="#shared_custom">Customizing Postfix
+dynamically-linked libraries and database plugins</a>" below for
+how to customize the Postfix dynamically-linked library location,
+including support to upgrade a running mail system safely. </p>
+
+<h4><a name="dynamicmaps_enable"> 4.4.2 Turning on Postfix
+database-plugin support </a></h4>
+
+<p> Additionally, Postfix can be built to support dynamic loading
+of Postfix database clients (database plugins) with the Debian-style
+dynamicmaps feature. Postfix 3.0 supports dynamic loading of cdb:,
+ldap:, lmdb:, mysql:, pcre:, pgsql:, sdbm:, and sqlite: database
+clients. Dynamic loading is useful when you distribute or install
+pre-compiled Postfix packages. </p>
+
+<p> Specify "dynamicmaps=yes" on the "make makefiles" command line
+to build Postfix with support to dynamically load Postfix database
+clients with the Debian-style dynamicmaps feature.
+</p>
+
+<blockquote>
+<pre>
+$ make makefiles dynamicmaps=yes ...other arguments...
+$ make
+</pre>
+</blockquote>
+
+<p> (Specify "make makefiles dynamicmaps=no" to explicitly disable
+Postfix database-plugin support). </p>
+
+<p> This implicitly enables dynamically-linked library support,
+installs the configuration file dynamicmaps.cf in $meta_directory
+(usually, /etc/postfix or /usr/local/etc/postfix), and installs
+database plugins in $shlib_directory (see above). Database plugins
+are named postfix-<i>type</i>.so where the <i>type</i> is a database
+type such as "cdb" or "ldap". </p>
+
+<blockquote>
+
+<p> NOTE: The Postfix 3.0 build procedure expects that you specify
+database library dependencies with variables named AUXLIBS_CDB,
+AUXLIBS_LDAP, etc. With Postfix 3.0 and later, the old AUXLIBS
+variable still supports building a statically-loaded database client,
+but only the new AUXLIBS_CDB etc. variables support building a
+dynamically-loaded or statically-loaded CDB etc. database client.
+See CDB_README, LDAP_README, etc. for details. </p>
+
+<p> Failure to follow this advice will defeat the purpose of dynamic
+database client loading. Every Postfix executable file will have
+database library dependencies. And that was exactly what dynamic
+database client loading was meant to avoid. </p>
+
+</blockquote>
+
+<p> See the next section for how to customize the location and
+version of Postfix database plugins and the location of the file
+dynamicmaps.cf. </p>
+
+<h4><a name="shared_custom"> 4.4.3 Customizing Postfix dynamically-linked
+libraries and database plugins </a></h4>
+
+<h5> Customizing build-time and run-time options for Postfix
+dynamically-linked libraries and database plugins </h5>
+
+<p> The build-time environment variables SHLIB_CFLAGS, SHLIB_RPATH,
+and SHLIB_SUFFIX provide control over how Postfix libraries and
+plugins are compiled, linked, and named.
+
+<blockquote>
+<pre>
+$ make makefiles SHLIB_CFLAGS=flags SHLIB_RPATH=rpath SHLIB_SUFFIX=suffix ...other arguments...
+$ make
+</pre>
+</blockquote>
+
+<p> See section 4.7 "<a href="#build_other">Overriding other
+compile-time features</a>" below for details. </p>
+
+<h5> Customizing the location of Postfix dynamically-linked libraries
+and database plugins </h5>
+
+<p> As a reminder, the directories with Postfix dynamically-linked
+libraries or database plugins should contain only Postfix-related
+files. Linking these files into other programs is not supported.
+</p>
+
+<p> To override the default location of Postfix dynamically-linked
+libraries and database plugins specify, for example: </p>
+
+<blockquote>
+<pre>
+$ make makefiles shared=yes shlib_directory=/usr/local/lib/postfix ...
+</pre>
+</blockquote>
+
+<p> If you intend to upgrade Postfix without stopping the mail
+system, then you should append the Postfix release version to the
+shlib_directory pathname, to eliminate the possibility that programs
+will link with dynamically-linked libraries or database plugins
+from the wrong Postfix version. For example: </p>
+
+<blockquote>
+<pre>
+$ make makefiles shared=yes \
+ shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ...
+</pre>
+</blockquote>
+
+<p> The command "make makefiles name=value..." will replace the
+string MAIL_VERSION at the end of a configuration parameter value
+with the Postfix release version. Do not try to specify something
+like $mail_version on this command line. This produces inconsistent
+results with different versions of the make(1) command. </p>
+
+<p> You can change the shlib_directory setting after Postfix is
+built, with "make install" or "make upgrade". However, you may have
+to run ldconfig if you change shlib_directory after Postfix is built
+(the symptom is that Postfix programs fail because the run-time
+linker cannot find the files libpostfix-*.so). No ldconfig command
+is needed if you keep the files libpostfix-*.so in the compiled-in
+default $shlib_directory location. </p>
+
+<blockquote>
+<pre>
+# make upgrade shlib_directory=/usr/local/lib/postfix ...
+# make install shlib_directory=/usr/local/lib/postfix ...
+</pre>
+</blockquote>
+
+<p> To append the Postfix release version to the pathname if you
+intend to upgrade Postfix without stopping the mail system: </p>
+
+<blockquote>
+<pre>
+# make upgrade shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ...
+# make install shlib_directory=/usr/local/lib/postfix/MAIL_VERSION ...
+</pre>
+</blockquote>
+
+<p> See also the comments above for appending MAIL_VERSION with
+the "make makefiles" command. </p>
+
+<h5> Customizing the location of dynamicmaps.cf and other files
+</h5>
+
+<p> The meta_directory parameter has the same default setting as
+the config_directory parameter, typically /etc/postfix or
+/usr/local/etc/postfix. </p>
+
+<p> You can override the default meta_directory location at compile
+time or after Postfix is built. To override the default location
+at compile time specify, for example: </p>
+
+<blockquote>
+<pre>
+% make makefiles meta_directory=/usr/libexec/postfix ...
+</pre>
+</blockquote>
+
+<p> Here is a tip if you want to make a pathname dependent on the
+Postfix release version: the command "make makefiles name=value..."
+will replace the string MAIL_VERSION at the end of a configuration
+parameter value with the Postfix release version. Do not try to
+specify something like $mail_version on this command line. This
+produces inconsistent results with different versions of the make(1)
+command. </p>
+
+<p> You can override the meta_directory setting after Postfix is
+built, with "make install" or "make upgrade". </p>
+
+<blockquote>
+<pre>
+# make upgrade meta_directory=/usr/libexec/postfix ...
+# make install meta_directory=/usr/libexec/postfix ...
+</pre>
+</blockquote>
+
+<p> As with the command "make makefiles", the command "make
+install/upgrade name=value..." will replace the string MAIL_VERSION
+at the end of a configuration parameter value with the Postfix
+release version. Do not try to specify something like $mail_version
+on this command line. This produces inconsistent results with
+different versions of the make(1) command. </p>
+
+<h4><a name="shared_tips"> 4.4.4 Tips for distribution maintainers
+</a></h4>
+
+<ul>
+
+<li> <p> The shlib_directory parameter setting also provides the
+default directory for database plugin files with a relative pathname
+in the file dynamicmaps.cf. </p>
+
+<li> <p> The meta_directory parameter specifies the location of the
+files dynamicmaps.cf, postfix-files, and some multi-instance template
+files. The meta_directory parameter has the same default value as
+the config_directory parameter (typically, /etc/postfix or
+/usr/local/etc/postfix). For backwards compatibility with Postfix
+2.6 .. 2.11, specify "meta_directory = $daemon_directory" in main.cf
+before installing or upgrading Postfix, or specify "meta_directory
+= /path/name" on the "make makefiles", "make install" or "make
+upgrade" command line. </p>
+
+<li> <p> The configuration file dynamicmaps.cf will automatically
+include files under the directory dynamicmaps.cf.d, just like the
+configuration file postfix-files will automatically include files
+under the directory postfix-files.d. Thanks to this, you can install
+or deinstall a database plugin package without having to edit
+postfix-files or dynamicmaps.cf. Instead, you give that plugin its
+own configuration files under dynamicmaps.cf.d and postfix-files.d, and
+you add or remove those configuration files along with the database
+plugin dynamically-linked object. </p>
+
+<li> <p> Each configuration file under the directory dynamicmaps.cf.d
+must have the same format as the configuration file dynamicmaps.cf.
+There is no requirement that these configuration file *names* have a
+specific format. </p>
+
+<li> <p> Each configuration file under the directory postfix-files.d
+must have the same format as the configuration file postfix-files.
+There is no requirement that these configuration file *names* have a
+specific format. </p>
+
+</ul>
+
+<h3><a name="build_opt">4.5 - Building with optional features</a></h3>
+
+By default, Postfix builds as a mail system with relatively few
+bells and whistles. Support for third-party databases etc.
+must be configured when Postfix is compiled. The following documents
+describe how to build Postfix with support for optional features:
+
+<blockquote>
+<table border="1">
+
+<tr> <th>Optional feature </th> <th>Document </th> <th>Availability</th>
+</tr>
+
+<tr> <td> Berkeley DB database</td> <td>DB_README</td> <td> Postfix
+1.0 </td> </tr>
+
+<tr> <td> LMDB database</td> <td>LMDB_README</td> <td> Postfix
+2.11 </td> </tr>
+
+<tr> <td> LDAP database</td> <td>LDAP_README</td> <td> Postfix
+1.0 </td> </tr>
+
+<tr> <td> MySQL database</td> <td>MYSQL_README</td> <td> Postfix
+1.0 </td> </tr>
+
+<tr> <td> Perl compatible regular expression</td> <td>PCRE_README</td>
+<td> Postfix 1.0 </td> </tr>
+
+<tr> <td> PostgreSQL database</td> <td>PGSQL_README</td> <td>
+Postfix 2.0 </td> </tr>
+
+<tr> <td> SASL authentication </td> <td>SASL_README</td> <td>
+Postfix 1.0 </td> </tr>
+
+<tr> <td> SQLite database</td> <td>SQLITE_README</td> <td> Postfix
+2.8 </td> </tr>
+
+<tr> <td> STARTTLS session encryption </td> <td>TLS_README</td> <td>
+Postfix 2.2 </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> Note: IP version 6 support is compiled into Postfix on operating
+systems that have IPv6 support. See the IPV6_README file for details.
+</p>
+
+<h3><a name="build_over">4.6 - Overriding built-in parameter default
+settings</a></h3>
+
+<h4>4.6.1 - Postfix 3.0 and later </h4>
+
+<p> All Postfix configuration parameters can be changed by editing
+a Postfix configuration file, except for one: the parameter that
+specifies the location of Postfix configuration files. In order to
+build Postfix with a configuration directory other than /etc/postfix,
+use: </p>
+
+<blockquote>
+<pre>
+$ make makefiles config_directory=/some/where ...other arguments...
+$ make
+</pre>
+</blockquote>
+
+<p> The command "make makefiles name=value ..." will replace the
+string MAIL_VERSION at the end of a configuration parameter value
+with the Postfix release version. Do not try to specify something
+like $mail_version on this command line. This produces inconsistent
+results with different versions of the make(1) command. </p>
+
+<p> Parameters whose defaults can be specified in this way are
+listed below. See the postconf(5) manpage for a description
+(command: "<tt>nroff -man man/man5/postconf.5 | less</tt>"). </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th>parameter name</th> <th>typical default</th> </tr>
+
+<tr> <td>command_directory</td> <td>/usr/sbin</td> </tr>
+
+<tr> <td>config_directory</td> <td>/etc/postfix</td> </tr>
+
+<tr> <td>default_database_type</td> <td>hash</td> </tr>
+
+<tr> <td>daemon_directory</td> <td>/usr/libexec/postfix</td> </tr>
+
+<tr> <td>data_directory</td> <td>/var/lib/postfix</td> </tr>
+
+<tr> <td>html_directory</td> <td>no</td> </tr>
+
+<tr> <td>mail_spool_directory</td> <td>/var/mail</td> </tr>
+
+<tr> <td>mailq_path</td> <td>/usr/bin/mailq</td> </tr>
+
+<tr> <td>manpage_directory</td> <td>/usr/local/man</td> </tr>
+
+<tr> <td>meta_directory</td> <td>/etc/postfix</td> </tr>
+
+<tr> <td>newaliases_path</td> <td>/usr/bin/newaliases</td> </tr>
+
+<tr> <td>openssl_path</td> <td>openssl</td> </tr>
+
+<tr> <td>queue_directory</td> <td>/var/spool/postfix</td> </tr>
+
+<tr> <td>readme_directory</td> <td>no</td> </tr>
+
+<tr> <td>sendmail_path</td> <td>/usr/sbin/sendmail</td> </tr>
+
+<tr> <td>shlib_directory</td> <td>/usr/lib/postfix</td> </tr>
+
+</table>
+
+</blockquote>
+
+<h4>4.6.2 - All Postfix versions </h4>
+
+<p> All Postfix configuration parameters can be changed by editing
+a Postfix configuration file, except for one: the parameter that
+specifies the location of Postfix configuration files. In order to
+build Postfix with a configuration directory other than /etc/postfix,
+use: </p>
+
+<blockquote>
+<pre>
+$ make makefiles CCARGS='-DDEF_CONFIG_DIR=\"/some/where\"'
+$ make
+</pre>
+</blockquote>
+
+<p> IMPORTANT: Be sure to get the quotes right. These details matter
+a lot. </p>
+
+<p> Parameters whose defaults can be specified in this way are
+listed below. See the postconf(5) manpage for a description
+(command: "<tt>nroff -man man/man5/postconf.5 | less</tt>"). </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr><th> Macro name </th> <th>default value for</th> <th>typical
+default</th> </tr>
+
+<tr> <td>DEF_COMMAND_DIR</td> <td>command_directory</td>
+<td>/usr/sbin</td> </tr>
+
+<tr> <td>DEF_CONFIG_DIR</td> <td>config_directory</td>
+<td>/etc/postfix</td> </tr>
+
+<tr> <td>DEF_DB_TYPE</td> <td>default_database_type</td>
+<td>hash</td> </tr>
+
+<tr> <td>DEF_DAEMON_DIR</td> <td>daemon_directory</td>
+<td>/usr/libexec/postfix</td> </tr>
+
+<tr> <td>DEF_DATA_DIR</td> <td>data_directory</td>
+<td>/var/lib/postfix</td> </tr>
+
+<tr> <td>DEF_MAILQ_PATH</td> <td>mailq_path</td> <td>/usr/bin/mailq</td>
+</tr>
+
+<tr> <td>DEF_HTML_DIR</td> <td>html_directory</td>
+<td>no</td> </tr>
+
+<tr> <td>DEF_MANPAGE_DIR</td> <td>manpage_directory</td>
+<td>/usr/local/man</td> </tr>
+
+<tr> <td>DEF_NEWALIAS_PATH</td> <td>newaliases_path</td>
+<td>/usr/bin/newaliases</td> </tr>
+
+<tr> <td>DEF_QUEUE_DIR</td> <td>queue_directory</td>
+<td>/var/spool/postfix</td> </tr>
+
+<tr> <td>DEF_README_DIR</td> <td>readme_directory</td>
+<td>no</td> </tr>
+
+<tr> <td>DEF_SENDMAIL_PATH</td> <td>sendmail_path</td>
+<td>/usr/sbin/sendmail</td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> Note: the data_directory parameter (for caches and pseudo-random
+numbers) was introduced with Postfix version 2.5. </p>
+
+<h3><a name="build_other">4.7 - Overriding other compile-time
+features</a></h3>
+
+<p> The general method to override Postfix compile-time features
+is as follows: </p>
+
+<blockquote>
+<pre>
+$ make makefiles name=value name=value...
+$ make
+</pre>
+</blockquote>
+
+<p> The following is an extensive list of names and values. </p>
+
+<table border="1">
+
+<tr> <th colspan="2"> Name/Value </th> <th> Description </th> </tr>
+
+<tr> <td colspan="2"> AUXLIBS="object_library..."</td> <td> Specifies
+one or more non-default object libraries. Postfix 3.0 and later
+specify some of their database library dependencies with AUXLIBS_CDB,
+AUXLIBS_LDAP, AUXLIBS_LMDB, AUXLIBS_MYSQL, AUXLIBS_PCRE, AUXLIBS_PGSQL,
+AUXLIBS_SDBM, and AUXLIBS_SQLITE, respectively. </td> </tr>
+
+<tr> <td colspan="2"> CC=compiler_command</td> <td> Specifies a
+non-default compiler. On many systems, the default is <tt>gcc</tt>.
+</td> </tr>
+
+<tr> <td colspan="2"> CCARGS="compiler_arguments..."</td> <td>
+Specifies non-default compiler arguments, for example, a non-default
+<tt>include</tt> directory. The following directives turn
+off Postfix features at compile time:</td> </tr>
+
+<tr> <td> </td> <td> -DNO_DB </td> <td> Do not build with Berkeley
+DB support. By default, Berkeley DB support is compiled in on
+platforms that are known to support this feature. If you override
+this, then you probably should also override DEF_DB_TYPE as described
+in section 4.6. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_DNSSEC </td> <td> Do not build with DNSSEC
+support, even if the resolver library appears to support it. </td>
+</tr>
+
+<tr> <td> </td> <td> -DNO_DEVPOLL </td> <td> Do not build with
+Solaris <tt>/dev/poll</tt> support. By default, <tt>/dev/poll</tt>
+support is compiled in on Solaris versions that are known to support
+this feature. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_EPOLL </td> <td> Do not build with Linux
+EPOLL support. By default, EPOLL support is compiled in on platforms
+that are known to support this feature. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_EAI </td> <td> Do not build with EAI
+(SMTPUTF8) support. By default, EAI support is compiled in when
+the "icuuc" library and header files are found. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_INLINE </td> <td> Do not require support
+for C99 "inline" functions. Instead, implement argument typechecks
+for non-printf/scanf-like functions with ternary operators and
+unreachable code. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_IPV6 </td> <td> Do not build with IPv6
+support. By default, IPv6 support is compiled in on platforms that
+are known to have IPv6 support. Note: this directive is for debugging
+And testing only. It is not guaranteed to work on all platforms.
+If you don't want IPv6 support, set "inet_protocols = ipv4" in
+main.cf.
+</td> </tr>
+
+<tr> <td> </td> <td> -DNO_KQUEUE </td> <td> Do not build with FreeBSD
+/ NetBSD / OpenBSD / MacOSX KQUEUE support. By default, KQUEUE
+support is compiled in on platforms that are known to support it.
+</td> </tr>
+
+<tr> <td> </td> <td> -DNO_NIS </td> <td> Do not build with NIS or
+NISPLUS support. NIS is not available on some recent Linux
+distributions. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_NISPLUS </td> <td> Do not build with
+NISPLUS support. NISPLUS is not available on some recent Solaris
+distributions. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_PCRE </td> <td> Do not build with PCRE
+support. By default, PCRE support is compiled in when the
+<tt>pcre-config</tt> utility is installed. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_POSIX_GETPW_R </td> <td> Disable support
+for POSIX <tt>getpwnam_r/getpwuid_r</tt>. By default Postfix uses
+these where they are known to be available. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_RES_NCALLS </td> <td> Do not build with
+the threadsafe resolver(5) API (res_ninit() etc.). </td> </tr>
+
+<tr> <td> </td> <td> -DNO_SIGSETJMP </td> <td> Use
+<tt>setjmp()/longjmp()</tt> instead of <tt>sigsetjmp()/siglongjmp()</tt>.
+By default, Postfix uses <tt>sigsetjmp()/siglongjmp()</tt> when
+they are known to be available. </td> </tr>
+
+<tr> <td> </td> <td> -DNO_SNPRINTF </td> <td> Use <tt>sprintf()</tt>
+instead of <tt>snprintf()</tt>. By default, Postfix uses
+<tt>snprintf()</tt> except on ancient systems. </td> </tr>
+
+<tr> <td colspan="2"> DEBUG=debug_level </td> <td> Specifies a
+non-default compiler debugging level. The default is "<tt>-g</tt>".
+Specify DEBUG= to turn off debugging. </td> </tr>
+
+<tr> <td colspan="2"> OPT=optimization_level </td> <td> Specifies
+a non-default optimization level. The default is "<tt>-O</tt>".
+Specify OPT= to turn off optimization. </td> </tr>
+
+<tr> <td colspan="2"> POSTFIX_INSTALL_OPTS=-option... </td> <td>
+Specifies options for the <tt>postfix-install</tt> command, separated
+by whitespace. Currently, the only supported option is
+"<tt>-keep-build-mtime</tt>". </td> </tr>
+
+<tr> <td colspan="2"> SHLIB_CFLAGS=flags </td> <td> Specifies
+non-default compiler options for building Postfix dynamically-linked
+libraries and database plugins. The typical default is "-fPIC".
+</td> </tr>
+
+<tr> <td colspan="2"> SHLIB_RPATH=rpath </td> <td> Specifies
+a non-default runpath for Postfix dynamically-linked libraries. The
+typical default is "'-Wl,-rpath,${SHLIB_DIR}'". </td> </tr>
+
+<tr> <td colspan="2"> SHLIB_SUFFIX=suffix </td> <td> Specifies
+a non-default suffix for Postfix dynamically-linked libraries and
+database plugins. The typical default is "<tt>.so</tt>". </td>
+</tr>
+
+<tr> <td colspan="2"> WARN="warning_flags..." </td> <td> Specifies
+non-default compiler warning options for use when "<tt>make</tt>"
+is invoked in a source subdirectory only. </td>
+</tr>
+
+</table>
+
+<h3><a name="build_proc">4.8 - Support for thousands of processes</a></h3>
+
+<p> The number of connections that Postfix can manage simultaneously
+is limited by the number of processes that it can run. This number
+in turn is limited by the number of files and sockets that a single
+process can open. For example, the Postfix queue manager has a
+separate connection to each delivery process, and the anvil(8)
+server has one connection per smtpd(8) process. </p>
+
+<p> Postfix version 2.4 and later have no built-in limits on the
+number of open files or sockets, when compiled on systems that
+support one of the following: </p>
+
+<ul>
+
+<li> BSD kqueue(2) (FreeBSD 4.1, NetBSD 2.0, OpenBSD 2.9),
+
+<li> Solaris 8 /dev/poll,
+
+<li> Linux 2.6 epoll(4).
+
+</ul>
+
+
+<p> With other Postfix versions or operating systems, the number
+of file descriptors per process is limited by the value of the
+FD_SETSIZE macro. If you expect to run more than 1000 mail delivery
+processes, you may need to override the definition of the FD_SETSIZE
+macro to make select() work correctly: </p>
+
+<blockquote>
+<pre>
+$ make makefiles CCARGS=-DFD_SETSIZE=2048
+</pre>
+</blockquote>
+
+<p> Warning: the above has no effect on some Linux versions.
+Apparently, on these systems the FD_SETSIZE value can be changed
+only by using undocumented interfaces. Currently, that means
+including &lt;bits/types.h&gt; directly (which is not allowed) and
+overriding the __FD_SETSIZE macro. Beware, undocumented interfaces
+can change at any time and without warning. </p>
+
+<p> But wait, there is more: none of this will work unless the
+operating system is configured to handle thousands of connections.
+See the TUNING_README guide for examples of how to increase the
+number of open sockets or files. </p>
+
+<h3><a name="build_final">4.9 - Compiling Postfix, at last</a></h3>
+
+<p> If the command </p>
+
+<blockquote>
+<pre>
+$ make
+</pre>
+</blockquote>
+
+<p> is successful, then you can proceed to <a href="#install">install</a>
+Postfix (section 6).
+
+<p> If the command produces compiler error messages, it may be time
+to search the web or to ask the postfix-users@postfix.org mailing
+list, but be sure to search the mailing list archives first. Some
+mailing list archives are linked from http://www.postfix.org/. </p>
+
+<h2> <a name="5">5 - Porting Postfix to an unsupported system</a> </h2>
+
+<p> Each system type that Postfix knows is identified by a unique
+name. Examples: SUNOS5, FREEBSD4, and so on. When porting Postfix
+to a new system, the first step is to choose a SYSTEMTYPE name for
+the new system. You must use a name that includes at least the
+major version of the operating system (such as SUNOS4 or LINUX2),
+so that different releases of the same system can be supported
+without confusion. </p>
+
+<p> Add a case statement to the "makedefs" shell script in the
+source code top-level directory that recognizes the new system
+reliably, and that emits the right system-specific information.
+Be sure to make the code robust against user PATH settings; if the
+system offers multiple UNIX flavors (e.g. BSD and SYSV) be sure to
+build for the native flavor, instead of the emulated one. </p>
+
+<p> Add an "#ifdef SYSTEMTYPE" section to the central util/sys_defs.h
+include file. You may have to invent new feature macro names.
+Please choose sensible feature macro names such as HAS_DBM or
+FIONREAD_IN_SYS_FILIO_H.
+
+<p> I strongly recommend against using "#ifdef SYSTEMTYPE" in
+individual source files. While this may look like the quickest
+solution, it will create a mess when newer versions of the same
+SYSTEMTYPE need to be supported. You're likely to end up placing
+"#ifdef" sections all over the source code again. </p>
+
+<h2><a name="install">6 - Installing the software after successful
+compilation</a></h2>
+
+<p> This text describes how to install Postfix from source code.
+See the PACKAGE_README file if you are building a package for
+distribution to other systems. </p>
+
+<h3>6.1 - Save existing Sendmail binaries</h3>
+
+<p> <a name="save">IMPORTANT</a>: if you are REPLACING an existing
+Sendmail installation with Postfix, you may need to keep the old
+sendmail program running for some time in order to flush the mail
+queue. </p>
+
+<ul>
+
+<li> <p> Some systems implement a mail switch mechanism where
+different MTAs (Postfix, Sendmail, etc.) can be installed at the
+same time, while only one of them is actually being used. Examples
+of such switching mechanisms are the FreeBSD mailwrapper(8) or the
+Linux mail switch. In this case you should try to "flip" the switch
+to "Postfix" before installing Postfix. </p>
+
+<li> <p> If your system has no mail switch mechanism, execute the
+following commands (your sendmail, newaliases and mailq programs
+may be in a different place): </p>
+
+<pre>
+# mv /usr/sbin/sendmail /usr/sbin/sendmail.OFF
+# mv /usr/bin/newaliases /usr/bin/newaliases.OFF
+# mv /usr/bin/mailq /usr/bin/mailq.OFF
+# chmod 755 /usr/sbin/sendmail.OFF /usr/bin/newaliases.OFF \
+ /usr/bin/mailq.OFF
+</pre>
+
+</ul>
+
+<h3>6.2 - Create account and groups</h3>
+
+<p> Before you install Postfix for the first time you need to
+create an account and a group:</p>
+
+<ul>
+
+<li> <p> Create a user account "postfix" with a user id and group
+id that are not used by any other user account. Preferably, this
+is an account that no-one can log into. The account does not need
+an executable login shell, and needs no existing home directory.
+My password and group file entries look like this: </p>
+
+<blockquote>
+<pre>
+/etc/passwd:
+ postfix:*:12345:12345:postfix:/no/where:/no/shell
+
+/etc/group:
+ postfix:*:12345:
+</pre>
+</blockquote>
+
+<p> Note: there should be no whitespace before "postfix:". </p>
+
+<li> <p> Create a group "postdrop" with a group id that is not used
+by any other user account. Not even by the postfix user account.
+My group file entry looks like:
+
+<blockquote>
+<pre>
+/etc/group:
+ postdrop:*:54321:
+</pre>
+</blockquote>
+
+<p> Note: there should be no whitespace before "postdrop:". </p>
+
+</ul>
+
+<h3>6.3 - Install Postfix</h3>
+
+<p> To install or upgrade Postfix from compiled source code, run
+one of the following commands as the super-user:</p>
+
+<blockquote>
+<pre>
+# make install (interactive version, first time install)
+
+# make upgrade (non-interactive version, for upgrades)
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> The interactive version ("make install") asks for pathnames
+for Postfix data and program files, and stores your preferences in
+the main.cf file. <b> If you don't want Postfix to overwrite
+non-Postfix "sendmail", "mailq" and "newaliases" files, specify
+pathnames that end in ".postfix"</b>. </p>
+
+<li> <p> The non-interactive version ("make upgrade") needs the
+/etc/postfix/main.cf file from a previous installation. If the file
+does not exist, use interactive installation ("make install")
+instead. </p>
+
+<li> <p> If you specify name=value arguments on the "make install"
+or "make upgrade" command line, then these will take precedence
+over compiled-in default settings or main.cf settings. </p>
+
+<p> The command "make install/upgrade name=value ..." will replace
+the string MAIL_VERSION at the end of a configuration parameter
+value with the Postfix release version. Do not try to specify
+something like $mail_version on this command line. This produces
+inconsistent results with different versions of the make(1) command.
+</p>
+
+</ul>
+
+<h3>6.4 - Configure Postfix</h3>
+
+<p> Proceed to the section on how you wish to run Postfix on
+your particular machine: </p>
+
+<ul>
+
+<li> <p> <a href="#send_only">Send</a> mail only, without changing
+an existing Sendmail installation (section 7). </p>
+
+<li> <p> <a href="#send_receive">Send and receive</a> mail via a
+virtual host interface, still without any change to an existing
+Sendmail installation (section 8). </p>
+
+<li> <p> Run Postfix <a href="#replace">instead of</a> Sendmail
+(section 9). </p>
+
+</ul>
+
+<h2><a name="send_only">7 - Configuring Postfix to send mail
+only</a></h2>
+
+<p> If you are going to use Postfix to send mail only, there is no
+need to change your existing sendmail setup. Instead, set up your
+mail user agent so that it calls the Postfix sendmail program
+directly. </p>
+
+<p> Follow the instructions in the "<a href="#mandatory">Mandatory
+configuration file edits</a>" in section 10, and review the "<a
+href="#hamlet">To chroot or not to chroot</a>" text in section
+11. </p>
+
+<p> You MUST comment out the "smtp inet" entry in /etc/postfix/master.cf,
+in order to avoid conflicts with the real sendmail. Put a "#"
+character in front of the line that defines the smtpd service: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ #smtp inet n - n - - smtpd
+</pre>
+</blockquote>
+
+<p> Start the Postfix system: </p>
+
+<blockquote>
+<pre>
+# postfix start
+</pre>
+</blockquote>
+
+<p> or, if you feel nostalgic, use the Postfix sendmail command: </p>
+
+<blockquote>
+<pre>
+# sendmail -bd -qwhatever
+</pre>
+</blockquote>
+
+<p> and watch your maillog file for any error messages. The pathname
+is /var/log/maillog, /var/log/mail, /var/log/syslog, or something
+else. Typically, the pathname is defined in the /etc/syslog.conf
+file. </p>
+
+<blockquote>
+<pre>
+$ egrep '(reject|warning|error|fatal|panic):' /some/log/file
+</pre>
+</blockquote>
+
+<p> Note: the most important error message is logged first. Later
+messages are not as useful. </p>
+
+<p> In order to inspect the mail queue, use one of the following
+commands: </p>
+
+<blockquote>
+<pre>
+$ mailq
+
+$ sendmail -bp
+
+$ postqueue -p
+</pre>
+</blockquote>
+
+<p> See also the "<a href="#care">Care and feeding</a>" section 12
+below. </p>
+
+<h2><a name="send_receive">8 - Configuring Postfix to send and
+receive mail via virtual interface</a></h2>
+
+<p> Alternatively, you can use the Postfix system to send AND
+receive mail while leaving your Sendmail setup intact, by running
+Postfix on a virtual interface address. Simply configure your mail
+user agent to directly invoke the Postfix sendmail program. </p>
+
+<p> To create a virtual network interface address, study your
+system ifconfig manual page. The command syntax could be any
+of: </p>
+
+<blockquote>
+<pre>
+# <b>ifconfig le0:1 &lt;address&gt; netmask &lt;mask&gt; up</b>
+# <b>ifconfig en0 alias &lt;address&gt; netmask 255.255.255.255</b>
+</pre>
+</blockquote>
+
+<p> In the /etc/postfix/main.cf file, I would specify </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ myhostname = virtual.host.tld
+ inet_interfaces = $myhostname
+ mydestination = $myhostname
+</pre>
+</blockquote>
+
+<p> Follow the instructions in the "<a href="#mandatory">Mandatory
+configuration file edits</a>" in section 10, and review the "<a
+href="#hamlet">To chroot or not to chroot</a>" text in section
+11. </p>
+
+<p> Start the Postfix system: </p>
+
+<blockquote>
+<pre>
+# postfix start
+</pre>
+</blockquote>
+
+<p> or, if you feel nostalgic, use the Postfix sendmail command: </p>
+
+<blockquote>
+<pre>
+# sendmail -bd -qwhatever
+</pre>
+</blockquote>
+
+<p> and watch your maillog file for any error messages. The pathname
+is /var/log/maillog, /var/log/mail, /var/log/syslog, or something
+else. Typically, the pathname is defined in the /etc/syslog.conf
+file. </p>
+
+<blockquote>
+<pre>
+$ egrep '(reject|warning|error|fatal|panic):' /some/log/file
+</pre>
+</blockquote>
+
+<p> Note: the most important error message is logged first. Later
+messages are not as useful. </p>
+
+<p> In order to inspect the mail queue, use one of the following
+commands: </p>
+
+<blockquote>
+<pre>
+$ mailq
+
+$ sendmail -bp
+
+$ postqueue -p
+</pre>
+</blockquote>
+
+<p> See also the "<a href="#care">Care and feeding</a>" section 12
+below. </p>
+
+<h2><a name="replace">9 - Running Postfix instead of Sendmail</a></h2>
+
+<p> Prior to installing Postfix you should <a href="#save">save</a>
+any existing sendmail program files as described in section 6. Be
+sure to keep the old sendmail running for at least a couple days
+to flush any unsent mail. To do so, stop the sendmail daemon and
+restart it as: </p>
+
+<blockquote>
+<pre>
+# /usr/sbin/sendmail.OFF -q
+</pre>
+</blockquote>
+
+<p> Note: this is old sendmail syntax. Newer versions use separate
+processes for mail submission and for running the queue. </p>
+
+<p> After you have visited the "<a href="#mandatory">Mandatory
+configuration file edits</a>" section below, you can start the
+Postfix system with: </p>
+
+<blockquote>
+<pre>
+# postfix start
+</pre>
+</blockquote>
+
+<p> or, if you feel nostalgic, use the Postfix sendmail command: </p>
+
+<blockquote>
+<pre>
+# sendmail -bd -qwhatever
+</pre>
+</blockquote>
+
+<p> and watch your maillog file for any error messages. The pathname
+is /var/log/maillog, /var/log/mail, /var/log/syslog, or something
+else. Typically, the pathname is defined in the /etc/syslog.conf
+file. </p>
+
+<blockquote>
+<pre>
+$ egrep '(reject|warning|error|fatal|panic):' /some/log/file
+</pre>
+</blockquote>
+
+<p> Note: the most important error message is logged first. Later
+messages are not as useful. </p>
+
+<p> In order to inspect the mail queue, use one of the following
+commands: </p>
+
+<blockquote>
+<pre>
+$ mailq
+
+$ sendmail -bp
+
+$ postqueue -p
+</pre>
+</blockquote>
+
+<p> See also the "<a href="#care">Care and feeding</a>" section 12
+below. </p>
+
+<h2><a name="mandatory">10 - Mandatory configuration file edits</a></h2>
+
+<p> Note: the material covered in this section is covered in more
+detail in the BASIC_CONFIGURATION_README document. The information
+presented below is targeted at experienced system administrators.
+</p>
+
+<h3>10.1 - Postfix configuration files</h3>
+
+<p> By default, Postfix configuration files are in /etc/postfix.
+The two most important files are main.cf and master.cf; these files
+must be owned by root. Giving someone else write permission to
+main.cf or master.cf (or to their parent directories) means giving
+root privileges to that person. </p>
+
+<p> In /etc/postfix/main.cf, you will have to set up a minimal number
+of configuration parameters. Postfix configuration parameters
+resemble shell variables, with two important differences: the first
+one is that Postfix does not know about quotes like the UNIX shell
+does.</p>
+
+<p> You specify a configuration parameter as: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ parameter = value
+</pre>
+</blockquote>
+
+<p> and you use it by putting a "$" character in front of its name: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ other_parameter = $parameter
+</pre>
+</blockquote>
+
+<p> You can use $parameter before it is given a value (that is the
+second main difference with UNIX shell variables). The Postfix
+configuration language uses lazy evaluation, and does not look at
+a parameter value until it is needed at runtime. </p>
+
+<p> Whenever you make a change to the main.cf or master.cf file,
+execute the following command in order to refresh a running mail
+system: </p>
+
+<blockquote>
+<pre>
+# postfix reload
+</pre>
+</blockquote>
+
+<h3>10.2 - Default domain for unqualified addresses</h3>
+
+<p> First of all, you must specify what domain will be appended to an
+unqualified address (i.e. an address without @domain.tld). The
+"myorigin" parameter defaults to the local hostname, but that is
+probably OK only for very small sites. </p>
+
+<p> Some examples (use only one): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ myorigin = $myhostname (send mail as "user@$myhostname")
+ myorigin = $mydomain (send mail as "user@$mydomain")
+</pre>
+</blockquote>
+
+<h3>10.3 - What domains to receive locally</h3>
+
+<p> Next you need to specify what mail addresses Postfix should deliver
+locally. </p>
+
+<p> Some examples (use only one): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mydestination = $myhostname, localhost.$mydomain, localhost
+ mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
+ mydestination = $myhostname
+</pre>
+</blockquote>
+
+<p>The first example is appropriate for a workstation, the second
+is appropriate for the mailserver for an entire domain. The third
+example should be used when running on a virtual host interface.</p>
+
+<h3>10.4 - Proxy/NAT interface addresses </h3>
+
+<p> The proxy_interfaces parameter specifies all network addresses
+that Postfix receives mail on by way of a proxy or network address
+translation unit. You may specify symbolic hostnames instead of
+network addresses. </p>
+
+<p> IMPORTANT: You must specify your proxy/NAT external addresses
+when your system is a backup MX host for other domains, otherwise
+mail delivery loops will happen when the primary MX host is down.
+</p>
+
+<p> Example: host behind NAT box running a backup MX host. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ proxy_interfaces = 1.2.3.4 (the proxy/NAT external network address)
+</pre>
+</blockquote>
+
+<h3>10.5 - What local clients to relay mail from </h3>
+
+<p> If your machine is on an open network then you must specify
+what client IP addresses are authorized to relay their mail through
+your machine into the Internet. The default setting includes all
+subnetworks that the machine is attached to. This may give relay
+permission to too many clients. My own settings are: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mynetworks = 168.100.189.0/28, 127.0.0.0/8
+</pre>
+</blockquote>
+
+<h3>10.6 - What relay destinations to accept from strangers </h3>
+
+<p> If your machine is on an open network then you must also specify
+whether Postfix will forward mail from strangers. The default
+setting will forward mail to all domains (and subdomains of) what
+is listed in $mydestination. This may give relay permission for
+too many destinations. Recommended settings (use only one): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relay_domains = (do not forward mail from strangers)
+ relay_domains = $mydomain (my domain and subdomains)
+ relay_domains = $mydomain, other.domain.tld, ...
+</pre>
+</blockquote>
+
+<h3>10.7 - Optional: configure a smart host for remote delivery</h3>
+
+<p> If you're behind a firewall, you should set up a relayhost. If
+you can, specify the organizational domain name so that Postfix
+can use DNS lookups, and so that it can fall back to a secondary
+MX host when the primary MX host is down. Otherwise just specify
+a hard-coded hostname. </p>
+
+<p> Some examples (use only one): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relayhost = $mydomain
+ relayhost = [mail.$mydomain]
+</pre>
+</blockquote>
+
+<p> The form enclosed with <tt>[]</tt> eliminates DNS MX lookups. </p>
+
+<p> By default, the SMTP client will do DNS lookups even when you
+specify a relay host. If your machine has no access to a DNS server,
+turn off SMTP client DNS lookups like this: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ disable_dns_lookups = yes
+</pre>
+</blockquote>
+
+<p> The STANDARD_CONFIGURATION_README file has more hints and tips for
+firewalled and/or dial-up networks. </p>
+
+<h3>10.8 - Create the aliases database</h3>
+
+<p> Postfix uses a Sendmail-compatible aliases(5) table to redirect
+mail for local(8) recipients. Typically, this information is kept
+in two files: in a text file /etc/aliases and in an indexed file
+/etc/aliases.db. The command "postconf alias_maps" will tell you
+the exact location of the text file. </p>
+
+<p> First, be sure to update the text file with aliases for root,
+postmaster and "postfix" that forward mail to a real person. Postfix
+has a sample aliases file /etc/postfix/aliases that you can adapt
+to local conditions. </p>
+
+<blockquote>
+<pre>
+/etc/aliases:
+ root: you
+ postmaster: root
+ postfix: root
+ bin: root
+ <i>etcetera...</i>
+</pre>
+</blockquote>
+
+<p> Note: there should be no whitespace before the ":". </p>
+
+<p> Finally, build the indexed aliases file with one of the
+following commands: </p>
+
+<blockquote>
+<pre>
+# newaliases
+# sendmail -bi
+# postalias /etc/aliases (pathname is system dependent!)
+</pre>
+</blockquote>
+
+<h2><a name="hamlet">11 - To chroot or not to chroot</a></h2>
+
+<p> Postfix daemon processes can be configured (via master.cf) to
+run in a chroot jail. The processes run at a fixed low privilege
+and with access only to the Postfix queue directories (/var/spool/postfix).
+This provides a significant barrier against intrusion. The barrier
+is not impenetrable, but every little bit helps. </p>
+
+<p> With the exception of Postfix daemons that deliver mail locally
+and/or that execute non-Postfix commands, every Postfix daemon can
+run chrooted. </p>
+
+<p> Sites with high security requirements should consider to chroot
+all daemons that talk to the network: the smtp(8) and smtpd(8)
+processes, and perhaps also the lmtp(8) client. The author's own
+porcupine.org mail server runs all daemons chrooted that can be
+chrooted. </p>
+
+<p> The default /etc/postfix/master.cf file specifies that no
+Postfix daemon runs chrooted. In order to enable chroot operation,
+edit the file /etc/postfix/master.cf. Instructions are in the file.
+</p>
+
+<p> Note that a chrooted daemon resolves all filenames relative to
+the Postfix queue directory (/var/spool/postfix). For successful
+use of a chroot jail, most UNIX systems require you to bring in
+some files or device nodes. The examples/chroot-setup directory
+in the source code distribution has a collection of scripts that
+help you set up Postfix chroot environments on different operating
+systems. </p>
+
+<p> Additionally, you almost certainly need to configure syslogd
+so that it listens on a socket inside the Postfix queue directory.
+Examples for specific systems: </p>
+
+<dl>
+
+<dt> FreeBSD: </dt>
+
+<dd> <pre>
+# mkdir -p /var/spool/postfix/var/run
+# syslogd -l /var/spool/postfix/var/run/log
+</pre> </dd>
+
+<dt> Linux, OpenBSD: </dt>
+
+<dd> <pre>
+# mkdir -p /var/spool/postfix/dev
+# syslogd -a /var/spool/postfix/dev/log
+</pre> </dd>
+
+</dl>
+
+<h2><a name="care">12 - Care and feeding of the Postfix system</a></h2>
+
+<p> Postfix daemon processes run in the background, and log problems
+and normal activity to the syslog daemon. The names of logfiles
+are specified in /etc/syslog.conf. At the very least you need
+something like: </p>
+
+<blockquote>
+<pre>
+/etc/syslog.conf:
+ mail.err /dev/console
+ mail.debug /var/log/maillog
+</pre>
+</blockquote>
+
+<p> IMPORTANT: the syslogd will not create files. You must create
+them before (re)starting syslogd. </p>
+
+<p> IMPORTANT: on Linux you need to put a "-" character before
+the pathname, e.g., -/var/log/maillog, otherwise the syslogd
+will use more system resources than Postfix does. </p>
+
+<p> Hopefully, the number of problems will be small, but it is a good
+idea to run every night before the syslog files are rotated: </p>
+
+<blockquote>
+<pre>
+# postfix check
+# egrep '(reject|warning|error|fatal|panic):' /some/log/file
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> The first line (postfix check) causes Postfix to report
+file permission/ownership discrepancies. </p>
+
+<li> <p> The second line looks for problem reports from the mail
+software, and reports how effective the relay and junk mail access
+blocks are. This may produce a lot of output. You will want to
+apply some postprocessing to eliminate uninteresting information.
+</p>
+
+</ul>
+
+<p> The <a href="DEBUG_README.html#logging"> DEBUG_README </a>
+document describes the meaning of the "warning" etc. labels in
+Postfix logging. </p>
+
+</body>
+
+</html>
diff --git a/proto/IPV6_README.html b/proto/IPV6_README.html
new file mode 100644
index 0000000..01ea51b
--- /dev/null
+++ b/proto/IPV6_README.html
@@ -0,0 +1,360 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix IPv6 Support</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+IPv6 Support</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> Postfix 2.2 introduces support for the IPv6 (IP version 6)
+protocol. IPv6 support for older Postfix versions was available as
+an add-on patch. The section "<a href="#compat">Compatibility with
+Postfix &lt;2.2 IPv6 support</a>" below discusses the differences
+between these implementations. </p>
+
+<p> The main feature of interest is that IPv6 uses 128-bit IP
+addresses instead of the 32-bit addresses used by IPv4. It can
+therefore accommodate a much larger number of hosts and networks
+without ugly kluges such as NAT. A side benefit of the much larger
+address space is that it makes random network scanning impractical.
+</p>
+
+<p> Postfix uses the same SMTP protocol over IPv6 as it already
+uses over the older IPv4 network, and does AAAA record lookups in
+the DNS in addition to the older A records. Information about IPv6
+can be found at http://www.ipv6.org/. </p>
+
+<p> This document provides information on the following topics:
+</p>
+
+<ul>
+
+<li><a href="#platforms">Supported platforms</a>
+
+<li><a href="#configuration">Configuration</a>
+
+<li><a href="#limitations">Known limitations</a>
+
+<li><a href="#compat">Compatibility with Postfix &lt;2.2 IPv6 support</a>
+
+<li><a href="#porting">IPv6 Support for unsupported platforms</a>
+
+<li><a href="#credits">Credits</a>
+
+</ul>
+
+<h2><a name="platforms">Supported Platforms</a></h2>
+
+<p> Postfix version 2.2 supports IPv4 and IPv6 on the following
+platforms: </p>
+
+<ul>
+
+<li> AIX 5.1+
+<li> Darwin 7.3+
+<li> FreeBSD 4+
+<li> Linux 2.4+
+<li> NetBSD 1.5+
+<li> OpenBSD 2+
+<li> Solaris 8+
+<li> Tru64Unix V5.1+
+
+</ul>
+
+<p> On other platforms Postfix will simply use IPv4 as it has always
+done. </p>
+
+<p> See <a href="#porting">below</a> for tips how to port Postfix
+IPv6 support to other environments. </p>
+
+<h2><a name="configuration">Configuration</a></h2>
+
+<p> Postfix IPv6 support introduces two new main.cf configuration
+parameters, and introduces an important change in address syntax
+notation in match lists such as mynetworks or
+debug_peer_list. </p>
+
+<p> Postfix IPv6 address syntax is a little tricky, because there
+are a few places where you must enclose an IPv6 address inside
+"<tt>[]</tt>" characters, and a few places where you must not. It is
+a good idea to use "<tt>[]</tt>" only in the few places where you
+have to. Check out the postconf(5) manual whenever you do IPv6
+related configuration work with Postfix. </p>
+
+<ul>
+
+<li> <p> Instead of hard-coding 127.0.0.1 and ::1 loopback addresses
+in master.cf, specify "inet_interfaces = loopback-only" in main.cf.
+This way you can use the same master.cf file regardless of whether
+or not Postfix will run on an IPv6-enabled system. </p>
+
+<li> <p> The first new parameter is called inet_protocols. This
+specifies what protocols Postfix will use when it makes or accepts
+network connections, and also controls what DNS lookups Postfix
+will use when it makes network connections. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # You must stop/start Postfix after changing this parameter.
+ inet_protocols = all (enable IPv4, and IPv6 if supported)
+ inet_protocols = ipv4 (enable IPv4 only)
+ inet_protocols = ipv4, ipv6 (enable both IPv4 and IPv6)
+ inet_protocols = ipv6 (enable IPv6 only)
+</pre>
+</blockquote>
+
+<p> The default is compile-time dependent: "all" when Postfix is built
+on a software distribution with IPv6 support, "ipv4" otherwise. </p>
+
+<p> Note 1: you must stop and start Postfix after changing the
+inet_protocols configuration parameter. </p>
+
+<p> Note 2: on older Linux and Solaris systems, the setting
+"inet_protocols = ipv6" will not prevent Postfix from
+accepting IPv4 connections. </p>
+
+<li> <p> The other new parameter is smtp_bind_address6.
+This sets the local interface address for outgoing IPv6 SMTP
+connections, just like the smtp_bind_address parameter
+does for IPv4: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_bind_address6 = 2001:240:587:0:250:56ff:fe89:1
+</pre>
+</blockquote>
+
+<li> <p> If you left the value of the mynetworks parameter at its
+default (i.e. no mynetworks setting in main.cf) Postfix will figure
+out by itself what its network addresses are. This is what a typical
+setting looks like: </p>
+
+<blockquote>
+<pre>
+% postconf mynetworks
+mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [fe80::]/10 [2001:240:587::]/64
+</pre>
+</blockquote>
+
+<p> If you did specify the mynetworks parameter value in
+main.cf, you need to update the mynetworks value to include
+the IPv6 networks the system is in. Be sure to specify IPv6 address
+information inside "<tt>[]</tt>", like this: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mynetworks = ...<i>IPv4 networks</i>... [::1]/128 [2001:240:587::]/64 ...
+</pre>
+</blockquote>
+
+</ul>
+
+<p> <b> NOTE: when configuring Postfix match lists such as
+mynetworks or debug_peer_list, you must specify
+IPv6 address information inside "<tt>[]</tt>" in the main.cf parameter
+value and in files specified with a "<i>/file/name</i>" pattern.
+IPv6 addresses contain the ":" character, and would otherwise be
+confused with a "<i>type:table</i>" pattern. </b> </p>
+
+<h2><a name="limitations">Known Limitations</a></h2>
+
+<ul>
+
+<li> <p> Postfix SMTP clients before version 2.8 try to connect
+over IPv6 before trying IPv4. With more recent Postfix versions,
+the order of IPv6 versus IPv4 outgoing connection attempts is
+configurable with the smtp_address_preference parameter. </p>
+
+<li> <p> Postfix versions before 2.6 do not support DNSBL (DNS
+blocklist) lookups for IPv6 client IP addresses. </p>
+
+<li> <p> IPv6 does not have class A, B, C, etc. networks. With IPv6
+networks, the setting "mynetworks_style = class" has the
+same effect as the setting "mynetworks_style = subnet".
+</p>
+
+<li> <p> On Tru64Unix and AIX, Postfix can't figure out the local
+subnet mask
+and always assumes a /128 network. This is a problem only with
+"mynetworks_style = subnet" and no explicit mynetworks
+setting in main.cf. </p>
+
+</ul>
+
+<h2> <a name="compat">Compatibility with Postfix &lt;2.2 IPv6 support</a>
+</h2>
+
+<p> Postfix version 2.2 IPv6 support is based on the Postfix/IPv6 patch
+by Dean Strik and others, but differs in a few minor ways. </p>
+
+<ul>
+
+<li> <p> main.cf: The inet_interfaces parameter does not support
+the notation "ipv6:all" or "ipv4:all". Use the
+inet_protocols parameter instead. </p>
+
+<li> <p> main.cf: Specify "inet_protocols = all" or
+"inet_protocols = ipv4, ipv6" in order to enable both IPv4
+and IPv6 support. </p>
+
+<li> <p> main.cf: The inet_protocols parameter also controls
+what DNS lookups Postfix will attempt to make when delivering or
+receiving mail. </p>
+
+<li> <p> main.cf: Specify "inet_interfaces = loopback-only"
+to listen on loopback network interfaces only. </p>
+
+<li> <p> The lmtp_bind_address and lmtp_bind_address6
+features were omitted. Postfix version 2.3 merged the LMTP client
+into the SMTP client, so there was no reason to keep adding features
+to the LMTP client. </p>
+
+<li> <p> The SMTP server now requires that IPv6 addresses in SMTP
+commands are specified as [ipv6:<i>ipv6address</i>], as
+described in RFC 2821. </p>
+
+<li> <p> The IPv6 network address matching code was rewritten from
+the ground up, and is expected to be closer to the specification.
+The result may be incompatible with the Postfix/IPv6 patch.
+</p>
+
+</ul>
+
+<h2><a name="porting">IPv6 Support for unsupported platforms</a></h2>
+
+<p> Getting Postfix IPv6 working on other platforms involves the
+following steps: </p>
+
+<ul>
+
+<li> <p> Specify how Postfix should find the local network interfaces.
+Postfix needs this information to avoid mailer loops and to find out
+if mail for <i>user@[ipaddress]</i> is a local or remote destination. </p>
+
+<p> If your system has the getifaddrs() routine then add
+the following to your platform-specific section in
+src/util/sys_defs.h: </p>
+
+<blockquote>
+<pre>
+#ifndef NO_IPV6
+# define HAS_IPV6
+# define HAVE_GETIFADDRS
+#endif
+</pre>
+</blockquote>
+
+<p> Otherwise, if your system has the SIOCGLIF ioctl()
+command in /usr/include/*/*.h, add the following to your
+platform-specific section in src/util/sys_defs.h: </p>
+
+<blockquote>
+<pre>
+#ifndef NO_IPV6
+# define HAS_IPV6
+# define HAS_SIOCGLIF
+#endif
+</pre>
+</blockquote>
+
+<p> Otherwise, Postfix will have to use the old SIOCGIF commands
+and get along with reduced IPv6 functionality (it won't be able to
+figure out your IPv6 netmasks, which are needed for "mynetworks_style
+= subnet". Add this to your platform-specific section in
+src/util/sys_defs.h: </p>
+
+<blockquote>
+<pre>
+#ifndef NO_IPV6
+# define HAS_IPV6
+#endif
+</pre>
+</blockquote>
+
+<li> <p> Test if Postfix can figure out its interface information. </p>
+
+<p> After compiling Postfix in the usual manner, step into the
+src/util directory and type "<b>make inet_addr_local</b>".
+Running this file by hand should produce all the interface addresses
+and network masks, for example: </p>
+
+<blockquote>
+<pre>
+% make
+% cd src/util
+% make inet_addr_local
+[... some messages ...]
+% ./inet_addr_local
+[... some messages ...]
+./inet_addr_local: inet_addr_local: configured 2 IPv4 addresses
+./inet_addr_local: inet_addr_local: configured 4 IPv6 addresses
+168.100.189.2/255.255.255.224
+127.0.0.1/255.0.0.0
+fe80:1::2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff::
+2001:240:587:0:2d0:b7ff:fe88:2ca7/ffff:ffff:ffff:ffff::
+fe80:5::1/ffff:ffff:ffff:ffff::
+::1/ffff:ffff:ffff:ffff:ffff:ffff:ffff:ffff
+</pre>
+</blockquote>
+
+<p> The above is for an old FreeBSD machine. Other systems produce
+slightly different results, but you get the idea. </p>
+
+</ul>
+
+<p> If none of all this produces a usable result, send email to the
+postfix-users@postfix.org mailing list and we'll try to help you
+through this. </p>
+
+<h2><a name="credits">Credits</a></h2>
+
+<p> The following information is in part based on information that
+was compiled by Dean Strik. </p>
+
+<ul>
+
+<li> <p> Mark Huizer wrote the original Postfix IPv6 patch. </p>
+
+<li> <p> Jun-ichiro 'itojun' Hagino of the KAME project made
+substantial improvements. Since then, we speak of the KAME patch.
+</p>
+
+<li> <p> The PLD Linux Distribution ported the code to other stacks
+(notably USAGI). We speak of the PLD patch. A very important
+feature of the PLD patch was that it can work with Lutz Jaenicke's
+TLS patch for Postfix. </p>
+
+<li> <p> Dean Strik extended IPv6 support to platforms other than
+KAME and USAGI, updated the patch to keep up with Postfix development,
+and provided a combined IPv6 + TLS patch. Information about his
+effort can be found on Dean Strik's Postfix website at
+http://www.ipnet6.org/postfix/. </p>
+
+<li> <p> Wietse Venema took Dean Strik's IPv6 patch, merged it into
+Postfix 2.2, and took the opportunity to eliminate all IPv4-specific
+code from Postfix that could be removed. For systems without IPv6
+support in the kernel and system libraries, Postfix has a simple
+compatibility layer, so that it will use IPv4 as before. </p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/LDAP_README.html b/proto/LDAP_README.html
new file mode 100644
index 0000000..720d1c0
--- /dev/null
+++ b/proto/LDAP_README.html
@@ -0,0 +1,632 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix LDAP Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix LDAP Howto</h1>
+
+<hr>
+
+<h2>LDAP Support in Postfix</h2>
+
+<p> Postfix can use an LDAP directory as a source for any of its
+lookups: aliases(5), virtual(5), canonical(5), etc. This allows
+you to keep information for your mail service in a replicated
+network database with fine-grained access controls. By not storing
+it locally on the mail server, the administrators can maintain it
+from anywhere, and the users can control whatever bits of it you
+think appropriate. You can have multiple mail servers using the
+same information, without the hassle and delay of having to copy
+it to each. </p>
+
+<p> Topics covered in this document:</p>
+
+<ul>
+
+<li><a href="#build">Building Postfix with LDAP support</a>
+
+<li><a href="#config">Configuring LDAP lookups</a>
+
+<li><a href="#example_alias">Example: aliases</a>
+
+<li><a href="#example_virtual">Example: virtual domains/addresses</a>
+
+<li><a href="#example_group">Example: expanding LDAP groups</a>
+
+<li><a href="#other">Other uses of LDAP lookups</a>
+
+<li><a href="#hmmmm">Notes and things to think about</a>
+
+<li><a href="#feedback">Feedback</a>
+
+<li><a href="#credits">Credits</a>
+
+</ul>
+
+<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>
+
+<p> Note 2: to use LDAP with Debian GNU/Linux's Postfix, all you
+need is to install the postfix-ldap package and you're done. There
+is no need to recompile Postfix. </p>
+
+<p> You need to have LDAP libraries and include files installed
+somewhere on your system, and you need to configure the Postfix
+Makefiles accordingly. </p>
+
+<p> For example, to build the OpenLDAP libraries for use with
+Postfix (i.e. LDAP client code only), you could use the following
+command: </p>
+
+<blockquote>
+<pre>
+% ./configure --without-kerberos --without-cyrus-sasl --without-tls \
+ --without-threads --disable-slapd --disable-slurpd \
+ --disable-debug --disable-shared
+</pre>
+</blockquote>
+
+<p> If you're using the libraries from the UM distribution
+(http://www.umich.edu/~dirsvcs/ldap/ldap.html) or OpenLDAP
+(http://www.openldap.org), something like this in the top level of
+your Postfix source tree should work: </p>
+
+<blockquote>
+<pre>
+% make tidy
+% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
+ AUXLIBS_LDAP="-L/usr/local/lib -lldap -L/usr/local/lib -llber"
+</pre>
+</blockquote>
+
+<p> If your LDAP shared library is in a directory that the RUN-TIME
+linker does not know about, add a "-Wl,-R,/path/to/directory" option after
+"-lldap". </p>
+
+<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_LDAP.
+With Postfix 3.0 and later, the old AUXLIBS variable still supports
+building a statically-loaded LDAP database client, but only the new
+AUXLIBS_LDAP variable supports building a dynamically-loaded or
+statically-loaded LDAP database client. </p>
+
+<blockquote>
+
+<p> Failure to use the AUXLIBS_LDAP variable will defeat the purpose
+of dynamic database client loading. Every Postfix executable file
+will have LDAP database library dependencies. And that was exactly
+what dynamic database client loading was meant to avoid. </p>
+
+</blockquote>
+
+<p> On Solaris 2.x you may have to specify run-time link information,
+otherwise ld.so will not find some of the shared libraries: </p>
+
+<blockquote>
+<pre>
+% make tidy
+% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
+ AUXLIBS_LDAP="-L/usr/local/lib -R/usr/local/lib -lldap \
+ -L/usr/local/lib -R/usr/local/lib -llber"
+</pre>
+</blockquote>
+
+<p> The 'make tidy' command is needed only if you have previously
+built Postfix without LDAP support. </p>
+
+<p> Instead of '/usr/local' specify the actual locations of your
+LDAP include files and libraries. Be sure to not mix LDAP include
+files and LDAP libraries of different versions!! </p>
+
+<p> If your LDAP libraries were built with Kerberos support, you'll
+also need to include your Kerberos libraries in this line. Note
+that the KTH Kerberos IV libraries might conflict with Postfix's
+lib/libdns.a, which defines dns_lookup. If that happens, you'll
+probably want to link with LDAP libraries that lack Kerberos support
+just to build Postfix, as it doesn't support Kerberos binds to the
+LDAP server anyway. Sorry about the bother. </p>
+
+<p> If you're using one of the Netscape LDAP SDKs, you'll need to
+change the AUXLIBS line to point to libldap10.so or libldapssl30.so
+or whatever you have, and you may need to use the appropriate linker
+option (e.g. '-R') so the executables can find it at runtime. </p>
+
+<p> If you are using OpenLDAP, and the libraries were built with SASL
+support, you can add -DUSE_LDAP_SASL to the CCARGS to enable SASL support.
+For example: </p>
+
+<blockquote>
+<pre>
+ CCARGS="-I/usr/local/include -DHAS_LDAP -DUSE_LDAP_SASL"
+</pre>
+</blockquote>
+
+<h2><a name="config">Configuring LDAP lookups</a></h2>
+
+<p> In order to use LDAP lookups, define an LDAP source
+as a table lookup in main.cf, for example: </p>
+
+<blockquote>
+<pre>
+alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf
+</pre>
+</blockquote>
+
+<p> The file /etc/postfix/ldap-aliases.cf can specify a great number
+of parameters, including parameters that enable LDAP SSL or STARTTLS,
+and LDAP SASL. For a complete description, see the ldap_table(5)
+manual page. </p>
+
+<h2><a name="example_alias">Example: local(8) aliases</a></h2>
+
+<p> Here's a basic example for using LDAP to look up local(8)
+aliases. Assume that in main.cf, you have: </p>
+
+<blockquote>
+<pre>
+alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf
+</pre>
+</blockquote>
+
+<p> and in ldap:/etc/postfix/ldap-aliases.cf you have: </p>
+
+<blockquote>
+<pre>
+server_host = ldap.example.com
+search_base = dc=example, dc=com
+</pre>
+</blockquote>
+
+<p> Upon receiving mail for a local address "ldapuser" that isn't
+found in the /etc/aliases database, Postfix will search the LDAP
+server listening at port 389 on ldap.example.com. It will bind anonymously,
+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 RFC822 addresses to which the message will be delivered. </p>
+
+<h2><a name="example_virtual">Example: virtual domains/addresses</a></h2>
+
+<p> If you want to keep information for virtual lookups in your
+directory, it's only a little more complicated. First, you need to
+make sure Postfix knows about the virtual domain. An easy way to
+do that is to add the domain to the mailacceptinggeneralid attribute
+of some entry in the directory. Next, you'll want to make sure all
+of your virtual recipient's mailacceptinggeneralid attributes are
+fully qualified with their virtual domains. Finally, if you want
+to designate a directory entry as the default user for a virtual
+domain, just give it an additional mailacceptinggeneralid (or the
+equivalent in your directory) of "@fake.dom". That's right, no
+user part. If you don't want a catchall user, omit this step and
+mail to unknown users in the domain will simply bounce. </p>
+
+<p> In summary, you might have a catchall user for a virtual domain
+that looks like this: </p>
+
+<blockquote>
+<pre>
+ dn: cn=defaultrecipient, dc=fake, dc=dom
+ objectclass: top
+ objectclass: virtualaccount
+ cn: defaultrecipient
+ owner: uid=root, dc=someserver, dc=isp, dc=dom
+1 -&gt; mailacceptinggeneralid: fake.dom
+2 -&gt; mailacceptinggeneralid: @fake.dom
+3 -&gt; maildrop: realuser@real.dom
+</pre>
+</blockquote>
+
+<dl compact>
+
+<dd> <p> 1: Postfix knows fake.dom is a valid virtual domain when
+it looks for this and gets something (the maildrop) back. </p>
+
+<dd> <p> 2: This causes any mail for unknown users in fake.dom to
+go to this entry ... </p>
+
+<dd> <p> 3: ... and then to its maildrop. </p>
+
+</dl>
+
+<p> Normal users might simply have one mailacceptinggeneralid and
+maildrop, e.g. "normaluser@fake.dom" and "normaluser@real.dom".
+</p>
+
+<h2><a name="example_group">Example: expanding LDAP groups</a></h2>
+
+<p>
+LDAP is frequently used to store group member information. There are a
+number of ways of handling LDAP groups. We will show a few examples in
+order of increasing complexity, but owing to the number of independent
+variables, we can only present a tiny portion of the solution space.
+We show how to:
+</p>
+
+<ol>
+
+<li> <p> query groups as lists of addresses; </p>
+
+<li> <p> query groups as lists of user objects containing addresses; </p>
+
+<li> <p> forward special lists unexpanded to a separate list server,
+for moderation or other processing; </p>
+
+<li> <p> handle complex schemas by controlling expansion and by treating
+leaf nodes specially, using features that are new in Postfix 2.4. </p>
+
+</ol>
+
+<p>
+The example LDAP entries and implied schema below show two group entries
+("agroup" and "bgroup") and four user entries ("auser", "buser", "cuser"
+and "duser"). The group "agroup" has the users "auser" (1) and "buser" (2)
+as members via DN references in the multi-valued attribute "memberdn", and
+direct email addresses of two external users "auser@example.org" (3) and
+"buser@example.org" (4) stored in the multi-valued attribute "memberaddr".
+The same is true of "bgroup" and "cuser"/"duser" (6)/(7)/(8)/(9), but
+"bgroup" also has a "maildrop" attribute of "bgroup@mlm.example.com"
+(5): </p>
+
+<blockquote>
+<pre>
+ dn: cn=agroup, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapgroup
+ cn: agroup
+ mail: agroup@example.com
+1 -&gt; memberdn: uid=auser, dc=example, dc=com
+2 -&gt; memberdn: uid=buser, dc=example, dc=com
+3 -&gt; memberaddr: auser@example.org
+4 -&gt; memberaddr: buser@example.org
+</pre>
+<br>
+
+<pre>
+ dn: cn=bgroup, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapgroup
+ cn: bgroup
+ mail: bgroup@example.com
+5 -&gt; maildrop: bgroup@mlm.example.com
+6 -&gt; memberdn: uid=cuser, dc=example, dc=com
+7 -&gt; memberdn: uid=duser, dc=example, dc=com
+8 -&gt; memberaddr: cuser@example.org
+9 -&gt; memberaddr: duser@example.org
+</pre>
+<br>
+
+<pre>
+ dn: uid=auser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: auser
+10 -&gt; mail: auser@example.com
+11 -&gt; maildrop: auser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=buser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: buser
+12 -&gt; mail: buser@example.com
+13 -&gt; maildrop: buser@mailhub.example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=cuser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: cuser
+14 -&gt; mail: cuser@example.com
+</pre>
+<br>
+
+<pre>
+ dn: uid=duser, dc=example, dc=com
+ objectclass: top
+ objectclass: ldapuser
+ uid: duser
+15 -&gt; mail: duser@example.com
+</pre>
+<br>
+
+</blockquote>
+
+<p> Our first use case ignores the "memberdn" attributes, and assumes
+that groups hold only direct "memberaddr" strings as in (3), (4), (8) and
+(9). The goal is to map the group address to the list of constituent
+"memberaddr" values. This is simple, ignoring the various connection
+related settings (hosts, ports, bind settings, timeouts, ...) we have:
+</p>
+
+<blockquote>
+<pre>
+ simple.cf:
+ ...
+ search_base = dc=example, dc=com
+ query_filter = mail=%s
+ result_attribute = memberaddr
+ $ postmap -q agroup@example.com ldap:/etc/postfix/simple.cf \
+ auser@example.org,buser@example.org
+</pre>
+</blockquote>
+
+<p> We search "dc=example, dc=com". The "mail" attribute is used in the
+query_filter to locate the right group, the "result_attribute" setting
+described in ldap_table(5) is used to specify that "memberaddr" values
+from the matching group are to be returned as a comma separated list.
+Always check tables using postmap(1) with the "-q" option, before
+deploying them into production use in main.cf. </p>
+
+<p> Our second use case instead expands "memberdn" attributes (1), (2),
+(6) and (7), follows the DN references and returns the "maildrop" of the
+referenced user entries. Here we use the "special_result_attribute"
+setting from ldap_table(5) to designate the "memberdn" attribute
+as holding DNs of the desired member entries. The "result_attribute"
+setting selects which attributes are returned from the selected DNs. It
+is important to choose a result attribute that is not also present in
+the group object, because result attributes are collected from both
+the group and the member DNs. In this case we choose "maildrop" and
+assume for the moment that groups never have a "maildrop" (the "bgroup"
+"maildrop" attribute is for a different use case). The returned data for
+"auser" and "buser" is from items (11) and (13) in the example data. </p>
+
+<blockquote>
+<pre>
+ special.cf:
+ ...
+ search_base = dc=example, dc=com
+ query_filter = mail=%s
+ result_attribute = maildrop
+ special_result_attribute = memberdn
+ $ postmap -q agroup@example.com ldap:/etc/postfix/special.cf \
+ auser@mailhub.example.com,buser@mailhub.example.com
+</pre>
+</blockquote>
+
+<p> Note: if the desired member object result attribute is always also
+present in the group, you get surprising results: the expansion also
+returns the address of the group. This is a known limitation of Postfix
+releases prior to 2.4, and is addressed in the new with Postfix 2.4
+"leaf_result_attribute" feature described in ldap_table(5). </p>
+
+<p> Our third use case has some groups that are expanded immediately,
+and other groups that are forwarded to a dedicated mailing list manager
+host for delayed expansion. This uses two LDAP tables, one for users
+and forwarded groups and a second for groups that can be expanded
+immediately. It is assumed that groups that require forwarding are
+never nested members of groups that are directly expanded. </p>
+
+<blockquote>
+<pre>
+ no_expand.cf:
+ ...
+ search_base = dc=example, dc=com
+ query_filter = mail=%s
+ result_attribute = maildrop
+ expand.cf
+ ...
+ search_base = dc=example, dc=com
+ query_filter = mail=%s
+ result_attribute = maildrop
+ special_result_attribute = memberdn
+ $ postmap -q auser@example.com \
+ ldap:/etc/postfix/no_expand.cf ldap:/etc/postfix/expand.cf \
+ auser@mailhub.example.com
+ $ postmap -q agroup@example.com \
+ ldap:/etc/postfix/no_expand.cf ldap:/etc/postfix/expand.cf \
+ auser@mailhub.example.com,buser@mailhub.example.com
+ $ postmap -q bgroup@example.com \
+ ldap:/etc/postfix/no_expand.cf ldap:/etc/postfix/expand.cf \
+ bgroup@mlm.example.com
+</pre>
+</blockquote>
+
+<p> Non-group objects and groups with delayed expansion (those that have a
+maildrop attribute) are rewritten to a single maildrop value. Groups that
+don't have a maildrop are expanded as the second use case. This admits
+a more elegant solution with Postfix 2.4 and later. </p>
+
+<p> Our final use case is the same as the third, but this time uses new
+features in Postfix 2.4. We now are able to use just one LDAP table and
+no longer need to assume that forwarded groups are never nested inside
+expanded groups. </p>
+
+<blockquote>
+<pre>
+ fancy.cf:
+ ...
+ search_base = dc=example, dc=com
+ query_filter = mail=%s
+ result_attribute = memberaddr
+ special_result_attribute = memberdn
+ terminal_result_attribute = maildrop
+ leaf_result_attribute = mail
+ $ postmap -q auser@example.com ldap:/etc/postfix/fancy.cf \
+ auser@mailhub.example.com
+ $ postmap -q cuser@example.com ldap:/etc/postfix/fancy.cf \
+ cuser@example.com
+ $ postmap -q agroup@example.com ldap:/etc/postfix/fancy.cf \
+ auser@mailhub.example.com,buser@mailhub.example.com,auser@example.org,buser@example.org
+ $ postmap -q bgroup@example.com ldap:/etc/postfix/fancy.cf \
+ bgroup@mlm.example.com
+</pre>
+</blockquote>
+
+<p> Above, delayed expansion is enabled via "terminal_result_attribute",
+which, if present, is used as the sole result and all other expansion is
+suppressed. Otherwise, the "leaf_result_attribute" is only returned for
+leaf objects that don't have a "special_result_attribute" (non-groups),
+while the "result_attribute" (direct member address of groups) is returned
+at every level of recursive expansion, not just the leaf nodes. This fancy
+example illustrates all the features of Postfix 2.4 group expansion. </p>
+
+<h2><a name="other">Other uses of LDAP lookups</a></h2>
+
+Other common uses for LDAP lookups include rewriting senders and
+recipients with Postfix's canonical lookups, for example in order
+to make mail leaving your site appear to be coming from
+"First.Last@example.com" instead of "userid@example.com".
+
+<h2><a name="hmmmm">Notes and things to think about</a></h2>
+
+<ul>
+
+<li> <p> The bits of schema and attribute names used in this document are just
+ examples. There's nothing special about them, other than that some are
+ the defaults in the LDAP configuration parameters. You can use
+ whatever schema you like, and configure Postfix accordingly. </p>
+
+<li> <p> You probably want to make sure that mailacceptinggeneralids are
+ unique, and that not just anyone can specify theirs as postmaster or
+ root, say. </p>
+
+<li> <p> An entry can have an arbitrary number of mailacceptinggeneralids or
+ maildrops. Maildrops can also be comma-separated lists of addresses.
+ They will all be found and returned by the lookups. For example, you
+ could define an entry intended for use as a mailing list that looks
+ like this (Warning! Schema made up just for this example): </p>
+
+<blockquote>
+<pre>
+dn: cn=Accounting Staff List, dc=example, dc=com
+cn: Accounting Staff List
+o: example.com
+objectclass: maillist
+mailacceptinggeneralid: accountingstaff
+mailacceptinggeneralid: accounting-staff
+maildrop: mylist-owner
+maildrop: an-accountant
+maildrop: some-other-accountant
+maildrop: this, that, theother
+</pre>
+</blockquote>
+
+<li> <p> If you use an LDAP map for lookups other than aliases, you may have to
+ make sure the lookup makes sense. In the case of virtual lookups,
+ maildrops other than mail addresses are pretty useless, because
+ Postfix can't know how to set the ownership for program or file
+ delivery. Your <b>query_filter</b> should probably look something like this: </p>
+
+<blockquote>
+<pre>
+query_filter = (&amp;(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))))
+</pre>
+</blockquote>
+
+<li> <p> And for that matter, even for aliases, you may not want users to be able to
+ specify their maildrops as programs, includes, etc. This might be
+ particularly pertinent on a "sealed" server where they don't have
+ local UNIX accounts, but exist only in LDAP and Cyrus. You might allow
+ the fun stuff only for directory entries owned by an administrative
+ account,
+ so that if the object had a program as its maildrop and weren't owned
+ by "cn=root" it wouldn't be returned as a valid local user. This will
+ require some thought on your part to implement safely, considering the
+ ramifications of this type of delivery. You may decide it's not worth
+ the bother to allow any of that nonsense in LDAP lookups, ban it in
+ the <b>query_filter</b>, and keep things like majordomo lists in local alias
+ databases. </p>
+
+<blockquote>
+<pre>
+query_filter = (&amp;(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com)))
+</pre>
+</blockquote>
+
+<li> <p> LDAP lookups are slower than local DB or DBM lookups. For most sites
+ they won't be a bottleneck, but it's a good idea to know how to tune
+ your directory service. </p>
+
+<li> <p> Multiple LDAP maps share the same LDAP connection if they differ
+ only in their query related parameters: base, scope, query_filter, and
+ so on. To take advantage of this, avoid spurious differences in the
+ definitions of LDAP maps: host selection order, version, bind, tls
+ parameters, ... should be the same for multiple maps whenever possible. </p>
+
+</ul>
+
+<h2><a name="feedback">Feedback</a></h2>
+
+<p> If you have questions, send them to postfix-users@postfix.org. Please
+include relevant information about your Postfix setup: LDAP-related
+output from postconf, which LDAP libraries you built with, and which
+directory server you're using. If your question involves your directory
+contents, please include the applicable bits of some directory entries. </p>
+
+<h2><a name="credits">Credits</a></h2>
+
+<ul>
+
+<li>Manuel Guesdon: Spotted a bug with the timeout attribute.
+
+<li>John Hensley: Multiple LDAP sources with more configurable attributes.
+
+<li>Carsten Hoeger: Search scope handling.
+
+<li>LaMont Jones: Domain restriction, URL and DN searches, multiple result
+ attributes.
+
+<li>Mike Mattice: Alias dereferencing control.
+
+<li>Hery Rakotoarisoa: Patches for LDAPv3 updating.
+
+<li>Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching.
+
+<li>Keith Stevenson: RFC 2254 escaping in queries.
+
+<li>Samuel Tardieu: Noticed that searches could include wildcards, prompting
+ the work on RFC 2254 escaping in queries. Spotted a bug
+ in binding.
+
+<li>Sami Haahtinen: Referral chasing and v3 support.
+
+<li>Victor Duchovni: ldap_bind() timeout. With fixes from LaMont Jones:
+ OpenLDAP cache deprecation. Limits on recursion, expansion
+ and search results size. LDAP connection sharing for maps
+ differing only in the query parameters.
+
+<li>Liviu Daia: Support for SSL/STARTTLS. Support for storing map definitions in
+ external files (ldap:/path/ldap.cf) needed to securely store
+ passwords for plain auth.
+
+<li>Liviu Daia revised the configuration interface and added the main.cf
+ configuration feature.</li>
+
+<li>Liviu Daia with further refinements from Jose Luis Tallon and
+Victor Duchovni developed the common query, result_format, domain and
+expansion_limit interface for LDAP, MySQL and PosgreSQL.</li>
+
+<li>Gunnar Wrobel provided a first implementation of a feature to
+limit LDAP search results to leaf nodes only. Victor generalized
+this into the Postfix 2.4 "leaf_result_attribute" feature. </li>
+
+<li>Quanah Gibson-Mount contributed support for advanced LDAP SASL
+mechanisms, beyond the password-based LDAP "simple" bind. </li>
+
+</ul>
+
+And of course Wietse.
+
+</body>
+
+</html>
diff --git a/proto/LINUX_README.html b/proto/LINUX_README.html
new file mode 100644
index 0000000..76c605f
--- /dev/null
+++ b/proto/LINUX_README.html
@@ -0,0 +1,119 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix and Linux</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix and Linux</h1>
+
+<hr>
+
+<h2> Host lookup issues </h2>
+
+<p> By default Linux /etc/hosts lookups do not support multiple IP
+addresses per hostname. This causes warnings from the Postfix SMTP
+server that "hostname XXX does not resolve to address YYY", and is
+especially a problem with hosts that have both IPv4 and IPv6
+addresses. To fix this, turn on support for multiple IP addresses: </p>
+
+<blockquote>
+<pre>
+/etc/host.conf:
+ ...
+ # We have machines with multiple IP addresses.
+ multi on
+ ...
+</pre>
+</blockquote>
+
+<p> Alternatively, specify the RESOLV_MULTI environment variable
+in main.cf: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ import_environment = MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG TZ XAUTHORITY DISPLAY LANG=C RESOLV_MULTI=on
+</pre>
+</blockquote>
+
+<h2>Berkeley DB issues</h2>
+
+<p> If you can't compile Postfix because the file "db.h"
+isn't found, then you MUST install the Berkeley DB development
+package (name: db???-devel-???) that matches your system library.
+You can find out what is installed with the rpm command. For example:
+</p>
+
+<blockquote>
+<pre>
+$ <b>rpm -qf /usr/lib/libdb.so</b>
+db4-4.3.29-2
+</pre>
+</blockquote>
+
+<p> This means that you need to install db4-devel-4.3.29-2 (on
+some systems, specify "<b>rpm -qf /lib/libdb.so</b>" instead). </p>
+
+<p> DO NOT download some Berkeley DB version from the network.
+Every Postfix program will dump core when it is built with a different
+Berkeley DB version than the version that is used by the system
+library routines. See the DB_README file for further information.
+</p>
+
+<h2>Procmail issues</h2>
+
+<p> On RedHat Linux 7.1 and later <b>procmail</b> no longer has
+permission
+to write to the mail spool directory. Workaround: </p>
+
+<blockquote>
+<pre>
+# chmod 1777 /var/spool/mail
+</pre>
+</blockquote>
+
+<h2>Logging in a container</h2>
+
+<p> When running Postfix inside a container, you can use stdout
+logging as described in MAILLOG_README. Alternatives: run syslogd
+inside the container, or mount the host's syslog socket inside the
+container. </p>
+
+<h2>Syslogd performance</h2>
+
+<p> LINUX <b>syslogd</b> uses synchronous writes by default. Because
+of this, <b>syslogd</b> can actually use more system resources than
+Postfix. To avoid such badness, disable synchronous mail logfile
+writes by editing /etc/syslog.conf and by prepending a - to the
+logfile name: </p>
+
+<blockquote>
+<pre>
+/etc/syslog.conf:
+ mail.* -/var/log/mail.log
+</pre>
+</blockquote>
+
+<p> Send a "<b>kill -HUP</b>" to the <b>syslogd</b> to make the
+change effective. </p>
+
+<h2>Other logging performance issues</h2>
+
+<p> LINUX <b>systemd</b> intercepts all logging and enforces its
+own rate limits before handing off requests to a backend such as
+<b>rsyslogd</b> or <b>syslog-ng</b>. On a busy mail server this can
+result in information loss. As a workaround, you can use Postfix's
+built-in logging as described in MAILLOG_README. </p>
+
+</body>
+
+</html>
diff --git a/proto/LMDB_README.html b/proto/LMDB_README.html
new file mode 100644
index 0000000..a9794cc
--- /dev/null
+++ b/proto/LMDB_README.html
@@ -0,0 +1,421 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix OpenLDAP LMDB Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix OpenLDAP LMDB Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> Postfix uses databases of various kinds to store and look up
+information. Postfix databases are specified as "type:name". OpenLDAP
+LMDB (called "LMDB" from here on) implements the Postfix database
+type "lmdb". The name of a Postfix LMDB database is the name of
+the database file without the ".lmdb" suffix. </p>
+
+<p> This document describes: </p>
+
+<ul>
+
+<li> <p> <a href="#with_lmdb">Building Postfix with LMDB support</a>.
+</p>
+
+<li> <p> <a href="#configure">Configuring LMDB settings</a>. </p>
+
+<li> <p> <a href="#locking">Using LMDB maps with non-Postfix programs</a>. </p>
+
+<li> <p> <a href="#supported"> Required minimum LMDB patchlevel</a>. </p>
+
+<li> <p> <a href="#credits"> Credits</a>. </p>
+
+</ul>
+
+<h2><a name="with_lmdb">Building Postfix with LMDB support</a></h2>
+
+<p> Postfix normally does not enable LMDB support. To
+build Postfix with LMDB support, use something like: </p>
+
+<blockquote>
+<pre>
+% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \
+ AUXLIBS_LMDB="-L/usr/local/lib -llmdb"
+% make
+</pre>
+</blockquote>
+
+<p> If your LMDB shared library is in a directory that the RUN-TIME
+linker does not know about, add a "-Wl,-R,/path/to/directory" option after
+"-llmdb". </p>
+
+<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_LMDB.
+With Postfix 3.0 and later, the old AUXLIBS variable still supports
+building a statically-loaded LMDB database client, but only the new
+AUXLIBS_LMDB variable supports building a dynamically-loaded or
+statically-loaded LMDB database client. </p>
+
+<blockquote>
+
+<p> Failure to use the AUXLIBS_LMDB variable will defeat the purpose
+of dynamic database client loading. Every Postfix executable file
+will have LMDB database library dependencies. And that was exactly
+what dynamic database client loading was meant to avoid. </p>
+
+</blockquote>
+
+
+<p> Solaris may need this: </p>
+
+<blockquote>
+<pre>
+% make makefiles CCARGS="-DHAS_LMDB -I/usr/local/include" \
+ AUXLIBS_LMDB="-R/usr/local/lib -L/usr/local/lib -llmdb"
+% make
+</pre>
+</blockquote>
+
+<p> The exact pathnames depend on how LMDB was installed. </p>
+
+<p> When building Postfix fails with: </p>
+
+<blockquote>
+<pre>
+undefined reference to `pthread_mutexattr_destroy'
+undefined reference to `pthread_mutexattr_init'
+undefined reference to `pthread_mutex_lock'
+</pre>
+</blockquote>
+
+<p> Add the "-lpthread" library to the "make makefiles" command. </p>
+
+<blockquote>
+<pre>
+% make makefiles .... AUXLIBS_LMDB="... -lpthread"
+</pre>
+</blockquote>
+
+<h2><a name="configure">Configuring LMDB settings</a></h2>
+
+<p> Postfix provides one configuration parameter that controls
+LMDB database behavior. </p>
+
+<ul>
+
+<li> <p> lmdb_map_size (default: 16777216). This setting specifies
+the initial LMDB database size limit in bytes. Each time a database
+becomes "full", its size limit is doubled. The maximum size is the
+largest signed integer value of "long". </p>
+
+</ul>
+
+<h2> <a name="locking">Using LMDB maps with non-Postfix programs</a> </h2>
+
+<p> Programs that use LMDB's built-in locking protocol will corrupt
+a Postfix LMDB database or will read garbage. </p>
+
+<p> Postfix does not use LMDB's built-in locking protocol, because
+that would require world-writable lockfiles, and would violate
+Postfix security policy. Instead, Postfix uses external locks based
+on fcntl(2) to prevent writers from corrupting the database, and
+to prevent readers from receiving garbage. </p>
+
+<p> See lmdb_table(5) for a detailed description of the locking
+protocol that all programs must use when they access a Postfix LMDB
+database. </p>
+
+<h2> <a name="supported"> Required minimum LMDB patchlevel </a> </h2>
+
+<p> Currently, Postfix requires LMDB 0.9.11 or later. The required
+minimum LMDB patchlevel has evolved over time, as the result of
+Postfix deployment experience: </p>
+
+<ul>
+
+<li> <p> LMDB 0.9.11 allows Postfix daemons to log an LMDB error
+message, instead of falling out of the sky without any notification.
+</p>
+
+<li> <p> LMDB 0.9.10 closes an information leak where LMDB was
+writing up to 4-kbyte chunks of uninitialized heap memory to the
+database. This would persist information that was not meant to be
+persisted, or share information that was not meant to be shared.
+</p>
+
+<li> <p> LMDB 0.9.9 allows Postfix to use external (fcntl()-based)
+locks, instead of having to use world-writable LMDB lock files,
+violating the Postfix security model in multiple ways. </p>
+
+<li> <p> LMDB 0.9.8 allows Postfix to recover from a "database full"
+error without having to close the database. This version adds support
+to update the database size limit on-the-fly. This is necessary
+because Postfix database sizes vary with mail server load. </p>
+
+<li> <p> LMDB 0.9.7 allows the postmap(1) and postalias(1) commands
+to use a bulk-mode transaction larger than the amount of physical
+memory. This is necessary because LMDB supports databases larger
+than physical memory. </p>
+
+</ul>
+
+<h2> <a name="credits"> Credits</a> </h2>
+
+<ul>
+
+<li> <p> Howard Chu contributed the initial Postfix dict_lmdb driver.
+</p>
+
+<li> <p> Wietse Venema wrote an abstraction layer (slmdb) that
+behaves more like Berkeley DB, NDBM, etc. This layer automatically
+retries an LMDB request when a database needs to be resized, or
+after a database was resized by a different process. </p>
+
+<li> <p> Howard and Wietse went through many iterations with changes
+to both LMDB and Postfix, with input from Viktor Dukhovni. </p>
+
+</ul>
+
+<!--
+
+<h2><a name="limitations">Unexpected failure modes of Postfix LMDB
+databases. </a> </h2>
+
+<p> As documented below, conversion to LMDB introduces a number of
+failure modes that don't exist with other Postfix databases. Some
+failure modes have been eliminated in the course of time.
+The writeup below reflects the status as of LMDB 0.9.9. </p>
+
+-->
+
+<!--
+
+<p> <strong>Unexpected "Permission denied" errors. </strong></p>
+
+<dl>
+
+<dt> Problem: </dt> <dd> <p> A world-readable LMDB database cannot
+be opened by a process with a UID that differs from the database
+file owner, even when an attempt is made to open the database
+read-only. This problem does not exist with other Postfix databases.
+</p> </dd>
+
+<dt> Background: </dt> <dd> <p> The LMDB implementation requires
+write access to maintain read locks, and perhaps for other purposes.
+</p> </dd>
+
+<dt> Solution: </dt> <dd> <p> Consider using cdb: to manage root-owned
+databases under the root-owned <tt>/etc</tt> or config_directory
+(default: <tt>/etc/postfix</tt>) such as access(5), virtual(5),
+transport(5). Support to create LMDB databases is available only
+for unprivileged Postfix daemon processes such as postscreen(8),
+tlsmgr(8) and verify(8) that manage postfix-owned databases under
+the postfix-owned data_directory (default: <tt>/var/lib/postfix</tt>).
+</p> </dd>
+
+</dl>
+
+-->
+
+<!--
+
+<p> <strong>Unexpected "readers full" errors. </strong></p>
+
+<dl>
+
+<dt> Problem: </dt> <dd> <p> Under heavy load, database read
+operations fail with MDB_READERS_FULL errors. This problem does not
+exist with other Postfix databases. </p> </dd>
+
+<dt> Background: </dt> <dd> <p> The LMDB implementation enforces a
+hard limit on the number of simultaneous read requests for the same
+database environment. This limit must be specified in advance with
+the lmdb_max_readers configuration parameter. </p> </dd>
+
+<dt> Mitigation: </dt> <dd> <p> Postfix logs a warning suggesting
+that the lmdb_max_readers parameter value be increased, and retries
+the failed operation for a limited number of times while running
+with reduced performance. </p> </dd>
+
+<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files for
+MDB_READERS_FULL errors. After making the necessary adjustments,
+restart Postfix. </p> </dd>
+
+</dl>
+
+-->
+
+<!--
+
+<p> <strong>Unexpected postmap(1)/postalias(1) "database full"
+errors. </strong></p>
+
+<dl>
+
+<dt> Problem: </dt> <dd> <p> The "postmap lmdb:filename" command
+fails with an MDB_TXN_FULL error. This problem does not exist with
+other Postfix databases. </p> </dd>
+
+<dt> Background: </dt>
+
+<dd>
+
+<p> The LMDB implementation has a hard limit on the total transaction
+size. This limit is independent of the LMDB database size. Therefore,
+the problem cannot be resolved by increasing the lmdb_map_size
+value. </p>
+
+<p> This symptom is indicative of a flawed design. All LMDB data
+structures should share the same storage pool so that they can scale
+with the database size, and so that all "out of storage" errors are
+resolved by increasing the database size. </p> </dd>
+
+-->
+
+<!--
+
+<p> Problem: </dt> <dd> <p> The "postmap lmdb:filename" command
+fails with an MDB_MAP_FULL error. This problem does not exist with
+other Postfix databases. </p> </dd>
+
+<dl>
+
+<dt> Background: </dt>
+
+<dd>
+
+<p> LMDB databases have a hard size limit (configured with the
+lmdb_map_size configuration parameter). </p>
+
+<p> When executing "postmap lmdb:filename", the Postfix LMDB database
+client stores the new data in a transaction which takes up space
+in addition to the existing data, and commits the transaction when
+it closes the database. Only then can the space for old data be
+reused. </p>
+
+</dd>
+
+<dt> Impact: </dt> <dd> <p> This failure does not affect Postfix
+availability, because the old data still exists in the database.
+</p> </dd>
+
+<dt> Mitigation: </dt> <dd>
+
+<p> When the postmap(1) or postalias(1) command fails with an
+MDB_MAP_FULL error, it expands the database file size to the current
+LMDB map size limit before terminating. </p>
+
+<p> Next, when you re-run the postmap(1) or postalias(1) command,
+it discovers that the LMDB file is larger than lmdb_map_size/3,
+logs a warning, and uses a larger LMDB map size limit instead: </p>
+
+<p> <tt> warning: <i>filename</i>.lmdb: file size 15024128 &ge;
+(lmdb map size limit 16777216)/3<br> warning: <i>filename</i>.lmdb:
+using map size limit 45072384</tt> </p>
+
+<p> By repeating the two steps above you can automate recovery and
+avoid the need for human intervention. Just repeat "postmap
+lmdb:filename" (up to some limit). After each failure it will use
+a 3x larger size limit, and eventually the "database full" error
+should disappear. This fails only when the disk is full or when
+the LMDB map size limit would exceed the memory address space size
+limit. </p>
+
+<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files and make
+sure that in main.cf, lmdb_map_size &gt; 3x the largest LMDB file
+size. </p> </dd> </dl>
+
+</dl>
+
+-->
+
+<!--
+
+<p> <strong>Unexpected Postfix daemon "database full" errors.
+</strong></p>
+
+<dl>
+
+<dt> Problem: </dt> <dd> <p> Postfix daemon programs fail with
+"database full" errors, such as postscreen(8), tlsmgr(8) or verify(8).
+This problem does not exist with other Postfix databases. </p>
+</dd>
+
+<dt> Impact: </dt> <dd> <p> This failure temporarily affects Postfix
+availability. The daemon restarts automatically and tries to open
+the database again as described next. </p> </dd>
+
+<dt> Mitigation: </dt> <dd> <p> When a Postfix daemon opens an LMDB
+file larger than lmdb_map_size/3, it logs a warning and uses a
+larger size limit instead: </p>
+
+<p> <tt> warning: <i>filename</i>.lmdb: file size 15024128 &ge;
+(lmdb map size limit 16777216)/3 <br>warning: <i>filename</i>.lmdb:
+using map size limit 45072384</tt> </p>
+
+<p> This can be used to automate recovery and avoid the need for
+human intervention. Each time the daemon runs into a "database full"
+error, it restarts and uses a 3x larger size limit. The "database
+full" error will disappear, at least for a while. </p>
+
+<dt> Prevention: </dt> <dd> <p> Monitor your LMDB files and make
+sure that lmdb_map_size &gt; 3x the largest LMDB file size. </p>
+</dd> </dl>
+
+-->
+
+<!--
+
+<p> <strong>Non-obvious recovery with postmap(1), postalias(1), or
+tlsmgr(8) from a corrupted database. </strong></p>
+
+<dl>
+
+<dt> Problem: </dt> <dd> <p> A corrupted LMDB database can't be
+rebuilt simply by re-running postmap(1) or postalias(1), or by
+waiting until a tlsmgr(8) daemon restarts. This problem does not
+exist with other Postfix databases. </p> </dd>
+
+<dt> Background: </dt> <dd> <p> The Postfix LMDB database client
+does not truncate the database file. Instead it attempts to create
+a transaction for a "drop" request plus subsequent "store" requests.
+That is obviously not possible with a corrupted database file. </p>
+</dd>
+
+<dt> Impact: </dt> <dd> <p> Postfix does not process mail until
+someone fixes the problem. </p> </dd>
+
+<dt> Recovery: </dt> <dd> <p> First delete the ".lmdb" file by hand.
+Then rebuild the file with the postmap(1) or postalias(1)
+command if the file was created with those commands, or restart
+postfix daemons if the file is maintained by tlsmgr(8).
+</p> </dd>
+
+<dt> Prevention: </dt> <dd>
+
+<p> Arrange your file systems such that they never run out of free
+space. </p>
+
+<p> Use ECC memory to detect and correct silent corruption of
+in-memory file system data and metadata. </p>
+
+<p> Use a file system such as ZFS to detect and correct silent
+corruption of on-disk file system data and metadata. DO NOT
+use ZFS on systems without ECC memory error correction. </p>
+
+</dd> </dl>
+
+-->
+
+</body>
+
+</html>
diff --git a/proto/LOCAL_RECIPIENT_README.html b/proto/LOCAL_RECIPIENT_README.html
new file mode 100644
index 0000000..12828cd
--- /dev/null
+++ b/proto/LOCAL_RECIPIENT_README.html
@@ -0,0 +1,180 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Rejecting Unknown Local Recipients with Postfix</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Rejecting Unknown Local Recipients with Postfix</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> As of Postfix version 2.0, the Postfix SMTP server rejects mail
+for unknown recipients in local domains (domains that match
+$mydestination or the IP addresses in $inet_interfaces or
+$proxy_interfaces) with "User unknown in local recipient table".
+This feature was optional with earlier Postfix versions. </p>
+
+<p> The good news is that this keeps undeliverable mail out of your
+queue, so that your mail queue is not clogged up with undeliverable
+MAILER-DAEMON messages. </p>
+
+<p> The bad news is that it may cause mail to be rejected when you
+upgrade from a Postfix system that was not configured to reject
+mail for unknown local recipients. </p>
+
+<p> This document describes what steps are needed in order to reject
+unknown local recipients correctly. </p>
+
+<ul>
+
+<li><a href="#main_config">Configuring local_recipient_maps
+in main.cf</a>
+
+<li><a href="#change">When you need to change the local_recipient_maps
+setting in main.cf</a>
+
+<li><a href="#format">Local recipient table format </a>
+
+</ul>
+
+<h2><a name="main_config">Configuring local_recipient_maps
+in main.cf</a></h2>
+
+<p> The local_recipient_maps parameter specifies lookup tables with
+all names or addresses of local recipients. A recipient address is
+local when its domain matches $mydestination, $inet_interfaces or
+$proxy_interfaces. If a local username or address is not listed in
+$local_recipient_maps, then the Postfix SMTP server will reject
+the address with "User unknown in local recipient table". </p>
+
+<p> The default setting, shown below, assumes that you use the
+default Postfix local(8) delivery agent for local delivery, where
+recipients are either UNIX accounts or local aliases: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ local_recipient_maps = proxy:unix:passwd.byname $alias_maps
+</pre>
+</blockquote>
+
+<p> To turn off unknown local recipient rejects by the SMTP server,
+specify: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ local_recipient_maps =
+</pre>
+</blockquote>
+
+<p> That is, an empty value. With this setting, the Postfix SMTP
+server will not reject mail with "User unknown in local recipient
+table". <b> Don't do this on systems that receive mail directly
+from the Internet. With today's worms and viruses, Postfix will
+become a backscatter source: it accepts mail for non-existent
+recipients and then tries to return that mail as "undeliverable"
+to the often forged sender address</b>. </p>
+
+<h2><a name="change">When you need to change the local_recipient_maps
+setting in main.cf</a></h2>
+
+<ul>
+
+ <li> <p> Problem: you don't use the default Postfix local(8)
+ delivery agent for domains matching $mydestination, $inet_interfaces,
+ or $proxy_interfaces. For example, you redefined the
+ "local_transport" setting in main.cf. </p>
+
+ <p> Solution: your local_recipient_maps setting needs to specify
+ a database that lists all the known user names or addresses
+ for that delivery agent. For example, if you deliver users in
+ $mydestination etc. domains via the virtual(8) delivery agent,
+ specify: </p>
+
+<pre>
+/etc/postfix/main.cf
+ mydestination = $myhostname localhost.$mydomain localhost ...
+ local_transport = virtual
+ local_recipient_maps = $virtual_mailbox_maps
+</pre>
+
+ <p> If you use a different delivery agent for $mydestination
+ etc. domains, see the section "<a href="#format">Local recipient
+ table format</a>" below for a description of how the table
+ should be populated. </p>
+
+ <li> <p> Problem: you use the mailbox_transport or fallback_transport
+ feature of the Postfix local(8) delivery agent in order to
+ deliver mail to non-UNIX accounts. </p>
+
+ <p> Solution: you need to add the database that lists the
+ non-UNIX users: </p>
+
+<pre>
+/etc/postfix/main.cf
+ local_recipient_maps = proxy:unix:passwd.byname, $alias_maps,
+ &lt;the database with non-UNIX accounts&gt;
+</pre>
+
+ <p> See the section "<a href="#format">Local recipient table
+ format</a>" below for a description of how the table should be
+ populated. </p>
+
+ <li> <p> Problem: you use the luser_relay feature of the Postfix
+ local delivery agent. </p>
+
+ <p> Solution: you must disable the local_recipient_maps feature
+ completely, so that Postfix accepts mail for all local addresses:
+ </p>
+
+<pre>
+/etc/postfix/main.cf
+ local_recipient_maps =
+</pre>
+
+</ul>
+
+<h2><a name="format">Local recipient table format</a> </h2>
+
+<p> If you use local files in postmap(1) format, then
+local_recipient_maps expects the following table format: </p>
+
+<ul>
+
+<li> <p> In the left-hand side, specify a bare username, an
+"@domain.tld" wild-card, or specify a complete "user@domain.tld"
+address. </p>
+
+<li> <p> You have to specify something on the right-hand side of
+the table, but the value is ignored by local_recipient_maps.
+
+</ul>
+
+<p> If you use lookup tables based on NIS, LDAP, MYSQL, or PGSQL,
+then local_recipient_maps does the same queries as for local files
+in postmap(1) format, and expects the same results. </p>
+
+<p> With regular expression tables, Postfix only queries with the
+full recipient address, and not with the bare username or the
+"@domain.tld" wild-card. </p>
+
+<p> NOTE: a lookup table should always return a result when the address
+exists, and should always return "not found" when the address does
+not exist. In particular, a zero-length result does not count as
+a "not found" result. </p>
+
+</body>
+
+</html>
diff --git a/proto/MAILDROP_README.html b/proto/MAILDROP_README.html
new file mode 100644
index 0000000..0271ea9
--- /dev/null
+++ b/proto/MAILDROP_README.html
@@ -0,0 +1,195 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix + Maildrop Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix + Maildrop Howto</h1>
+
+<hr>
+
+<h2> Introduction </h2>
+
+<p> This document discusses various options to plug the maildrop
+delivery agent into Postfix: </p>
+
+<ul>
+
+<li><a href="#direct">Direct delivery without the local delivery agent</a>
+
+<li><a href="#indirect">Indirect delivery via the local delivery agent</a>
+
+<li><a href="#credits">Credits</a>
+
+</ul>
+
+<h2><a name="direct">Direct delivery without the local delivery agent</a></h2>
+
+<p> Postfix can be configured to deliver mail directly to maildrop,
+without using the local(8) delivery agent as an intermediate. This
+means that you do not get local aliases(5) expansion or $HOME/.forward
+file processing. You would typically do this for hosted domains with
+recipients that don't have UNIX home directories. </p>
+
+<p> The following example shows how to use maildrop for some.domain
+and for someother.domain. The example comes in two parts. </p>
+
+<p> Part 1 describes changes to the main.cf file: </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 maildrop_destination_recipient_limit = 1
+ 3 virtual_mailbox_domains = some.domain someother.domain
+ 4 virtual_transport = maildrop
+ 5 virtual_mailbox_maps = hash:/etc/postfix/virtual_mailbox
+ 6 virtual_alias_maps = hash:/etc/postfix/virtual_alias
+ 7
+ 8 /etc/postfix/virtual_mailbox:
+ 9 user1@some.domain <i>...text here does not matter...</i>
+10 user2@some.domain <i>...text here does not matter...</i>
+11 user3@someother.domain <i>...text here does not matter...</i>
+12
+13 /etc/postfix/virtual_alias:
+14 postmaster@some.domain postmaster
+15 postmaster@someother.domain postmaster
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> Line 2 is needed so that Postfix will provide one recipient
+at a time to the maildrop delivery agent. </p>
+
+<li> <p> Line 3 informs Postfix that some.domain and someother.domain
+are so-called virtual mailbox domains.
+Instead of listing the names in main.cf you can also
+list them in a file; see the virtual_mailbox_domains documentation for
+details. </p>
+
+<li> <p> Line 4 specifies that mail for some.domain and someother.domain
+should be delivered by the maildrop delivery agent. </p>
+
+<li> <p> Lines 5 and 8-11 specify what recipients the Postfix SMTP
+server should receive mail for. This prevents the mail queue from
+becoming clogged with undeliverable messages. Specify an empty
+value ("virtual_mailbox_maps =") to disable this feature. </p>
+
+<li> <p> Lines 6 and 13-15 redirect mail for postmaster to the
+local postmaster. RFC 821 requires that every domain has a postmaster
+address. </p>
+
+</ul>
+
+<p> The vmail userid as used below is the user that maildrop should
+run as. This would be the owner of the virtual mailboxes if they
+all have the same owner. If maildrop is suid (see maildrop
+documentation), then maildrop will change to the appropriate owner
+to deliver the mail. </p>
+
+<p> Note: Do not use the postfix user as the maildrop user. </p>
+
+<p> Part 2 describes changes to the master.cf file: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ maildrop unix - n n - - pipe
+ flags=ODRhu user=vmail argv=/path/to/maildrop -d ${recipient}
+</pre>
+</blockquote>
+
+<p> The pipe(8) manual page gives a detailed description of the
+above command line arguments, and more. </p>
+
+<p> If you want to support user+extension@domain style addresses,
+use the following instead: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ maildrop unix - n n - - pipe
+ flags=ODRhu user=vmail argv=/path/to/maildrop
+ -d ${user}@${domain} ${extension} ${recipient} ${user} ${nexthop}
+</pre>
+</blockquote>
+
+<p> The mail is delivered to ${user}@${domain} (search key for
+maildrop userdb lookup). The ${extension} and the other address
+components are available to maildrop rules as $1, $2, $3, ... and
+can be omitted from master.cf or ignored by maildrop when not
+needed. </p>
+
+<p> With Postfix 2.4 and earlier, use ${nexthop} instead of ${domain}.
+</p>
+
+<h2><a name="indirect">Indirect delivery via the local delivery agent</a></h2>
+
+<p> Postfix can be configured to deliver mail to maildrop via the
+local delivery agent. This is slightly less efficient than the
+"direct" approach discussed above, but gives you the convenience
+of local aliases(5) expansion and $HOME/.forward file processing.
+You would typically use this for domains that are listed in
+mydestination and that have users with a UNIX system account. </p>
+
+<p> To configure maildrop delivery for all UNIX system accounts: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mailbox_command = /path/to/maildrop -d ${USER}
+</pre>
+</blockquote>
+
+<p> Note: ${USER} is spelled in upper case. </p>
+
+<p> To enable maildrop delivery for specific users only, you can
+use the Postfix local(8) delivery agent's mailbox_command_maps feature:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mailbox_command_maps = hash:/etc/postfix/mailbox_commands
+
+/etc/postfix/mailbox_commands:
+ you /path/to/maildrop -d ${USER}
+</pre>
+</blockquote>
+
+<p> Maildrop delivery for specific users is also possible by
+invoking it from the user's $HOME/.forward file: </p>
+
+<blockquote>
+<pre>
+/home/you/.forward:
+ "|/path/to/maildrop -d ${USER}"
+</pre>
+</blockquote>
+
+<h2><a name="credits">Credits</a></h2>
+
+<ul>
+
+<li> The original text was kindly provided by Russell Mosemann.
+
+<li> Victor Duchovni provided tips for supporting user+foo@domain
+addresses.
+
+<li> Tonni Earnshaw contributed text about delivery via the local(8)
+delivery agent.
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/MAILLOG_README.html b/proto/MAILLOG_README.html
new file mode 100644
index 0000000..5a19a92
--- /dev/null
+++ b/proto/MAILLOG_README.html
@@ -0,0 +1,183 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix logging to file or stdout</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+logging to file or stdout</h1>
+
+<hr>
+
+<h2>Overview </h2>
+
+<p> Postfix supports it own logging system as an alternative to
+syslog (which remains the default). This is available with Postfix
+version 3.4 or later. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#log-to-file">Configuring logging to file</a>
+
+<li><a href="#log-to-stdout">Configuring logging to stdout</a>
+
+<li><a href="#logrotate">Rotating logs </a>
+
+<li><a href="#limitations">Limitations</a>
+
+</ul>
+
+<h2> <a name="log-to-file"> Configuring logging to file </a> </h2>
+
+<p> Logging to file solves a usability problem for MacOS, and
+eliminates multiple problems for systemd-based systems. </p>
+
+<ol>
+
+<li> <p> Add the following line to master.cf if not already present
+(note: there must be no whitespace at the start of the line): </p>
+
+<blockquote>
+<pre>
+postlog unix-dgram n - n - 1 postlogd
+</pre>
+</blockquote>
+
+<p> Note: the service type "<b>unix-dgram</b>" was introduced with
+Postfix 3.4. Remove the above line before backing out to an older
+Postfix version. </p>
+
+<li> <p> Configure Postfix to write logging, to, for example,
+/var/log/postfix.log. See also the "<a href="#logrotate">Logfile
+rotation</a>" section below for logfile management. </p>
+
+<blockquote>
+<pre>
+# postfix stop
+# postconf maillog_file=/var/log/postfix.log
+# postfix start
+</pre>
+</blockquote>
+
+<p> By default, the logfile name must start with "/var" or "/dev/stdout"
+(the list of allowed prefixes is configured with the maillog_file_prefixes
+parameter). This safety mechanism limits the damage from a single
+configuration mistake. </p>
+
+</ol>
+
+<h2> <a name="log-to-stdout"> Configuring logging to stdout </a> </h2>
+
+<p> Logging to stdout is useful when Postfix runs in a container,
+as it eliminates a syslogd dependency. </p>
+
+<ol>
+
+<li> <p> Add the following line to master.cf if not already present (note:
+there must be no whitespace at the start of the line): </p>
+
+<blockquote>
+<pre>
+postlog unix-dgram n - n - 1 postlogd
+</pre>
+</blockquote>
+
+<p> Note: the service type "<b>unix-dgram</b>" was introduced with
+Postfix 3.4. Remove the above line before backing out to an older
+Postfix version. </p>
+
+<li> <p> Configure main.cf with "maillog_file = /dev/stdout". </p>
+
+<li> <p> Start Postfix with "<b>postfix start-fg</b>". </p>
+
+</ol>
+
+<h2> <a name="logrotate"> Rotating logs </a> </h2>
+
+<p> The command "<b>postfix logrotate</b>" may be run by hand or
+by a cronjob. It logs all errors, and reports errors to stderr if
+run from a terminal. This command implements the following steps:
+</p>
+
+<ul>
+
+<li> <p> Rename the current logfile by appending a suffix that
+contains the date and time. This suffix is configured with the
+maillog_file_rotate_suffix parameter (default: %Y%m%d-%H%M%S). </p>
+
+<li> <p> Reload Postfix so that postlogd(8) immediately closes the
+old logfile. </p>
+
+<li> <p> After a brief pause, compress the old logfile. The compression
+program is configured with the maillog_file_compressor parameter
+(default: gzip). </p>
+
+</ul>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> This command will not rotate a logfile with a pathname under
+the /dev directory, such as /dev/stdout. </p>
+
+<li> <p> This command does not (yet) remove old logfiles. </p>
+
+</ul>
+
+<h2> <a name="limitations">Limitations</a> </h2>
+
+<p> Background: </p>
+
+<ul>
+
+<li> <p> Postfix consists of a number of daemon programs that run
+in the background, as well as non-daemon programs for local mail
+submission or Postfix management.
+
+<li> <p> Logging to the Postfix logfile or stdout requires the Postfix
+postlogd(8) service. This ensures that simultaneous logging from
+different programs will not get mixed up. </p>
+
+<li> <p> All Postfix programs can log to syslog, but not all programs
+have sufficient privileges to use the Postfix logging service, and
+many non-daemon programs must not log to stdout as that would corrupt
+their output. </p>
+
+</ul>
+
+<p> Limitations: </p>
+
+<ul>
+
+<li> <p> Non-daemon Postfix programs will log errors to syslogd(8)
+before they have processed command-line options and main.cf parameters.
+
+<li> <p> If Postfix is down, the non-daemon programs postfix(1),
+postsuper(1), postmulti(1), and postlog(1), will log directly to
+$maillog_file. These programs expect to run with root privileges,
+for example during Postfix start-up, reload, or shutdown.
+
+<li> <p> Other non-daemon Postfix programs will never write directly
+to $maillog_file (also, logging to stdout would interfere with the
+operation of some of these programs). These programs can log to
+postlogd(8) if they are run by the super-user, or if their executable
+file has set-gid permission. Do not set this permission on programs
+other than postdrop(1) and postqueue(1).
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/MEMCACHE_README.html b/proto/MEMCACHE_README.html
new file mode 100644
index 0000000..d144935
--- /dev/null
+++ b/proto/MEMCACHE_README.html
@@ -0,0 +1,76 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix memcache client Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix memcache client Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p>The Postfix memcache client allows you to hook up Postfix to a
+memcache server. The current implementation supports one memcache
+server per Postfix table, with one optional Postfix database that
+provides persistent backup. The Postfix memcache client supports
+the lookup, update, delete and sequence operations. The sequence
+(i.e. first/next) operation requires a backup database that supports
+this operation. </p>
+
+<p> Typically, the Postfix memcache client is used to reduce query
+load on a persistent database, but it may also be used to query a
+memory-only database for low-value, easy-to-recreate, information
+such as a reputation cache for postscreen(8), verify(8) or greylisting.
+</p>
+
+<h2>Limitations</h2>
+
+<ul>
+
+<li> <p> The Postfix memcache client cannot be used for security-sensitive
+tables such as <tt>alias_maps</tt> (these may contain "<tt>|command</tt>"
+and "<tt>/file/name</tt>" destinations), or <tt>virtual_uid_maps</tt>,
+<tt>virtual_gid_maps</tt> and <tt>virtual_mailbox_maps</tt> (these
+specify UNIX process privileges or "<tt>/file/name</tt>" destinations).
+Typically, a memcache database is writable by any process that can
+talk to the memcache server; in contrast, security-sensitive tables
+must never be writable by the unprivileged Postfix user. </p>
+
+<li> <p> The Postfix memcache client requires additional configuration
+when used as postscreen(8) or verify(8) cache. For details see the
+<tt>backup</tt> and <tt>ttl</tt> parameter discussions in the
+memcache_table(5) manual page. </p>
+
+</ul>
+
+<h2>Building Postfix with memcache support</h2>
+
+<p>The Postfix memcache client has no external dependencies,
+and is therefore built into Postfix by default. </p>
+
+<h2>Configuring memcache lookup tables</h2>
+
+<p> Configuration is described in the memcache_table(5) manpage. </p>
+
+<h2>Credits</h2>
+
+<p> The first memcache client for Postfix was written by Omar Kilani,
+and was based on the libmemcache library. </p>
+
+<p> Wietse wrote the current memcache client from the ground up for
+Postfix version 2.9. This implementation does not use libmemcache,
+and bears no resemblance to earlier work. </p>
+
+</body>
+
+</html>
diff --git a/proto/MILTER_README.html b/proto/MILTER_README.html
new file mode 100644
index 0000000..a0d5ac6
--- /dev/null
+++ b/proto/MILTER_README.html
@@ -0,0 +1,952 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix before-queue Milter support </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix before-queue Milter support </h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> Postfix implements support for the Sendmail version 8 Milter
+(mail filter) protocol. This protocol is used by applications that
+run outside the MTA to inspect SMTP events (CONNECT, DISCONNECT),
+SMTP commands (HELO, MAIL FROM, etc.) as well as mail content
+(headers and body). All this happens before mail is queued. </p>
+
+<p> The reason for adding Milter support to Postfix is that there
+exists a large collection of applications, not only to block unwanted
+mail, but also to verify authenticity (examples: <a
+href="http://www.opendkim.org/">OpenDKIM</a> and <a
+href="http://www.trusteddomain.org/opendmarc/">DMARC </a>)
+or to digitally sign mail (example: <a
+href="http://www.opendkim.org/">OpenDKIM</a>).
+Having yet another Postfix-specific version of all that software
+is a poor use of human and system resources. </p>
+
+<p> The Milter protocol has evolved over time, and different Postfix
+versions implement different feature sets. See the <a
+href="#workarounds">workarounds</a> and <a
+href="#limitations">limitations</a> sections at the end of this
+document for differences between Postfix and Sendmail implementations.
+</p>
+
+<p> This document provides information on the following topics: </p>
+
+<ul>
+
+<li><a href="#plumbing">How Milter applications plug into Postfix </a>
+
+<li><a href="#building">Building Milter applications</a>
+
+<li><a href="#running">Running Milter applications</a>
+
+<li><a href="#config">Configuring Postfix</a>
+
+<li><a href="#workarounds">Workarounds</a>
+
+<li><a href="#limitations">Limitations</a>
+
+</ul>
+
+<h2><a name="plumbing">How Milter applications plug into Postfix </a> </h2>
+
+<p> The Postfix Milter implementation uses two different lists of
+mail filters: one list of filters for SMTP mail only,
+and one list of filters for non-SMTP mail. The two
+lists have different capabilities, which is unfortunate. Avoiding
+this would require major restructuring of Postfix. </p>
+
+<ul>
+
+<li> <p> The SMTP-only filters handle mail that arrives via the
+Postfix smtpd(8) server. They are typically used to filter unwanted
+mail and to sign mail from authorized SMTP clients. You specify
+SMTP-only Milter applications with the smtpd_milters parameter as
+described in a later section. Mail that arrives via the Postfix
+smtpd(8) server is not filtered by the non-SMTP filters that are
+described next. </p>
+
+<li> <p> The non-SMTP filters handle mail that arrives via the
+Postfix sendmail(1) command-line or via the Postfix qmqpd(8) server.
+They are typically used to digitally sign mail only. Although
+non-SMTP filters can be used to filter unwanted mail, they have
+limitations compared to the SMTP-only filters. You specify non-SMTP
+Milter applications with the non_smtpd_milters parameter as described
+in a later section. </p>
+
+</ul>
+
+<p> For those who are familiar with the Postfix architecture, the
+figure below shows how Milter applications plug into Postfix. Names
+followed by a number are Postfix commands or server programs, while
+unnumbered names inside shaded areas represent Postfix queues. To
+avoid clutter, the path for local submission is simplified (the
+OVERVIEW document has a more complete description of the Postfix
+architecture). </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td align="center"> SMTP-only <br> filters </td>
+
+<td> </td>
+
+<td align="center"> non-SMTP <br> filters </td>
+
+</tr>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td align="center"> <table> <tr> <td align="center">
+^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt>
+</td> </tr> </table> </td>
+
+<td rowspan="2"> </td>
+
+<td rowspan="3" align="center"> <table> <tr> <td align="center">
+^<br> <tt> |<br> |<br> | </tt> </td> <td align="center"> <tt> |<br>
+|<br> |<br> v </tt> </td> </tr> </table> </td>
+
+</tr>
+
+<tr>
+
+<td> Network </td> <td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> smtpd(8)
+</td>
+
+</tr>
+
+<tr>
+
+<td colspan="3"> </td> <td> <tt> \ </tt> </td>
+
+</tr>
+
+<tr>
+
+<td> Network </td> <td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> qmqpd(8)
+</td>
+
+<td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> cleanup(8)
+</td>
+
+<td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> <a
+href="QSHAPE_README.html#incoming_queue"> incoming </a> </td>
+
+</tr>
+
+<tr>
+
+<td colspan="3"> </td> <td> <tt> / </tt> </td>
+
+</tr>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> pickup(8)
+</td>
+
+</tr>
+
+<tr> <td colspan="2"> </td> <td align="center"> : </td> </tr>
+
+<tr>
+
+<td> Local </td> <td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> sendmail(1)
+</td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<h2><a name="building">Building Milter applications</a></h2>
+
+<p> Milter applications have been written in C, JAVA and Perl, but
+this document deals with C applications only. For these, you need
+an object library that implements the Sendmail 8 Milter protocol.
+Postfix currently does not provide such a library, but Sendmail
+does. </p>
+
+<p> Some
+systems install the Sendmail libmilter library by default. With
+other systems, libmilter may be provided by a package (called
+"sendmail-devel" on some Linux systems). </p>
+
+<p> Once libmilter is installed, applications such as <a
+href="http://www.opendkim.org/">OpenDKIM</a> and
+<a href="http://www.trusteddomain.org/opendmarc/">OpenDMARC</a>
+build out of the box without requiring any tinkering:</p>
+
+<blockquote>
+<pre>
+$ <b>gzcat opendkim-<i>x.y.z</i>.tar.gz | tar xf -</b>
+$ <b>cd opendkim-<i>x.y.z</i></b>
+$ <b>./configure ...<i>options</i>...</b>
+$ <b>make</b>
+[...<i>lots of output omitted</i>...]
+$ <b>make install</b>
+</pre>
+</blockquote>
+
+<h2><a name="running">Running Milter applications</a></h2>
+
+<p> To run a Milter application, see the documentation of the filter
+for options. A typical command looks like this:</p>
+
+<blockquote>
+<pre>
+# <b>/some/where/opendkim -l -u <i>userid</i> -p inet:<i>portnumber</i>@localhost ...<i>other options</i>...</b>
+</pre>
+</blockquote>
+
+<p> Please specify a <i>userid</i> value that isn't used for other
+applications (not "postfix", not "www", etc.). </p>
+
+<h2><a name="config">Configuring Postfix</a></h2>
+
+<p> Like Sendmail, Postfix has a lot of configuration options that
+control how it talks to Milter applications. Besides global options
+that apply to all Milter applications, Postfix 3.0 and later
+support per-Milter timeouts, per-Milter error handling, etc. </p>
+
+<p> Information in this section: </p>
+
+<ul>
+
+<li><a href="#smtp-only-milters">SMTP-Only Milter applications </a>
+
+<li><a href="#non-smtp-milters">Non-SMTP Milter applications </a>
+
+<li><a href="#errors">Milter error handling </a>
+
+<li><a href="#version">Milter protocol version</a>
+
+<li><a href="#timeouts">Milter protocol timeouts</a>
+
+<li><a href="#per-milter">Different settings for different Milter
+applications </a>
+
+<li><a href="#per-client">Different settings for different SMTP
+clients </a>
+
+<li><a href="#macros">Sendmail macro emulation</a>
+
+<li><a href="#send-macros">What macros will Postfix send to Milters?</a>
+
+</ul>
+
+<h3><a name="smtp-only-milters">SMTP-Only Milter applications</a></h3>
+
+<p> The SMTP-only Milter applications handle mail that arrives via
+the Postfix smtpd(8) server. They are typically used to filter
+unwanted mail, and to sign mail from authorized SMTP clients. Mail
+that arrives via the Postfix smtpd(8) server is not filtered by the
+non-SMTP filters that are described in the next section. </p>
+
+<blockquote> NOTE for Postfix versions that have a mail_release_date
+before 20141018: do not use the header_checks(5) IGNORE action to remove
+Postfix's own Received: message header. This causes problems with
+mail signing filters. Instead, keep Postfix's own Received: message
+header and use the header_checks(5) REPLACE action to sanitize
+information. </blockquote>
+
+<p> You specify SMTP-only Milter applications (there can be more
+than one) with the smtpd_milters parameter. Each Milter application
+is identified by the name of its listening socket; other Milter
+configuration options will be discussed in later sections. Milter
+applications are applied in the order as specified, and the first
+Milter application that rejects a command will override the responses
+from other Milter applications. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Milters for mail that arrives via the smtpd(8) server.
+ # See below for socket address syntax.
+ smtpd_milters = inet:localhost:<i>portnumber</i> ...<i>other filters</i>...
+</pre>
+</blockquote>
+
+<p> The general syntax for listening sockets is as follows: </p>
+
+<blockquote>
+
+<dl>
+
+<dt> <b>unix:</b><i>pathname</i> </dt> <dd><p>Connect to the local
+UNIX-domain server that is bound to the specified pathname. If the
+smtpd(8) or cleanup(8) process runs chrooted, an absolute pathname
+is interpreted relative to the Postfix queue directory. On many
+systems, <b>local</b> is a synonym for <b>unix</b></p> </dd>
+
+<dt> <b> inet:</b><i>host</i><b>:</b><i>port</i> </dt> <dd> <p>
+Connect to the specified TCP port on the specified local or remote
+host. The host and port can be specified in numeric or symbolic
+form.</p>
+
+<p> NOTE: Postfix syntax differs from Milter syntax which has the
+form <b>inet:</b><i>port</i><b>@</b><i>host</i>. </p> </dd>
+
+</dl>
+
+</blockquote>
+
+<p> For advanced configuration see "<a href="#per-client">Different
+settings for different SMTP clients</a>" and "<a
+href="#per-milter">Different settings for different Milter
+applications</a>". </p>
+
+<h3> <a name="non-smtp-milters">Non-SMTP Milter applications </a> </h3>
+
+<p> The non-SMTP Milter applications handle mail that arrives via
+the Postfix sendmail(1) command-line or via the Postfix qmqpd(8)
+server. They are typically used to digitally sign mail. Although
+non-SMTP filters can be used to filter unwanted mail, there are
+limitations as discussed later in this section. Mail that arrives
+via the Postfix smtpd(8) server is not filtered by the non-SMTP
+filters. </p>
+
+<p> NOTE: Do not use the header_checks(5) IGNORE action to remove
+Postfix's own Received: message header. This causes problems with
+mail signing filters. Instead, keep Postfix's own Received: message
+header and use the header_checks(5) REPLACE action to sanitize
+information. </p>
+
+<p> You specify non-SMTP Milter applications with the non_smtpd_milters
+parameter. This parameter uses the same syntax as the smtpd_milters
+parameter in the previous section. As with the SMTP-only filters,
+you can specify more than one Milter application; they are applied
+in the order as specified, and the first Milter application that
+rejects a command will override the responses from the other
+applications. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Milters for non-SMTP mail.
+ # See below for socket address syntax.
+ non_smtpd_milters = inet:localhost:<i>portnumber</i> ...<i>other filters</i>...
+</pre>
+</blockquote>
+
+<p> There's one small complication when using Milter applications
+for non-SMTP mail: there is no SMTP session. To keep Milter
+applications happy, the Postfix cleanup(8) server actually has to
+simulate the SMTP client CONNECT and DISCONNECT events, and the
+SMTP client EHLO, MAIL FROM, RCPT TO and DATA commands. </p>
+
+<ul>
+
+<li> <p> When new mail arrives via the sendmail(1) command line,
+the Postfix cleanup(8) server pretends that the mail arrives with
+ESMTP from "localhost" with IP address "127.0.0.1". The result is
+very similar to what happens with command line submissions in
+Sendmail version 8.12 and later, although Sendmail uses a different
+mechanism to achieve this result. </p>
+
+<li> <p> When new mail arrives via the qmqpd(8) server, the Postfix
+cleanup(8) server pretends that the mail arrives with ESMTP, and
+uses the QMQPD client hostname and IP address. </p>
+
+<li> <p> When old mail is re-injected into the queue with "postsuper
+-r", the Postfix cleanup(8) server uses the same client information
+that was used when the mail arrived as new mail. </p>
+
+</ul>
+
+<p> This generally works as expected, with only one exception:
+non-SMTP filters must not REJECT or TEMPFAIL simulated RCPT TO
+commands. When a non_smtpd_milters application REJECTs or TEMPFAILs
+a recipient, Postfix will report a configuration error, and mail
+will stay in the queue. </p>
+
+<h4> Signing internally-generated bounce messages </h4>
+
+<p> Postfix normally does not apply content filters to mail
+that is generated internally such as bounces or Postmaster
+notifications. Filtering internally-generated bounces would result
+in loss of mail when a filter rejects a message, as the resulting
+double-bounce message would almost certainly also be blocked. </p>
+
+<p> To sign Postfix's own bounce messages, enable filtering of
+internally-generated bounces (line 2 below), and don't reject any
+internally-generated bounces with non_smtpd_milters, header_checks
+or body_checks (lines 3-5 below). </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 internal_mail_filter_classes = bounce
+3 non_smtpd_milters = <i>don't reject internally-generated bounces</i>
+4 header_checks = <i>don't reject internally-generated bounces</i>
+5 body_checks = <i>don't reject internally-generated bounces</i>
+</pre>
+</blockquote>
+
+<h3><a name="errors">Milter error handling</a></h3>
+
+<p> The milter_default_action parameter specifies how Postfix handles
+Milter application errors. The default action is to respond with a
+temporary error status, so that the client will try again later.
+Specify "accept" if you want to receive mail as if the filter does
+not exist, and "reject" to reject mail with a permanent status.
+The "quarantine" action is like "accept" but freezes the message
+in the "hold" queue, and is available with Postfix 2.6 or later.
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # What to do in case of errors? Specify accept, reject, tempfail,
+ # or quarantine (Postfix 2.6 or later).
+ milter_default_action = tempfail
+</pre>
+</blockquote>
+
+<p> See "<a href="#per-milter">Different settings for different
+Milter applications</a>" for advanced configuration options. </p>
+
+<h3><a name="version">Milter protocol version</a></h3>
+
+<p> As Postfix is not built with the Sendmail libmilter library,
+you may need to configure the Milter protocol version that Postfix
+should use. The default version is 6 (before Postfix 2.6 the default
+version is 2). </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Postfix &ge; 2.6
+ milter_protocol = 6
+ # 2.3 &le; Postfix &le; 2.5
+ milter_protocol = 2
+</pre>
+</blockquote>
+
+<p> If the Postfix milter_protocol setting specifies a too low
+version, the libmilter library will log an error message like this:
+</p>
+
+<blockquote>
+<pre>
+<i>application name</i>: st_optionneg[<i>xxxxx</i>]: 0x<i>yy</i> does not fulfill action requirements 0x<i>zz</i>
+</pre>
+</blockquote>
+
+<p> The remedy is to increase the Postfix milter_protocol version
+number. See, however, the <a href="#limitations">limitations</a>
+section below for features that aren't supported by Postfix. </p>
+
+<p> With Postfix 2.7 and earlier, if the Postfix milter_protocol
+setting specifies a too high
+version, the libmilter library simply hangs up without logging a
+warning, and you see a Postfix warning message like one of the
+following: </p>
+
+<blockquote>
+<pre>
+warning: milter inet:<i>host</i>:<i>port</i>: can't read packet header: Unknown error : 0
+warning: milter inet:<i>host</i>:<i>port</i>: can't read packet header: Success
+warning: milter inet:<i>host</i>:<i>port</i>: can't read SMFIC_DATA reply packet header: No such file or directory
+</pre>
+</blockquote>
+
+<p> The remedy is to lower the Postfix milter_protocol version
+number. Postfix 2.8 and later will automatically turn off protocol
+features that the application's libmilter library does not expect.
+</p>
+
+<p> See "<a href="#per-milter">Different settings for different
+Milter applications</a>" for advanced configuration options. </p>
+
+<h3><a name="timeouts">Milter protocol timeouts</a></h3>
+
+<p> Postfix uses different time limits at different Milter protocol
+stages. The table shows the timeout settings and the corresponding
+protocol stages
+(EOH = end of headers; EOM = end of message). </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Postfix parameter </th> <th> Time limit </th> <th> Milter
+protocol stage</th> </tr>
+
+<tr> <td> milter_connect_timeout </td> <td> 30s </td> <td> CONNECT
+</td> </tr>
+
+<tr> <td> milter_command_timeout </td> <td> 30s </td> <td> HELO,
+MAIL, RCPT, DATA, UNKNOWN </td> </tr>
+
+<tr> <td> milter_content_timeout </td> <td> 300s </td> <td> HEADER,
+EOH, BODY, EOM </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> Beware: 30s may be too short for Milter applications that do
+lots of DNS lookups. However, if you increase the above timeouts
+too much, remote SMTP clients may hang up and mail may be delivered
+multiple times. This is an inherent problem with before-queue
+filtering. </p>
+
+<p> See "<a href="#per-milter">Different settings for different
+Milter applications</a>" for advanced configuration options. </p>
+
+<h3><a name="per-milter">Different settings for different Milter
+applications </a></h3>
+
+<p> The previous sections list a number of Postfix main.cf parameters
+that control time limits and other settings for all Postfix Milter
+clients. This is sufficient for simple configurations. With more
+complex configurations it becomes desirable to have different
+settings for different Milter clients. This is supported with Postfix
+3.0 and later. </p>
+
+<p> The following example shows a "non-critical" Milter client with
+a short connect timeout, and with "accept" as default action when
+the service is unvailable. </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 smtpd_milters = { inet:host:port,
+3 connect_timeout=10s, default_action=accept }
+</pre>
+</blockquote>
+
+<p> Instead of a server endpoint, we now have a list enclosed in {}. </p>
+
+<ul>
+
+<li> <p> Line 2: The first item in the list is the server endpoint.
+This supports the exact same "inet" and "unix" syntax as described
+earlier. </p>
+
+<li> <p> Line 3: The remainder of the list contains per-Milter
+settings. These settings override global main.cf parameters, and
+have the same name as those parameters, without the "milter_" prefix.
+The per-Milter settings that are supported as of Postfix 3.0 are
+command_timeout, connect_timeout, content_timeout, default_action,
+and protocol. </p>
+
+</ul>
+
+<p> Inside the list, syntax is similar to what we already know from
+main.cf: items separated by space or comma. There is one difference:
+<b>you must enclose a setting in parentheses, as in "{ name = value
+}", if you want to have space or comma within a value or around
+"="</b>. </p>
+
+<h3><a name="per-client">Different settings for different SMTP
+clients </a></h3>
+
+<p> The smtpd_milter_maps feature supports different Milter settings
+for different client IP addresses. Lookup results override the the
+global smtpd_milters setting, and have the same syntax. For example,
+to disable Milter settings for local address ranges: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map
+ smtpd_milters = inet:host:port, { inet:host:port, ... }, ...
+
+/etc/postfix/smtpd_milter_map:
+ # Disable Milters for local clients.
+ 127.0.0.0/8 DISABLE
+ 192.168.0.0/16 DISABLE
+ ::/64 DISABLE
+ 2001:db8::/32 DISABLE
+</pre>
+
+<p> This feature is available with Postfix 3.2 and later. </p>
+
+<h3><a name="macros">Sendmail macro emulation</a></h3>
+
+<p> Postfix emulates a limited number of Sendmail macros, as shown
+in the table. Some macro values depend on whether a recipient is
+rejected (rejected recipients are available on request by the Milter
+application). Different macros are available at different Milter
+protocol stages (EOH = end-of-header, EOM = end-of-message); their
+availability is not
+always the same as in Sendmail. See the <a
+href="#workarounds">workarounds</a> section below for solutions.
+</p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Sendmail macro </th> <th> Milter protocol stage </th>
+<th> Description </th> </tr>
+
+<tr> <td> i </td> <td> DATA, EOH, EOM </td> <td> Queue ID, also
+Postfix queue file name </td> </tr>
+
+<tr> <td> j </td> <td> Always </td> <td> Value of myhostname </td>
+</tr>
+
+<tr> <td> _ </td> <td> Always </td> <td> The validated client name
+and address </td> </tr>
+
+<tr> <td> {auth_authen} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
+login name </td> </tr>
+
+<tr> <td> {auth_author} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
+sender </td> </tr>
+
+<tr> <td> {auth_type} </td> <td> MAIL, DATA, EOH, EOM </td> <td> SASL
+login method </td> </tr>
+
+<tr> <td> {client_addr} </td> <td> Always </td> <td> Remote client
+IP address </td> </tr>
+
+<tr> <td> {client_connections} </td> <td> CONNECT </td> <td>
+Connection concurrency for this client (zero if the client is
+excluded from all smtpd_client_* limits). </td> </tr>
+
+<tr> <td> {client_name} </td> <td> Always </td> <td> Remote client
+hostname <br> When address &rarr; name lookup or name &rarr; address
+verification fails: "unknown" </td> </tr>
+
+<tr> <td> {client_port} </td> <td> Always (Postfix &ge;2.5) </td>
+<td> Remote client TCP port </td> </tr>
+
+<tr> <td> {client_ptr} </td> <td> CONNECT, HELO, MAIL, DATA </td>
+<td> Client name from address &rarr; name lookup <br> When address
+&rarr; name lookup fails: "unknown" </td> </tr>
+
+<tr> <td> {cert_issuer} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td>
+TLS client certificate issuer </td> </tr>
+
+<tr> <td> {cert_subject} </td> <td> HELO, MAIL, DATA, EOH, EOM </td>
+<td> TLS client certificate subject </td> </tr>
+
+<tr> <td> {cipher_bits} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td>
+TLS session key size </td> </tr>
+
+<tr> <td> {cipher} </td> <td> HELO, MAIL, DATA, EOH, EOM </td> <td> TLS
+cipher </td> </tr>
+
+<tr> <td> {daemon_addr} </td> <td> Always (Postfix &ge;3.2) </td>
+<td> Local server IP address </td> </tr>
+
+<tr> <td> {daemon_name} </td> <td> Always </td> <td> value of
+milter_macro_daemon_name </td> </tr>
+
+<tr> <td> {daemon_port} </td> <td> Always (Postfix &ge;3.2) </td>
+<td> Local server TCP port </td> </tr>
+
+<tr> <td> {mail_addr} </td> <td> MAIL </td> <td> Sender address
+</td> </tr>
+
+<tr> <td> {mail_host} </td> <td> MAIL (Postfix &ge; 2.6, only with
+smtpd_milters) </td> <td> Sender next-hop destination </td> </tr>
+
+<tr> <td> {mail_mailer} </td> <td> MAIL (Postfix &ge; 2.6, only with
+smtpd_milters) </td> <td> Sender mail delivery transport </td> </tr>
+
+<tr> <td> {rcpt_addr} </td> <td> RCPT </td> <td> Recipient address
+<br> With rejected recipient: descriptive text </td> </tr>
+
+<tr> <td> {rcpt_host} </td> <td> RCPT (Postfix &ge; 2.6, only with
+smtpd_milters) </td> <td> Recipient next-hop destination <br> With
+rejected recipient: enhanced status code </td> </tr>
+
+<tr> <td> {rcpt_mailer} </td> <td> RCPT (Postfix &ge; 2.6, only with
+smtpd_milters) </td> <td> Recipient mail delivery transport <br>
+With rejected recipient: "error" </td> </tr>
+
+<tr> <td> {tls_version} </td> <td> HELO, MAIL, DATA, EOH, EOM </td>
+<td> TLS protocol version </td> </tr>
+
+<tr> <td> v </td> <td> Always </td> <td> value of milter_macro_v
+</td> </tr>
+
+</table>
+
+</blockquote>
+
+<h3><a name="send-macros">What macros will Postfix send to Milters?</a></h3>
+
+<p> Postfix sends specific sets of macros at different Milter protocol
+stages. The sets are configured with the parameters as shown in the
+table below (EOH = end of headers; EOM = end of message). The
+protocol version is a number that Postfix sends at the beginning
+of the Milter protocol handshake. </p>
+
+<p> As of Sendmail 8.14.0, Milter applications can specify what
+macros they want to receive at different Milter protocol stages.
+An application-specified list takes precedence over a Postfix-specified
+list. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Postfix parameter </th> <th> Milter protocol version </th>
+<th> Milter protocol stage </th> </tr>
+
+<tr> <td> milter_connect_macros </td> <td> 2 or higher </td> <td>
+CONNECT </td> </tr>
+
+<tr> <td> milter_helo_macros </td> <td> 2 or higher </td> <td>
+HELO/EHLO </td> </tr>
+
+<tr> <td> milter_mail_macros </td> <td> 2 or higher </td> <td> MAIL
+FROM </td> </tr>
+
+<tr> <td> milter_rcpt_macros </td> <td> 2 or higher </td> <td> RCPT
+TO </td> </tr>
+
+<tr> <td> milter_data_macros </td> <td> 4 or higher </td> <td> DATA
+</td> </tr>
+
+<tr> <td> milter_end_of_header_macros </td> <td> 6 or higher </td>
+<td> EOH </td> </tr>
+
+<tr> <td> milter_end_of_data_macros </td> <td> 2 or higher </td>
+<td> EOM </td> </tr>
+
+<tr> <td> milter_unknown_command_macros </td> <td> 3 or higher </td>
+<td> unknown command </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> By default, Postfix will send only macros whose values have been
+updated with information from main.cf or master.cf, from an SMTP session
+(for example; SASL login, or TLS certificates) or from a Mail delivery
+transaction (for example; queue ID, sender, or recipient). </p>
+
+<p> To force a macro to be sent even when its value has not been updated,
+you may specify macro default values with the milter_macro_defaults
+parameter. Specify zero or more <i>name=value</i> pairs separated by
+comma or whitespace; you may even specify macro names that Postfix does
+not know about! </p>
+
+<h2><a name="workarounds">Workarounds</a></h2>
+
+<ul>
+
+<li> <p> To avoid breaking DKIM etc. signatures with an SMTP-based
+content filter, update the before-filter SMTP client in master.cf,
+and add a line with "-o disable_mime_output_conversion=yes" (note:
+no spaces around the "="). For details, see the <a
+href="FILTER_README.html#advanced_filter">advanced content filter</a>
+example. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ # =============================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =============================================================
+ scan unix - - n - 10 smtp
+ -o smtp_send_xforward_command=yes
+ -o disable_mime_output_conversion=yes
+ -o smtp_generic_maps=
+</pre>
+
+<li> <p> Some Milter applications use the "<tt>{if_addr}</tt>" macro
+to recognize local mail; this macro does not exist in Postfix.
+Workaround: use the "<tt>{daemon_addr}</tt>" (Postfix &ge; 3.2) or
+"<tt>{client_addr}</tt>" macro instead. </p>
+
+<li> <p> Some Milter applications log a warning that looks like
+this: </p>
+
+<blockquote> <pre>
+sid-filter[36540]: WARNING: sendmail symbol 'i' not available
+</pre>
+</blockquote>
+
+<p> And they may insert an ugly message header with "unknown-msgid"
+like this: </p>
+
+<blockquote>
+<pre>
+X-SenderID: Sendmail Sender-ID Filter vx.y.z host.example.com &lt;unknown-msgid&gt;
+</pre>
+</blockquote>
+
+<p> The problem is that Milter applications expect that the queue
+ID is known <i>before</i> the MTA accepts the MAIL FROM (sender)
+command. Postfix does not choose a queue ID, which is used as the
+queue file name, until <i>after</i> it accepts the first valid RCPT
+TO (recipient) command. </p>
+
+<p> If you experience the ugly header problem, see if a recent
+version of the Milter application fixes it. For example, current
+versions of dkim-filter and dk-filter already have code that looks
+up the Postfix queue ID at a later protocol stage, and sid-filter
+version 1.0.0 no longer includes the queue ID in the message header.
+</p>
+
+<p> To fix the ugly message header, you will need to add code that
+looks up the Postfix queue ID at some later point in time. The
+example below adds the lookup after the end-of-message. </p>
+
+<ul>
+
+<li> <p> Edit the filter source file (typically named
+<tt>xxx-filter/xxx-filter.c</tt> or similar). </p>
+
+<li> <p> Look up the <tt>mlfi_eom()</tt> function and add code near
+the top shown as <b>bold</b> text below: </p>
+
+</ul>
+
+<blockquote>
+<pre>
+dfc = cc->cctx_msg;
+assert(dfc != NULL);
+<b>
+/* Determine the job ID for logging. */
+if (dfc->mctx_jobid == 0 || strcmp(dfc->mctx_jobid, JOBIDUNKNOWN) == 0) {
+ char *jobid = smfi_getsymval(ctx, "i");
+ if (jobid != 0)
+ dfc->mctx_jobid = jobid;
+}</b>
+</pre>
+</blockquote>
+
+<p> NOTES: </p>
+
+<ul>
+
+<li> <p> Different mail filters use slightly different names for
+variables. If the above code does not compile, look elsewhere in
+the mail filter source file for code that looks up the "i" macro
+value, and copy that code. </p>
+
+<li> <p> This change fixes only the ugly message header, but not
+the WARNING message. Fortunately, many Milters log that message
+only once. </p>
+
+</ul>
+
+</ul>
+
+<h2><a name="limitations">Limitations</a></h2>
+
+<p> This section lists limitations of the Postfix Milter implementation.
+Some limitations will be removed as the implementation is extended
+over time. Of course the usual limitations of before-queue filtering
+will always apply. See the CONTENT_INSPECTION_README document for
+a discussion. </p>
+
+<ul>
+
+<li> <p> The Milter protocol has evolved over time. Therefore,
+different Postfix versions implement different feature sets. </p>
+
+<table border="1">
+
+<tr> <th> Postfix </th> <th> Supported Milter requests </th>
+</tr>
+
+<tr> <td align="center"> 2.6 </td> <td> All Milter requests of
+Sendmail 8.14.0 (see notes below). </td> </tr>
+
+<tr> <td align="center"> 2.5 </td> <td> All Milter requests of
+Sendmail 8.14.0, except: <br> SMFIP_RCPT_REJ (report rejected
+recipients to the mail filter), <br> SMFIR_CHGFROM (replace sender,
+with optional ESMTP parameters), <br> SMFIR_ADDRCPT_PAR (add
+recipient, with optional ESMTP parameters). </td> </tr>
+
+<tr> <td align="center"> 2.4 </td> <td> All Milter requests of
+Sendmail 8.13.0. </td> </tr>
+
+<tr> <td align="center"> 2.3 </td> <td> All Milter requests of
+Sendmail 8.13.0, except: <br> SMFIR_REPLBODY (replace message body).
+
+</table>
+
+<li> <p> For Milter applications that are written in C, you need
+to use the Sendmail libmilter library. </p>
+
+<li> <p> Postfix has TWO sets of mail filters: filters that are used
+for SMTP mail only (specified with the smtpd_milters parameter),
+and filters for non-SMTP mail (specified with the non_smtpd_milters
+parameter). The non-SMTP filters are primarily for local submissions.
+</p>
+
+<p> When mail is filtered by non_smtpd_milters, the Postfix cleanup(8)
+server has to simulate SMTP client requests. This works as expected,
+with only one exception: non_smtpd_milters must not REJECT or
+TEMPFAIL simulated RCPT TO commands. When this rule is violated,
+Postfix will report a configuration error, and mail will stay in
+the queue. </p>
+
+<li> <p> When you use the before-queue content filter for incoming
+SMTP mail (see SMTPD_PROXY_README), Milter applications have access
+only to the SMTP command information; they have no access to the
+message header or body, and cannot make modifications to the message
+or to the envelope. </p>
+
+<li> <p> Postfix 2.6 ignores the optional ESMTP parameters in
+requests to replace the sender (SMFIR_CHGFROM) or to append a
+recipient (SMFIR_ADDRCPT_PAR). Postfix logs a warning message when
+a Milter application supplies such ESMTP parameters: </p>
+
+<pre>
+warning: <i>queue-id</i>: cleanup_chg_from: ignoring ESMTP arguments "<i>whatever</i>"
+warning: <i>queue-id</i>: cleanup_add_rcpt: ignoring ESMTP arguments "<i>whatever</i>"
+</pre>
+
+<li> <p> Postfix 2.3 does not implement requests to replace the
+message body. Milter applications log a warning message when they
+need this unsupported operation: </p>
+
+<pre>
+st_optionneg[134563840]: 0x3d does not fulfill action requirements 0x1e
+</pre>
+
+<p> The solution is to use Postfix version 2.4 or later. </p>
+
+<li> <p> Most Milter configuration options are global. Future Postfix
+versions may support per-Milter timeouts, per-Milter error handling,
+etc. </p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/MULTI_INSTANCE_README.html b/proto/MULTI_INSTANCE_README.html
new file mode 100644
index 0000000..196f804
--- /dev/null
+++ b/proto/MULTI_INSTANCE_README.html
@@ -0,0 +1,1274 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Managing multiple Postfix instances on a single host</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Managing
+multiple Postfix instances on a single host</h1>
+
+<hr>
+
+<h2>Overview </h2>
+
+<p> This document is a guide to managing multiple Postfix instances
+on a single host using the postmulti(1) instance manager. Multi-instance
+support is available with Postfix version 2.6 and later. See the
+postfix-wrapper(5) manual page for background on the instance
+management framework, and on how to deploy a custom instance manager.
+</p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#why"> Why multiple Postfix instances </a>
+
+<li><a href="#split"> Null-client instances versus service instances </a>
+
+<li><a href="#quick"> Multi-instance walk-through </a>
+
+<li><a href="#parts"> Components of a Postfix system </a>
+
+<li><a href="#default"> The default Postfix instance </a>
+
+<li><a href="#group"> Instance groups </a>
+
+<li><a href="#params"> Multi-instance configuration parameters </a>
+
+<li><a href="#how"> Using the postmulti(1) command </a>
+
+<li><a href="#credits"> Credits </a>
+
+</ul>
+
+<h2><a name="why"> Why multiple Postfix instances </a></h2>
+
+<p> Postfix is a general-purpose mail system that can be configured
+to serve a variety of needs. Examples of Postfix applications are: </p>
+
+<ul>
+
+<li><p> Local mail submission for shell users and system processes. </p>
+
+<li><p> Incoming (MX host) email from the Internet. </p>
+
+<li><p> Outbound mail relay for a corporate network. </p>
+
+<li><p> Authenticated submission for roaming users. </p>
+
+<li><p> Before/after content-filter mail. </p>
+
+</ul>
+
+<p> A single Postfix configuration can provide many or all of these
+services, but a complex interplay of settings may be required, for
+example with master.cf options overriding main.cf settings. In this
+document we take the view that multiple Postfix instances may be a
+simpler way to configure a multi-function Postfix system. With
+multiple Postfix instances, each instance has its own directories
+for configuration, queue and data files, but it shares all Postfix
+program and documentation files with other instances. </p>
+
+<p> Since there is no single right way to configure your system,
+we recommend that you choose what makes you most comfortable. If
+different Postfix services don't involve incompatible main.cf or
+master.cf settings, and if they can be combined together without
+complex tricks, then a single monolithic configuration may be the
+simplest approach. </p>
+
+<p> The purpose of multi-instance support in Postfix is not to force
+you to create multiple Postfix instances, but rather to give you a
+choice. Multiple instances give you the freedom to tune each Postfix
+instance to a single task that it does well and to combine instances
+into complete systems. </p>
+
+<p> With the introduction of the postmulti(1) utility and the reduction
+of the per-instance configuration footprint of a secondary Postfix
+instance to just a main.cf and master.cf file (other files are now in
+shared locations), we hope that multiple instances will be easier to
+use than ever before. </p>
+
+<h2><a name="split"> Null-client instances versus service instances </a></h2>
+
+<p> In the multi-instance approach to configuring Postfix, the first
+simplification is with the default local-submission Postfix instance.
+</p>
+
+<p> Most UNIX systems require support for email submission with the
+sendmail(1) command so that system processes such as cron jobs can
+send status reports, and so that system users can send email with
+command-line utilities. Such email can be handled with a <a
+href="STANDARD_CONFIGURATION_README.html#null_client">null-client</a>
+Postfix configuration that forwards all mail to a central mail hub.
+The null client will typically either not run an SMTP listener at
+all (master_service_disable = inet), or it will listen only on the
+loopback interface (inet_interfaces = loopback-only). </p>
+
+<p> When implementing specialized servers for inbound Internet
+email, outbound MTAs, internal mail hubs, and so on, we recommend
+using a null client for local submission and creating single-function
+secondary Postfix instances to serve the specialized needs. </p>
+
+<blockquote>
+
+<p> Note: usually, you need to use different "myhostname" settings
+when you run multiple instances on the same host. Otherwise, there
+will be false "mail loops back to myself" alarms when one instance
+tries to send mail into another instance. Typically, the null-client
+instance will use the system's hostname, and other instances will
+use their own dedicated "myhostname" settings. Different names are
+not needed when instances send mail to each other with a protocol
+other than SMTP, or with SMTP over a TCP port other than 25 as is
+usual with SMTP-based content filters. </p>
+
+</blockquote>
+
+<h2><a name="quick"> Multi-instance walk-through </a></h2>
+
+<p> Before discussing the fine details of multi-instance operation
+we first show the steps for creating a border mail server. This
+server has with a null-client Postfix instance for local submission,
+an input Postfix instance to receive mail from the Internet, plus
+an <a href="FILTER_README.html#advanced_filter">advanced</a> SMTP
+content-filter and an output Postfix instance to deliver filtered
+email to its internal destination. </p>
+
+<h3>Setting up the null-client Postfix instance </h3>
+
+<p> On a border mail hub, while mail from the Internet requires a
+great deal of scrutiny, locally submitted messages are typically
+limited to mail from cron jobs and other system services. In this
+regard the border MTA is not different from other Unix hosts in
+your environment. For this reason, it will submit locally-generated
+email to the internal mail hub. We start the construction of the
+border mail server with the <a href="#default_instance">default</a>
+instance, which will be a local-submission <a
+href="STANDARD_CONFIGURATION_README.html#null_client">null client</a>:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # We are mta1.example.com
+ #
+ myhostname = mta1.example.com
+ mydomain = example.com
+
+ # Flat user-account namespace in example.com:
+ #
+ # user@example.com not user@host.example.com
+ #
+ myorigin = $mydomain
+
+ # Postfix 2.6+, disable inet services, specifically disable smtpd(8)
+ #
+ master_service_disable = inet
+
+ # No local delivery:
+ #
+ mydestination =
+ local_transport = error:5.1.1 Mailbox unavailable
+ alias_database =
+ alias_maps =
+ local_recipient_maps =
+
+ # Send everything to the internal mailhub
+ #
+ relayhost = [mailhub.example.com]
+
+ # Indexed table macro:
+ # (use "hash", ... when <a href="CDB_README.html">cdb</a> is not available)
+ #
+ default_database_type = cdb
+ indexed = ${default_database_type}:${config_directory}/
+
+ # Expose origin host of mail from "root", ...
+ #
+ smtp_generic_maps = ${indexed}generic
+
+ # Send messages addressed to "root", ... to the MTA support team
+ #
+ virtual_alias_maps = ${indexed}virtual
+
+/etc/postfix/generic:
+ # The smarthost supports "+" addressing (recipient_delimiter = +).
+ # Mail from "root" exposes the origin host, without replies
+ # and bounces going back to the same host.
+ #
+ # On clustered MTAs this file is typically machine-built from
+ # a template file. The build process expands the template into
+ # "mtaadmin+root=mta1"
+ #
+ root mtaadmin+root=mta1
+
+/etc/postfix/virtual:
+ # Caretaker aliases:
+ #
+ root mtaadmin
+ postmaster root
+</pre>
+</blockquote>
+
+<p> You would typically also add a Makefile, to automatically run
+postmap(1) commands when source files change. This Makefile also
+creates a "generic" database when none exists. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/Makefile:
+ MTAADMIN=mtaadmin
+
+ all: virtual.cdb generic.cdb
+
+ generic: Makefile
+ @echo Creating $@
+ @rm -f $@.tmp
+ @printf '%s\t%s+root=%s\n' root ${MTAADMIN} `uname -n` &gt; $@.tmp
+ @mv $@.tmp generic
+
+ %.cdb: %
+ postmap cdb:$&lt;
+</pre>
+</blockquote>
+
+<p> Construct the "virtual" and "generic" databases (the latter is
+created by running "make"), then start and test the null-client:
+</p>
+
+<blockquote>
+<pre>
+# cd /etc/postfix; make
+# postfix start
+# sendmail -i -f root -t &lt;&lt;EOF
+From: root
+To: root
+Subject: test
+
+testing
+EOF
+</pre>
+</blockquote>
+
+<p> The test message should be delivered to the members of the "mtaadmin"
+address group (or whatever address group you choose) with the
+following headers: </p>
+
+<blockquote>
+<pre>
+From: mtaadmin+root=mta1@example.com
+To: mtadmin+root=mta1@example.com
+Subject: test
+</pre>
+</blockquote>
+
+<h3>Setting up the "output" Postfix instance </h3>
+
+<p> With the null-client instance out of the way, we can create the
+MTA "output" instance that will deliver filtered mail to the inside
+network. We add the "output" instance first, because the output
+instance needs to be up and running before the input instance can
+be fully tested, and when the system boots, the "output" instance
+must start before the input instance. We will put the output and
+input instances into a single instance group named "mta". </p>
+
+<p> Just once, when adding the first secondary instance, enable
+multi-instance support in the default (null-client) instance: </p>
+
+<blockquote>
+<pre>
+# postmulti -e init
+</pre>
+</blockquote>
+
+<p> Then create the output instance: <p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-out -G mta -e create
+</pre>
+</blockquote>
+
+<p> The instance configuration directory defaults to /etc/postfix-out,
+more precisely, the "postfix-out" subdirectory of the parent directory
+of the default-instance configuration directory. The new instance will
+be created in a "disabled" state: </p>
+
+<blockquote>
+<pre>
+/etc/postfix-out/main.cf
+ #
+ # ... "stock" main.cf settings ...
+ #
+ multi_instance_name = postfix-out
+ queue_directory = /var/spool/postfix-out
+ data_directory = /var/lib/postfix-out
+ #
+ multi_instance_enable = no
+ master_service_disable = inet
+ authorized_submit_users =
+</pre>
+</blockquote>
+
+<p> This instance has a "stock" master.cf file, and its queue and
+data directories, also named "postfix-out", will be located in the
+same parent directories as the corresponding directories of the
+default instance (e.g., /var/spool/postfix-out and /var/lib/postfix-out).
+</p>
+
+<p> While this instance is immediately safe to start, it is not yet
+usefully configured. It needs to be customized to fit the role of a
+post-filter re-injection SMTP service. Typical additions include: </p>
+
+<blockquote>
+<pre>
+/etc/postfix-out/master.cf:
+ # Replace default "smtp inet" entry with one listening on port 10026.
+ 127.0.0.1:10026 inet n - n - - smtpd
+
+/etc/postfix-out/main.cf
+ # ...
+
+ # Comment out if you don't use IPv6 internally
+ # inet_protocols = ipv4
+ inet_interfaces = loopback-only
+ mynetworks_style = host
+ smtpd_authorized_xforward_hosts = $mynetworks
+
+ # Don't anvil(8) control the re-injection port.
+ #
+ smtpd_client_connection_count_limit = 0
+ smtpd_client_event_limit_exceptions = $mynetworks
+
+ # Best practice when inet_interfaces is set, as this is not a
+ # "secondary IP personality" configuration.
+ #
+ smtp_bind_address = 0.0.0.0
+
+ # All header rewriting happens upstream
+ #
+ local_header_rewrite_clients =
+
+ # No local delivery on border gateway
+ #
+ mydestination =
+ alias_maps =
+ alias_database =
+ local_recipient_maps =
+ local_transport = error:5.1.1 Mailbox unavailable
+
+ # May need a recipient_delimiter for per-user transport lookups:
+ #
+ recipient_delimiter = +
+
+ # Only one (unrestricted client)
+ # With multiple instances, rarely need "-o param=value" overrides
+ # in master.cf, each instance gets its own main.cf file.
+ #
+ # Postfix 2.10 and later: specify empty smtpd_relay_restrictions.
+ smtpd_relay_restrictions =
+ smtpd_recipient_restrictions = permit_mynetworks, reject
+
+ # Tolerate occasional high latency in the content filter.
+ #
+ smtpd_timeout = 1200s
+
+ # Best when empty, with all parent domain matches explicit.
+ #
+ parent_domain_matches_subdomains =
+
+ # Use the "relay" transport for inbound mail, and the default
+ # "smtp" transport for outbound mail (bounces, ...). The latter
+ # won't starve the former of delivery agent slots.
+ #
+ relay_domains = example.com, .example.com
+
+ # With xforward, match the input instance setting, if you
+ # want "yes", set both to "yes".
+ #
+ smtpd_client_port_logging = no
+
+ # Transport settings ...
+ # Message size limit
+ # Concurrency tuning for "relay" and "smtp" transport
+ # ...
+</pre>
+</blockquote>
+
+<p> With the "output" configuration in place, enable and start the
+instance: </p>
+
+<blockquote>
+<pre>
+1 # postmulti -i postfix-out -x postconf -e \
+2 "master_service_disable =" "authorized_submit_users = root"
+3 # postmulti -i postfix-out -e enable
+4 # postmulti -i postfix-out -p start
+</pre>
+</blockquote>
+
+<p> This uses the postmulti(1) command to invoke postconf(1) in the
+context (MAIL_CONFIG=/etc/postfix-out) of the output instance. </p>
+
+<ul>
+
+<li> <p> Lines 1-2: With "authorized_submit_users = root", the
+superuser can test the postfix-out instance with "postmulti -i
+postfix-out -x sendmail -bv recipient...", but otherwise local
+submission remains disabled. </p>
+
+<li> <p> Lines 1-2: With "master_service_disable =", the "inet"
+listeners are re-enabled. </p>
+
+<li> <p> Line 3: The output instance is enabled for multi-instance
+start/stop. </p>
+
+<li> <p> Line 4: The output instance is started. </p>
+
+</ul>
+
+<p> Test the output instance by submitting probe messages via "sendmail
+-bv" and "telnet". For production systems, in-depth configuration tests
+should be done on a lab system. The simple tests just suggested will only
+confirm successful deployment of a configuration that should already be
+known good. </p>
+
+<h3> Setting up the content-filter proxy </h3>
+
+<p> With the output instance ready, deploy your content-filter
+proxy. Most proxies will need their own /etc/rc* start/stop script.
+Some proxies, however, are started on demand by the Postfix spawn(8)
+service, in which case you need to add the relevant spawn(8) entry
+to the output instance master.cf file. </p>
+
+<p> Configure the proxy to listen on 127.0.0.1:10025 and to re-inject
+filtered email to 127.0.0.1:10026. Start the proxy service if
+necessary, then test the proxy via "telnet" or automated SMTP
+injectors. The proxy should support the following ESMTP features:
+DSN, 8BITMIME, and XFORWARD. In addition, the proxy should support
+multiple mail deliveries within an SMTP session. </p>
+
+<h3> Setting up the input Postfix instance </h3>
+
+<p> The input Postfix instance receives mail from the network and
+sends it through the content filter. Now we create the input instance,
+also part of the "mta" instance group: </p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-in -G mta -e create
+</pre>
+</blockquote>
+
+<p> The new instance configuration directory defaults to /etc/postfix-in,
+more precisely, the "postfix-in" subdirectory of the parent directory
+of the default-instance configuration directory. The new instance will
+be created in a "disabled" state: </p>
+
+<blockquote>
+<pre>
+/etc/postfix-in/main.cf
+ #
+ # ... "stock" main.cf settings ...
+ #
+ multi_instance_name = postfix-in
+ queue_directory = /var/spool/postfix-in
+ data_directory = /var/lib/postfix-in
+ #
+ multi_instance_enable = no
+ master_service_disable = inet
+ authorized_submit_users =
+</pre>
+</blockquote>
+
+<p> As before, make appropriate changes to main.cf and master.cf to
+make the instance production ready. Consider setting "soft_bounce = yes"
+during the first few hours of deployment, so you can iron-out any unexpected
+"kinks". </p>
+
+<p> Manual testing can start with:
+
+<blockquote>
+<pre>
+/etc/postfix-in/main.cf
+ # Accept only local traffic, but allow impersonation:
+ inet_interfaces = 127.0.0.1
+ smtpd_authorized_xclient_hosts = 127.0.0.1
+</pre>
+</blockquote>
+
+<p> This allows you to use the Postfix-specific <a
+href="XCLIENT_README.html">XCLIENT</a> SMTP command to safely
+simulate connections from remote systems before any remote systems
+are able to connect. If the test results look good, revert the above
+settings to the required production values. Typical settings in the
+pre-filter input instance include: </p>
+
+<blockquote>
+<pre>
+/etc/postfix-in/main.cf
+ #
+ # ...
+ #
+
+ # No local delivery on border gateway
+ #
+ mydestination =
+ alias_maps =
+ alias_database =
+ local_recipient_maps =
+ local_transport = error:5.1.1 Mailbox unavailable
+
+ # Don't rewrite remote headers
+ #
+ local_header_rewrite_clients =
+
+ # All recipients of not yet filtered email go to the same filter together.
+ #
+ # With multiple instances, the content-filter is specified
+ # via transport settings not the "content_filter" transport
+ # switch override! Here the filter listens on local port 10025.
+ #
+ # If you need to route some users or recipient domains directly to the
+ # output instance bypassing the filter, just define a transport table
+ # with suitable entries.
+ #
+ default_transport = smtp:[127.0.0.1]:10025
+ relay_transport = $default_transport
+ virtual_transport = $default_transport
+ transport_maps =
+
+ # Pass original client log information through the filter.
+ #
+ smtp_send_xforward_command = yes
+
+ # Avoid splitting the envelope and scanning messages multiple times.
+ # Match the re-injection server's recipient limit.
+ #
+ smtp_destination_recipient_limit = 1000
+
+ # Tolerate occasional high latency in the content filter.
+ #
+ smtp_data_done_timeout = 1200s
+
+ # With xforward, match the output instance setting, if you
+ # want "yes", set both to "yes".
+ #
+ smtpd_client_port_logging = no
+
+ # ... Lots of settings for inbound MX host ...
+</pre>
+</blockquote>
+
+<p> With the "input" instance configured, enable and start it: </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-in -x postconf -e \
+ "master_service_disable =" "authorized_submit_users = root"
+# postmulti -i postfix-in -e enable
+# postmulti -i postfix-in -p start
+</pre>
+</blockquote>
+
+<p> That's it. You now have a 3-instance configuration. A null-client
+sending all locally submitted mail to the internal mail hub and a pair of
+"mta" instances that receive mail from the Internet, pass it through a
+content-filter, and then deliver it to the internal destination. </p>
+
+<p> Running "postfix start" or "postfix stop" will now start/stop all
+three Postfix instances. You can use "postfix -c /config/path start"
+to start just one instance, or use the instance name (or instance
+group name) via postmulti(1): </p>
+
+<blockquote>
+<pre>
+# postmulti -i - -p stop
+# postmulti -g mta -p status
+# postmulti -i postfix-out -p flush
+# postmulti -i postfix-in -p reload
+# ...
+</pre>
+</blockquote>
+
+<p> This example ends the multi-instance "walk through". The remainder
+of this document provides background information on Postfix
+multi-instance support features and options. </p>
+
+<h2><a name="parts"> Components of a Postfix system </a></h2>
+
+<p> A Postfix system consists of the following components: </p>
+
+<p> Shared among all instances: </p>
+
+<ul>
+
+<li><p> Command-line utilities for administrators and users installed in
+$command_directory, $sendmail_path, $mailq_path and $newaliases_path. </p>
+
+<li><p> Daemon executables, and run-time support files installed in
+$daemon_directory. </p>
+
+<li><p> Bundled documentation, installed in $html_directory,
+$manpage_directory and $readme_directory. </p>
+
+<li><p> Entries in /etc/passwd and /etc/group for the $mail_owner user and
+$setgid_group group. The $mail_owner user provides the mail system
+with a protected (non-root) execution context. The $setgid_group group
+is used exclusively to support the setgid postdrop(1) and postqueue(1)
+utilities (it <b>must not</b> be the primary group or secondary group
+of any users, including the $mail_owner user). </p>
+
+</ul>
+
+<p> Private to each instance: </p>
+
+<ul>
+
+<li><p> The main.cf, master.cf (and other optional) configuration
+files in $config_directory. </p>
+
+<li> <p> The maildrop, incoming, active, deferred and hold queues
+in $queue_directory (which contains additional directories needed
+by Postfix, and which optionally doubles as a chroot jail for Postfix
+daemon processes). </p>
+
+<li> <p> Various caches (TLS session, address verification, ...)
+in $data_directory. </p>
+
+</ul>
+
+<p> The Postfix configuration parameters mentioned above are
+collectively referred to as "installation parameters". Their default
+values are set when the Postfix software is built from source, and
+all but one may be optionally set to a non-default value via the
+main.cf file. The one parameter that (catch-22) cannot be set in
+main.cf is $config_directory, as this defines the location of the
+main.cf file itself. </p>
+
+<p> Though config_directory cannot be set in main.cf, postfix(1) and
+most of the other command-line Postfix utilities allow you to specify a
+non-default configuration directory via a command line option (typically
+<b>-c</b>) or via the MAIL_CONFIG environment variable. In this way,
+it is possible to have multiple configuration directories on the same
+machine, and to have multiple running master(8) daemons each with its
+own configuration files, queue directory and data directory. </p>
+
+<p> These multiple running copies of master(8) share the base Postfix
+software. They do not (and cannot) share their configuration
+directories, queue directories or data directories. </p>
+
+<p> Each combination of configuration directory, together with the queue
+directory and data directory (specified in the corresponding main.cf file)
+make up a Postfix <b>instance</b>. </p>
+
+<h2><a name="default"> The default Postfix instance </a></h2>
+
+<p> One Postfix instance is special: this is the instance whose
+configuration directory is the default one compiled into the Postfix
+utilities. The location of the default configuration directory is
+typically /etc/postfix, and can be queried via the "postconf -d
+config_directory" command. We call the instance with this configuration
+directory the "default instance". </p>
+
+<p> The default instance is responsible for local mail submission. The
+setgid postdrop(1) utility is used by the sendmail(1) local submission
+program to spool messages into the <b>maildrop</b> sub-directory of the
+queue directory of the default instance. </p>
+
+<p> Even in the rare case when "sendmail -C" is used to submit local mail
+into a non-default Postfix instance, for security reasons, postdrop(1)
+will consult the default main.cf file to check the validity of the
+requested non-default configuration directory. </p>
+
+<p> So, while in most other respects, all instances are equal, the
+default instance is "more equal than others". You may choose to create
+additional instances, but you must have at least the default instance,
+with its configuration directory in the default compiled-in location. </p>
+
+<h2><a name="group"> Instance groups </a></h2>
+
+<p> The postmulti(1) multi-instance manager supports the notion of an
+instance "group". Typically, the member instances of an instance group
+constitute a logical service, and are expected to all be running or all
+be stopped. </p>
+
+<p> In many cases a single Postfix instance will be a complete logical
+"service". You should define such instances as stand-alone instances
+that are not members of any instance "group". The null-client
+instance is an example of a non-group instance. </p>
+
+<p> When a logical service consists of multiple Postfix instances,
+often a pair of pre-filter and post-filter instances with a content
+filter proxy between them, the related instances should be members
+of a single instance group (however, the content filter usually has
+its own start/stop procedure that is separate from any Postfix
+instance). </p>
+
+<p> The default instance main.cf file's $multi_instance_directories
+configuration parameter lists the configuration directories of all
+secondary (non-default) instances. Together with the default instance,
+these secondary instances are managed by the multi-instance manager.
+Instances are started in the order listed, and stopped in the
+opposite order. For instances that are members of a service "group",
+you should arrange to start the service back-to-front, with the
+output stages started and ready to receive mail before the input
+stages are started. </p>
+
+<h2><a name="params"> Multi-instance configuration parameters </a></h2>
+
+<dl>
+
+<dt> multi_instance_wrapper </dt>
+
+<dd> <p> This default-instance configuration parameter must be set
+to a suitable multi-instance manager's "wrapper" program that
+controls the starting, stopping, etc. of a multi-instance Postfix
+system. To use the postmulti(1) manager described in this document,
+this parameter should be set with the "<a href="#init">postmulti
+-e init</a>" command. </p> </dd>
+
+<dt> multi_instance_directories </dt>
+
+<dd> <p> This default-instance configuration parameter specifies
+an optional list of the secondary instances controlled via the
+multi-instance manager. Instances are listed in their "start" order,
+with the default instance always started first (if enabled). If
+$multi_instance_directories is left empty, the postfix(1) command
+runs with multi-instance support turned off, and none of the
+multi_instance_ configuration parameters will have any effect. </p>
+
+<p> Do not assign a non-empty list of secondary instance configuration
+directories to multi_instance_directories until you have configured a
+suitable multi_instance_wrapper setting! This is best accomplished via
+the "<a href="#init">postmulti -e init</a>" command.
+</p> </dd>
+
+<dt> multi_instance_name </dt>
+
+<dd> <p> Each Postfix instance may be assigned a distinct name (with
+"postfix -e create/import/assign -I <i>name</i>..."). This name can
+be used with the postmulti(1) command-line utility to perform tasks
+on the instance by name (rather than the full pathname of its
+configuration directory). Choose a name that concisely captures the
+role of the instance (it must start with "postfix-"). It is an
+error for two instances to have the same $multi_instance_name. You
+can leave an instance "nameless" by leaving this parameter at the
+default empty setting. </p>
+
+<p> To avoid confusion in your logs, if you don't assign each
+secondary instance a non-empty (distinct) $multi_instance_name, you
+should make sure that the $syslog_name setting is different for
+each instance. The $syslog_name parameter defaults to $multi_instance_name
+when the latter is non-empty. If at all possible, the syslog_name
+should start with "postfix-", this helps log parsers to identify
+log entries from secondary Postfix instances. </p> </dd>
+
+<dt> multi_instance_group </dt>
+
+<dd> <p> Each Postfix instance may be assigned an "instance group"
+name (with "postfix -e create/import/assign -G <i>name</i>...").
+The default (empty) value of multi_instance_group parameter indicates
+a stand-alone instance that is not part of any group. The group
+name can be used with the postmulti(1) command-line utility to
+perform a task on the members of a group by name. Choose a single-word
+group name that concisely captures the role of the group. </p>
+</dd>
+
+<dt> multi_instance_enable </dt>
+
+<dd> <p> This parameter controls whether a Postfix instance will
+be started by a Postfix multi-instance manager. The default value
+is "no". The instance can be started explicitly with "postfix -c
+/path/to/config/directory"; this is useful for testing. </p>
+
+<p> When an instance is disabled, the postfix(1) "start" command
+is replaced by "check". </p>
+
+<p> Some postfix(1) commands (such as "stop", "flush", ...) require
+a running Postfix instance, and skip instances that are disabled.
+</p>
+
+<p> Other postfix(1) commands (such as "status", "set-permissions",
+"upgrade-configuration", ...) do not require a running Postfix
+system, and apply to all instances whether enabled or not. </p>
+</dd>
+
+</dl>
+
+<p> The postmulti(1) utility can be used to create (or destroy) instances.
+It can also be used to "import" or "deport" existing instances into or
+from the list of managed instances. When using postmulti(1) to manage
+instances, the above configuration parameters are managed for you
+automatically. See below. </p>
+
+<h2><a name="how"> Using the postmulti(1) command </a></h2>
+
+<ul>
+
+<li><a href="#init"> Initializing the multi-instance manager </a>
+
+<li><a href="#list"> Listing managed instances </a>
+
+<li><a href="#start"> Starting or stopping a multi-instance system </a>
+
+<li><a href="#adhoc"> Ad-hoc multi-instance operations </a>
+
+<li><a href="#create"> Creating a new Postfix instance </a>
+
+<li><a href="#destroy"> Destroying a Postfix instance </a>
+
+<li><a href="#import"> Importing an existing Postfix instance </a>
+
+<li><a href="#deport"> Deporting a managed Postfix instance </a>
+
+<li><a href="#assign"> Assigning a new name or group name </a>
+
+<li><a href="#enable"> Enabling/disabling managed instances </a>
+
+</ul>
+
+<h3><a name="init"> Initializing the multi-instance manager </a></h3>
+
+<p> Before postmulti(1) is used for the first time, you must install
+it as the multi_instance_wrapper for your Postfix system and enable
+multi-instance operation of the default Postfix instance. You can then
+proceed to add <a href="#create">new</a> or <a href="#import">existing</a>
+instances to the multi-instance configuration. This initial installation
+is accomplished as follows: </p>
+
+<blockquote>
+<pre>
+ # postmulti -e init
+</pre>
+</blockquote>
+
+<p> This updates the default instance main.cf file as follows: </p>
+
+<blockquote>
+<pre>
+ # Use postmulti(1) as a postfix-wrapper(5)
+ #
+ multi_instance_wrapper = ${command_directory}/postmulti -p --
+
+ # Configure the default instance to start when in multi-instance mode
+ #
+ multi_instance_enable = yes
+</pre>
+</blockquote>
+
+<p> If you prefer, you can make these changes by editing the default
+main.cf directly, or by using "postconf -e". </p>
+
+<h3><a name="list"> Listing managed instances </a></h3>
+
+<p> The list of managed instances consists of the default instance and
+the additional instances whose configuration directories are listed
+(in start order) under the multi_instance_directories parameter of the
+default main.cf configuration file. </p>
+
+<p> You can list selected instances, groups of instances or all
+instances by specifying only the instance matching options with the
+"-l" option. The "-a" option is assumed if no other instance
+selection options are specified (this behavior changes with the
+"-e" option). As a special case, even if it has an explicit name,
+the default instance can always be selected via "-i -". </p>
+
+<blockquote>
+<pre>
+# postmulti -l -a
+# postmulti -l -g a_group
+# postmulti -l -i an_instance
+</pre>
+</blockquote>
+
+<p> The output is one line per instance (in "postfix start" order):
+</p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th align="left">name</th> <th align="left">group</th> <th
+align="left">enabled</th> <th align="left">config_directory</th>
+</tr>
+
+<tr> <td>-</td> <td>-</td> <td>yes</td> <td>/etc/postfix
+
+<tr> <td>mta-out</td> <td>mta</td> <td>yes</td> <td>/etc/postfix/mta-out
+
+<tr> <td>mta-in</td> <td>mta</td> <td>yes</td> <td>/etc/postfix-mta-in
+
+<tr> <td>msa-out</td> <td>msa</td> <td>yes</td> <td>/etc/postfix-msa-out
+
+<tr> <td>msa-in</td> <td>msa</td> <td>yes</td> <td>/etc/postfix-msa-in
+
+<tr> <td>test</td> <td>-</td> <td>no</td> <td>/etc/postfix-test
+
+</table>
+
+</blockquote>
+
+<p> The first line showing the column headings is not part of the
+output. When either the instance name or the instance group is not
+set, it is shown as a "-". </p>
+
+<p> When selecting an existing instance via the "-i" option, you
+can always use the full pathname of its configuration directory
+instead of the instance (short) name. This is the only way to select
+a non-default nameless instance. The default instance can be selected
+via "-i -", whether it has a name or not. </p>
+
+<p> To list instances in reverse start order, include the "-R"
+option together with the instance selection options. </p>
+
+<h3><a name="start"> Starting or stopping a multi-instance system
+</a></h3>
+
+<p> To start, stop, reload, etc. the complete (already configured as
+above) multi-instance system just use postfix(1) as you would with a
+single-instance system. The Postfix multi-instance wrapper framework
+insulates Postfix init.d start and package upgrade scripts from the
+details of multi-instance management! </p>
+
+<p> The <b>-p</b> option of postmulti(1) turns on postfix(1) compatibility
+mode. With this option the remaining arguments are exactly those supported
+by postfix(1), but commands are applied to all instances or all enabled
+instances as appropriate. As described above, this switch is required
+when using postmulti(1) as the multi_instance_wrapper. </p>
+
+<p> If you want to specify a subset of instances by name, or group name,
+or run arbitrary commands (not just "postfix stop/start/etc. in the
+context (MAIL_CONFIG environment variable setting) of a particular
+instance or group of instances, then you can use the instance-aware
+postmulti(1) utility directly. </p>
+
+<h3><a name="adhoc"> Ad-hoc multi-instance operations </a></h3>
+
+<p> The postmulti(1) command can be used by the administrator to run arbitrary
+commands in the context of one or more Postfix instances. The most common
+use-case is stopping or starting a group of Postfix instances: </p>
+
+<blockquote>
+<pre>
+# postmulti -g mygroup -p start
+# postmulti -g mygroup -p flush
+# postmulti -g mygroup -p reload
+# postmulti -g mygroup -p status
+# postmulti -g mygroup -p stop
+# postmulti -g mygroup -p upgrade-configuration
+</pre>
+</blockquote>
+
+<p> The <b>-p</b> option is essentially a short-hand for a leading
+<b>postfix</b> command argument, but with appropriate additional options
+turned on depending on the first argument. In the case of "start",
+disabled instances are "checked" (postfix check) rather than simply
+skipped. </p>
+
+<p> The resulting command is executed for each candidate instance with
+the <b>MAIL_CONFIG</b> environment variable set to the configuration
+directory of the corresponding Postfix instance. </p>
+
+<p> The postmulti(1) utility is able to launch commands other than
+postfix(1), Use the <b>-x</b> option to ask postmulti to execute an
+ad-hoc command for all instances, a group of instances, or just one
+instance. With ad-hoc commands the multi_instance_enable parameter
+is ignored: the command is unconditionally executed for the instances
+selected via -a, -g or -i. In addition to MAIL_CONFIG, the following
+instance parameters are exported into the command environment: </p>
+
+<blockquote>
+<pre>
+command_directory=$command_directory
+daemon_directory=$daemon_directory
+config_directory=$config_directory
+queue_directory=$queue_directory
+data_directory=$data_directory
+multi_instance_name=$multi_instance_name
+multi_instance_group=$multi_instance_group
+multi_instance_enable=$multi_instance_enable
+</pre>
+</blockquote>
+
+<p> The config_directory setting is of course the same as MAIL_CONFIG,
+and is arguably redundant, but leaving it in is less surprising. If
+you want to skip disabled instances, just check multi_instance_enable
+environment variable and exit if it is set to "no". </p>
+
+<p> The ability to run ad-hoc commands opens up a wealth of additional
+possibilities: </p>
+
+<ul>
+
+<li><p> Specify an instance by name rather than configuration directory
+when using sendmail(1) to send a verification probe: </p>
+
+<blockquote>
+<pre>
+$ postmulti -i postfix-myinst -x sendmail -bv test@example.net
+</pre>
+</blockquote>
+
+<li><p> Display non-default main.cf settings of all Postfix instances.
+This uses an inline shell script to package together multiple shell
+commands to execute for each instance: </p>
+
+<blockquote>
+<pre>
+$ postmulti -x sh -c 'echo "-- $MAIL_CONFIG"; postconf -n'
+</pre>
+</blockquote>
+
+<li><p> Put all mail in enabled member instances of a group on hold: </p>
+
+<blockquote>
+<pre>
+# postmulti -g group_name -x \
+ sh -c 'test $multi_instance_enable = yes &amp;&amp; postsuper -h ALL'
+</pre>
+</blockquote>
+
+<li><p> Show top 10 domains in the deferred queue of all instances:
+</p>
+
+<blockquote>
+<pre>
+# postmulti -x sh -c 'echo "-- $MAIL_CONFIG"; qshape deferred | head -12'
+</pre>
+</blockquote>
+
+</ul>
+
+<h3><a name="create"> Creating a new Postfix instance </a></h3>
+
+<p> The postmulti(1) command can be used to create additional Postfix
+instances. New instances are created with local submission and all "inet"
+services disabled via the following non-default parameter settings in
+the main.cf file: </p>
+
+<blockquote>
+<pre>
+authorized_submit_users =
+master_service_disable = inet
+</pre>
+</blockquote>
+
+<p> The above settings ensure that new instances are safe to start
+immediately: they will not conflict with inet listeners in existing
+Postfix instances. They will also not accept any mail until they are
+fully configured, at which point you can do away with one or both of
+the above safety measures. </p>
+
+<p> The postmulti(1) command encourages a preferred way of organizing
+the configuration directories, queue directories and data directories
+of non-default instances. If the default instance settings are: </p>
+
+<blockquote>
+<pre>
+config_directory = /conf-path/postfix
+queue_directory = /queue-path/postfix
+data_directory = /data-path/postfix
+</pre>
+</blockquote>
+
+<p> A newly-created instance named <i>postfix-myinst</i> will by default
+have: </p>
+
+<blockquote>
+<pre>
+multi_instance_enable = no
+multi_instance_name = postfix-myinst
+config_directory = /conf-path/postfix-myinst
+queue_directory = /queue-path/postfix-myinst
+data_directory = /data-path/postfix-myinst
+</pre>
+</blockquote>
+
+<p> You can override any of these defaults when creating the instance,
+but unless you want to spread instance queue directories over multiple
+file-systems, use the default naming strategy. It keeps the multiple
+instances organized in a uniform, predictable fashion. </p>
+
+<p> When specifying the instance name later, you can refer to it
+either as "postfix-myinst", or via the full path of the configuration
+directory. </p>
+
+<p> To create a new instance just use the <b>-e create</b> option: </p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-myinst -e create
+</pre>
+</blockquote>
+
+<p> If the new instance is to belong to a group of related instances that
+implement a single logical service, assign it to a group: </p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-myinst -G mygroup -e create
+</pre>
+</blockquote>
+
+<p> If you want to override the conventional values of the instance
+installation parameters, specify their values on the command-line: </p>
+
+<blockquote>
+<pre>
+# postmulti [-I postfix-myinst] [-G mygroup] -e create \
+ "config_directory = /path/to/config_directory" \
+ "queue_directory = /path/to/queue_directory" \
+ "data_directory = /path/to/data_directory"
+</pre>
+</blockquote>
+
+<p> A note on the <b>-I</b> and <b>-G</b> options above. These are always
+used to assign a name or group name to an instance, while the <b>-i</b>
+and <b>-g</b> options always select existing instances. By default,
+the configuration directories of newly managed instances are appended
+to the instance list. You can use the "-i" or "-g" or "-a" options to
+insert the new instance before the specified instance or group, or at
+the beginning of the instance list (multi_instance_directories parameter
+of the default instance). </p>
+
+<p> If you do specify a name (use "-I" with a name that is not "-")
+for the new instance, you may omit any of the 3 instance installation
+parameters whose instance-name based value is acceptable. Otherwise, all
+three instance installation parameters are required. You should set the
+"syslog_name" explicitly in the main.cf file of a "nameless" instance,
+in order to avoid confusion in the mail logs when multiple instances
+are in use. </p>
+
+<h3><a name="destroy"> Destroying a Postfix instance </a></h3>
+
+<p> If you no longer need an instance, you can destroy it via: </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-myinst -p stop
+# postmulti -i postfix-myinst -e disable
+# postmulti -i postfix-myinst -e destroy
+</pre>
+</blockquote>
+
+<p> The instance must be stopped, disabled and have no queued messages.
+This is expected to fully delete a just created instance that has never
+been used. If the instance is not freshly created, files added after
+the instance was created will remain in the configuration, queue or
+data directories, in which case the corresponding directory may not
+be fully removed and a warning to that effect will be displayed. You
+can complete the destruction of the instance manually by removing any
+unwanted remnants of the instance-specific "private" directories. </p>
+
+<h3><a name="import"> Importing an existing Postfix instance </a></h3>
+
+<p> If you already have an existing secondary Postfix instance that is
+not yet managed via postmulti(1), you can "import" it into the list
+of managed instances. If your instance is already using the default
+configuration directory naming scheme, just specify the corresponding
+instance name (the multi_instance_name parameter in its configuration
+file will be adjusted to match this name if necessary): </p>
+
+<blockquote>
+<pre>
+# postmulti -I postfix-myinst [-G mygroup] -e import
+</pre>
+</blockquote>
+
+<p> Otherwise, you must specify the location of its configuration
+directory: </p>
+
+<blockquote>
+<pre>
+# postmulti [-I postfix-myinst] [-G mygroup] -e import \
+ "config_directory = /path/of/config_directory"
+</pre>
+</blockquote>
+
+<p> When the instance is imported, you can assign a name or a group. As
+with <a href="#create">"create"</a>, you can control the placement of the
+new instance in the start order by using "-i", "-g" or "-a" to prepend
+before the selected instance or instances. </p>
+
+<p> An imported instance is usually not multi-instance "enabled",
+unless it was part of a multi-instance configuration at an earlier
+time. If it is fully configured and ready to run, don't forget
+to <a href="#enable">enable</a> it and if necessary start it. When
+other enabled instances are already running, new instances need to
+be started individually when they are first created or imported.
+</p>
+
+<p> To find out what instances are running, use: </p>
+
+<blockquote>
+<pre>
+# postfix status
+</pre>
+</blockquote>
+
+<h3><a name="deport"> Deporting a managed Postfix instance </a></h3>
+
+<p> You can "deport" an existing instance from the list of managed
+instances. This does not destroy the instance, rather the instance
+just becomes a stand-alone Postfix instance not registered with the
+multi-instance manager. postmulti(1) will refuse to "deport" an
+instance that is not stopped and disabled. </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-myinst -p stop
+# postmulti -i postfix-myinst -e disable
+# postmulti -i postfix-myinst -e deport
+</pre>
+</blockquote>
+
+<h3><a name="assign"> Assigning a new name or group name </a></h3>
+
+<p> You can assign a new name or new group to a managed instance.
+Use "-" as the new value to assign the instance to no group or make it
+nameless. To specify a nameless secondary instance use the configuration
+directory path instead of the old name: </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-old [-I postfix-new] [-G newgroup] -e assign
+</pre>
+</blockquote>
+
+<h3><a name="enable"> Enabling/disabling managed instances </a></h3>
+
+<p> You can enable or disable a managed instance. As documented in
+postfix-wrapper(5), disabled instances are skipped with actions
+that <a href="postconf.5.html#postmulti_start_commands">start</a>,
+<a href="postconf.5.html#postmulti_start_commands">stop</a> or <a
+href="postconf.5.html#postmulti_control_commands">control</a> running
+Postfix instances. </p>
+
+<blockquote>
+<pre>
+# postmulti -i postfix-myinst -e enable
+# postmulti -i postfix-myinst -e disable
+</pre>
+</blockquote>
+
+<h2><a name="credits"> Credits </a></h2>
+
+<p> Wietse Venema created Postfix, designed and implemented the
+multi-instance wrapper framework and provided design feedback that made
+the postmulti(1) utility much more general and useful than originally
+envisioned. </p>
+
+<p> The postmulti(1) utility was developed by Victor Duchovni of Morgan
+Stanley, who also wrote the initial version of this document. </p>
+
+</body> </html>
diff --git a/proto/MYSQL_README.html b/proto/MYSQL_README.html
new file mode 100644
index 0000000..db52f02
--- /dev/null
+++ b/proto/MYSQL_README.html
@@ -0,0 +1,186 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix MySQL Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix MySQL Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> The Postfix mysql map type allows you to hook up Postfix to a
+MySQL database. This implementation allows for multiple mysql
+databases: you can use one for a virtual(5) table, one for an
+access(5) table, and one for an aliases(5) table if you want. You
+can specify multiple servers for the same database, so that Postfix
+can switch to a good database server if one goes bad. </p>
+
+<p> Busy mail servers using mysql maps will generate lots of
+concurrent mysql clients, so the mysql server(s) should be run with
+this fact in mind. You can reduce the number of concurrent mysql
+clients by using the Postfix proxymap(8) service. </p>
+
+<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>
+
+<p> The Postfix MySQL client utilizes the mysql client library,
+which can be obtained from: </p>
+
+<blockquote>
+ <p> http://www.mysql.com/downloads/ </p>
+</blockquote>
+
+<p> In order to build Postfix with mysql map support, you will need to add
+-DHAS_MYSQL and -I for the directory containing the mysql headers, and
+the mysqlclient library (and libm) to AUXLIBS_MYSQL, for example: </p>
+
+<blockquote>
+<pre>
+make -f Makefile.init makefiles \
+ 'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include' \
+ 'AUXLIBS_MYSQL=-L/usr/local/mysql/lib -lmysqlclient -lz -lm'
+</pre>
+</blockquote>
+
+<p> If your MySQL shared library is in a directory that the RUN-TIME
+linker does not know about, add a "-Wl,-R,/path/to/directory" option after
+"-lmysqlclient". </p>
+
+<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_MYSQL.
+With Postfix 3.0 and later, the old AUXLIBS variable still supports
+building a statically-loaded MySQL database client, but only the new
+AUXLIBS_MYSQL variable supports building a dynamically-loaded or
+statically-loaded MySQL database client. </p>
+
+<blockquote>
+
+<p> Failure to use the AUXLIBS_MYSQL variable will defeat the purpose
+of dynamic database client loading. Every Postfix executable file
+will have MYSQL database library dependencies. And that was exactly
+what dynamic database client loading was meant to avoid. </p>
+
+</blockquote>
+
+<p> On Solaris, use this instead: </p>
+
+<blockquote>
+<pre>
+make -f Makefile.init makefiles \
+ 'CCARGS=-DHAS_MYSQL -I/usr/local/mysql/include' \
+ 'AUXLIBS_MYSQL=-L/usr/local/mysql/lib -R/usr/local/mysql/lib \
+ -lmysqlclient -lz -lm'
+</pre>
+</blockquote>
+
+<p> Then, just run 'make'. This requires libz, the compression
+library. Older mysql implementations build without libz. </p>
+
+<h2>Using MySQL tables</h2>
+
+<p> Once Postfix is built with mysql support, you can specify a
+map type in main.cf like this: </p>
+
+<blockquote>
+<pre>
+alias_maps = mysql:/etc/postfix/mysql-aliases.cf
+</pre>
+</blockquote>
+
+<p> The file /etc/postfix/mysql-aliases.cf specifies lots of
+information telling Postfix how to reference the mysql database.
+For a complete description, see the mysql_table(5) manual page. </p>
+
+<h2>Example: local aliases </h2>
+
+<pre>
+#
+# mysql config file for local(8) aliases(5) lookups
+#
+
+# The user name and password to log into the mysql server.
+user = someone
+password = some_password
+
+# The database name on the servers.
+dbname = customer_database
+
+# For Postfix 2.2 and later The SQL query template.
+# See mysql_table(5) for details.
+query = SELECT forw_addr FROM mxaliases WHERE alias='%s' AND status='paid'
+
+# For Postfix releases prior to 2.2. See mysql_table(5) for details.
+select_field = forw_addr
+table = mxaliases
+where_field = alias
+# Don't forget the leading "AND"!
+additional_conditions = AND status = 'paid'
+
+# This is necessary to make UTF8 queries work for Postfix 2.11 .. 3.1,
+# and is the default setting as of Postfix 3.2.
+option_group = client
+</pre>
+
+<h2>Additional notes</h2>
+
+<p> Postfix 3.2 and later read <b>[client]</b> option group settings
+by default. To disable this, specify no <b>option_file</b> and
+specify "<b>option_group =</b>" (i.e. an empty value). </p>
+
+<p> Postfix 3.1 and earlier don't read <b>[client]</b> option group
+settings unless a non-empty <b>option_file</b> or <b>option_group</b>
+value are specified. To enable this, specify, for example
+"<b>option_group = client</b>". </p>
+
+<p> The MySQL configuration interface setup allows for multiple
+mysql databases: you can use one for a virtual table, one for an
+access table, and one for an aliases table if you want. </p>
+
+<p> Since sites that have a need for multiple mail exchangers may
+enjoy the convenience of using a networked mailer database, but do
+not want to introduce a single point of failure to their system,
+we've included the ability to have Postfix reference multiple hosts
+for access to a single mysql map. This will work if sites set up
+mirrored mysql databases on two or more hosts. Whenever queries
+fail with an error at one host, the rest of the hosts will be tried
+in random order. If no mysql server hosts are reachable, then mail
+will be deferred until at least one of those hosts is reachable.
+</p>
+
+<h2>Credits</h2>
+
+<ul>
+
+<li> The initial version was contributed by Scott Cotton and Joshua
+Marcus, IC Group, Inc.</li>
+
+<li> Liviu Daia revised the configuration interface and added the
+main.cf configuration feature.</li>
+
+<li> Liviu Daia with further refinements from Jose Luis Tallon and
+Victor Duchovni developed the common query, result_format, domain and
+expansion_limit interface for LDAP, MySQL and PostgreSQL.</li>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/Makefile.in b/proto/Makefile.in
new file mode 100644
index 0000000..511bd44
--- /dev/null
+++ b/proto/Makefile.in
@@ -0,0 +1,535 @@
+SHELL = /bin/sh
+
+# For now, just hard-coded rules.
+
+CONFIG = ../conf/access ../conf/aliases ../conf/canonical ../conf/relocated \
+ ../conf/transport ../conf/virtual ../conf/header_checks \
+ ../conf/generic
+
+HTML = ../html/ADDRESS_CLASS_README.html \
+ ../html/ADDRESS_REWRITING_README.html \
+ ../html/ADDRESS_VERIFICATION_README.html \
+ ../html/BACKSCATTER_README.html \
+ ../html/BASIC_CONFIGURATION_README.html \
+ ../html/BDAT_README.html \
+ ../html/BUILTIN_FILTER_README.html \
+ ../html/CDB_README.html \
+ ../html/COMPATIBILITY_README.html \
+ ../html/CONNECTION_CACHE_README.html \
+ ../html/CONTENT_INSPECTION_README.html \
+ ../html/DATABASE_README.html ../html/DB_README.html \
+ ../html/DEBUG_README.html \
+ ../html/DSN_README.html \
+ ../html/ETRN_README.html ../html/FILTER_README.html \
+ ../html/FORWARD_SECRECY_README.html \
+ ../html/INSTALL.html ../html/IPV6_README.html \
+ ../html/LDAP_README.html \
+ ../html/LINUX_README.html \
+ ../html/LOCAL_RECIPIENT_README.html ../html/MAILDROP_README.html \
+ ../html/MAILLOG_README.html \
+ ../html/LMDB_README.html \
+ ../html/MEMCACHE_README.html \
+ ../html/MILTER_README.html \
+ ../html/MULTI_INSTANCE_README.html \
+ ../html/MYSQL_README.html ../html/NFS_README.html \
+ ../html/OVERVIEW.html \
+ ../html/PACKAGE_README.html ../html/PCRE_README.html \
+ ../html/PGSQL_README.html \
+ ../html/POSTSCREEN_3_5_README.html \
+ ../html/POSTSCREEN_README.html \
+ ../html/QSHAPE_README.html \
+ ../html/RESTRICTION_CLASS_README.html ../html/SASL_README.html \
+ ../html/SCHEDULER_README.html ../html/SMTPD_ACCESS_README.html \
+ ../html/SMTPD_POLICY_README.html \
+ ../html/SMTPD_PROXY_README.html \
+ ../html/SMTPUTF8_README.html \
+ ../html/SOHO_README.html \
+ ../html/SQLITE_README.html \
+ ../html/STANDARD_CONFIGURATION_README.html \
+ ../html/STRESS_README.html \
+ ../html/TLS_README.html ../html/TLS_LEGACY_README.html \
+ ../html/TUNING_README.html \
+ ../html/UUCP_README.html \
+ ../html/VERP_README.html ../html/VIRTUAL_README.html \
+ ../html/XCLIENT_README.html ../html/XFORWARD_README.html \
+ ../html/postconf.5.html
+
+README = ../README_FILES/ADDRESS_CLASS_README \
+ ../README_FILES/ADDRESS_REWRITING_README \
+ ../README_FILES/ADDRESS_VERIFICATION_README \
+ ../README_FILES/BACKSCATTER_README \
+ ../README_FILES/BASIC_CONFIGURATION_README \
+ ../README_FILES/BDAT_README \
+ ../README_FILES/BUILTIN_FILTER_README \
+ ../README_FILES/CDB_README \
+ ../README_FILES/COMPATIBILITY_README \
+ ../README_FILES/CONNECTION_CACHE_README \
+ ../README_FILES/CONTENT_INSPECTION_README \
+ ../README_FILES/DATABASE_README ../README_FILES/DB_README \
+ ../README_FILES/DEBUG_README \
+ ../README_FILES/DSN_README \
+ ../README_FILES/ETRN_README ../README_FILES/FILTER_README \
+ ../README_FILES/FORWARD_SECRECY_README \
+ ../README_FILES/INSTALL ../README_FILES/IPV6_README \
+ ../README_FILES/LDAP_README \
+ ../README_FILES/LINUX_README \
+ ../README_FILES/LOCAL_RECIPIENT_README ../README_FILES/MAILDROP_README \
+ ../README_FILES/MAILLOG_README \
+ ../README_FILES/LMDB_README \
+ ../README_FILES/MEMCACHE_README \
+ ../README_FILES/MILTER_README \
+ ../README_FILES/MULTI_INSTANCE_README \
+ ../README_FILES/MYSQL_README ../README_FILES/NFS_README \
+ ../README_FILES/OVERVIEW \
+ ../README_FILES/PACKAGE_README ../README_FILES/PCRE_README \
+ ../README_FILES/PGSQL_README \
+ ../README_FILES/POSTSCREEN_3_5_README \
+ ../README_FILES/POSTSCREEN_README \
+ ../README_FILES/QSHAPE_README \
+ ../README_FILES/RESTRICTION_CLASS_README \
+ ../README_FILES/SASL_README ../README_FILES/SCHEDULER_README \
+ ../README_FILES/SMTPD_ACCESS_README \
+ ../README_FILES/SMTPD_POLICY_README ../README_FILES/SMTPD_PROXY_README \
+ ../README_FILES/SMTPUTF8_README \
+ ../README_FILES/SOHO_README \
+ ../README_FILES/SQLITE_README \
+ ../README_FILES/STANDARD_CONFIGURATION_README \
+ ../README_FILES/STRESS_README \
+ ../README_FILES/TLS_README ../README_FILES/TLS_LEGACY_README \
+ ../README_FILES/TUNING_README \
+ ../README_FILES/UUCP_README \
+ ../README_FILES/VERP_README ../README_FILES/VIRTUAL_README \
+ ../README_FILES/XCLIENT_README ../README_FILES/XFORWARD_README \
+ ../README_FILES/AAAREADME
+
+MAN = ../man/man5/postconf.5
+
+TOP = ../INSTALL
+
+AWK = awk '{ print; if (NR == 1) print ".pl 9999\n.ll 65" }'
+SRCTOMAN= ../mantools/srctoman
+POSTLINK= ../mantools/postlink
+DETAB = pr -tre
+NROFF = LANG=C GROFF_NO_SGR=1 nroff
+HT2READ = ../mantools/html2readme
+MAKEAAA = ../mantools/makereadme
+MAKESOHO= ../mantools/make_soho_readme
+DEPSOHO = SASL_README.html STANDARD_CONFIGURATION_README.html
+
+update: $(CONFIG) $(HTML) $(README) $(MAN) $(TOP)
+
+clean:
+ :
+
+tidy: clean
+
+clobber:
+ rm -f $(CONFIG) $(README) $(HTML)
+
+#$(README): $(HT2READ)
+#$(HTML): $(POSTLINK)
+
+../conf/access: access
+ $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@
+
+../conf/aliases: aliases0 aliases
+ (cat aliases0; $(SRCTOMAN) - aliases | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /') >$@
+
+../conf/canonical: canonical
+ $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@
+
+../conf/generic: generic
+ $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@
+
+../conf/header_checks: header_checks
+ $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@
+
+../conf/relocated: relocated
+ $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@
+
+../conf/transport: transport
+ $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@
+
+../conf/virtual: virtual
+ $(SRCTOMAN) - $? | $(AWK) | $(NROFF) -man | col -bx | uniq | sed 's/^/# /' >$@
+
+../html/ADDRESS_CLASS_README.html: ADDRESS_CLASS_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/ADDRESS_REWRITING_README.html: ADDRESS_REWRITING_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/ADDRESS_VERIFICATION_README.html: ADDRESS_VERIFICATION_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/BACKSCATTER_README.html: BACKSCATTER_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/CDB_README.html: CDB_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/COMPATIBILITY_README.html: COMPATIBILITY_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/CONNECTION_CACHE_README.html: CONNECTION_CACHE_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/CONTENT_INSPECTION_README.html: CONTENT_INSPECTION_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/CYRUS_README.html: CYRUS_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/BASIC_CONFIGURATION_README.html: BASIC_CONFIGURATION_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/BDAT_README.html: BDAT_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/BUILTIN_FILTER_README.html: BUILTIN_FILTER_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/DATABASE_README.html: DATABASE_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/DB_README.html: DB_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/DEBUG_README.html: DEBUG_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/DSN_README.html: DSN_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/ETRN_README.html: ETRN_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/FILTER_README.html: FILTER_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/FORWARD_SECRECY_README.html: FORWARD_SECRECY_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/INSTALL.html: INSTALL.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/IPV6_README.html: IPV6_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/LDAP_README.html: LDAP_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/LINUX_README.html: LINUX_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/LOCAL_RECIPIENT_README.html: LOCAL_RECIPIENT_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/MAILDROP_README.html: MAILDROP_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/MAILLOG_README.html: MAILLOG_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/LMDB_README.html: LMDB_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/MEMCACHE_README.html: MEMCACHE_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/MILTER_README.html: MILTER_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/MULTI_INSTANCE_README.html: MULTI_INSTANCE_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/MYSQL_README.html: MYSQL_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/NFS_README.html: NFS_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/OVERVIEW.html: OVERVIEW.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/PACKAGE_README.html: PACKAGE_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/PCRE_README.html: PCRE_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/PGSQL_README.html: PGSQL_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/POSTSCREEN_3_5_README.html: POSTSCREEN_3_5_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/POSTSCREEN_README.html: POSTSCREEN_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/QMQP_README.html: QMQP_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/QSHAPE_README.html: QSHAPE_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/RESTRICTION_CLASS_README.html: RESTRICTION_CLASS_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/SASL_README.html: SASL_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/SCHEDULER_README.html: SCHEDULER_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/SMTPD_ACCESS_README.html: SMTPD_ACCESS_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/SMTPD_POLICY_README.html: SMTPD_POLICY_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/SMTPD_PROXY_README.html: SMTPD_PROXY_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/SMTPUTF8_README.html: SMTPUTF8_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/SOHO_README.html: $(MAKESOHO) $(DEPSOHO)
+ $(MAKESOHO) | $(POSTLINK) | $(DETAB) >$@
+
+../html/SQLITE_README.html: SQLITE_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/STANDARD_CONFIGURATION_README.html: STANDARD_CONFIGURATION_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/STRESS_README.html: STRESS_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/TUNING_README.html: TUNING_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/UUCP_README.html: UUCP_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/ULTRIX_README.html: ULTRIX_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/VERP_README.html: VERP_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/VIRTUAL_README.html: VIRTUAL_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/XCLIENT_README.html: XCLIENT_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/XFORWARD_README.html: XFORWARD_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/TLS_README.html: TLS_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../html/TLS_LEGACY_README.html: TLS_LEGACY_README.html
+ $(DETAB) $? | $(POSTLINK) >$@
+
+../README_FILES/ADDRESS_CLASS_README: ADDRESS_CLASS_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/ADDRESS_REWRITING_README: ADDRESS_REWRITING_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/ADDRESS_VERIFICATION_README: ADDRESS_VERIFICATION_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/BACKSCATTER_README: BACKSCATTER_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/BASIC_CONFIGURATION_README: BASIC_CONFIGURATION_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/BDAT_README: BDAT_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/BUILTIN_FILTER_README: BUILTIN_FILTER_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/CDB_README: CDB_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/COMPATIBILITY_README: COMPATIBILITY_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/CONNECTION_CACHE_README: CONNECTION_CACHE_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/CONTENT_INSPECTION_README: CONTENT_INSPECTION_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/CYRUS_README: CYRUS_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/DATABASE_README: DATABASE_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/DB_README: DB_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/DEBUG_README: DEBUG_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/DSN_README: DSN_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/ETRN_README: ETRN_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/FILTER_README: FILTER_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/FORWARD_SECRECY_README: FORWARD_SECRECY_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/INSTALL: INSTALL.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/IPV6_README: IPV6_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/LDAP_README: LDAP_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/LINUX_README: LINUX_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/LOCAL_RECIPIENT_README: LOCAL_RECIPIENT_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/MAILDROP_README: MAILDROP_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/MAILLOG_README: MAILLOG_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/LMDB_README: LMDB_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/MEMCACHE_README: MEMCACHE_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/MILTER_README: MILTER_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/MULTI_INSTANCE_README: MULTI_INSTANCE_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/MYSQL_README: MYSQL_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/NFS_README: NFS_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/OVERVIEW: OVERVIEW.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/PACKAGE_README: PACKAGE_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/PCRE_README: PCRE_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/PGSQL_README: PGSQL_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/POSTSCREEN_3_5_README: POSTSCREEN_3_5_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/POSTSCREEN_README: POSTSCREEN_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/QMQP_README: QMQP_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/QSHAPE_README: QSHAPE_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/RESTRICTION_CLASS_README: RESTRICTION_CLASS_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/SASL_README: SASL_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/SCHEDULER_README: SCHEDULER_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/SMTPD_ACCESS_README: SMTPD_ACCESS_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/SMTPD_POLICY_README: SMTPD_POLICY_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/SMTPD_PROXY_README: SMTPD_PROXY_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/SMTPUTF8_README: SMTPUTF8_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/SOHO_README: $(MAKESOHO) $(DEPSOHO)
+ $(MAKESOHO) | $(HT2READ) | $(DETAB) >$@
+
+../README_FILES/SQLITE_README: SQLITE_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/STANDARD_CONFIGURATION_README: STANDARD_CONFIGURATION_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/STRESS_README: STRESS_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/TUNING_README: TUNING_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/UUCP_README: UUCP_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/ULTRIX_README: ULTRIX_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/VERP_README: VERP_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/VIRTUAL_README: VIRTUAL_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/XCLIENT_README: XCLIENT_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/XFORWARD_README: XFORWARD_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/TLS_README: TLS_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/TLS_LEGACY_README: TLS_LEGACY_README.html
+ $(DETAB) $? | $(HT2READ) >$@
+
+../README_FILES/AAAREADME: ../html/index.html $(MAKEAAA)
+ $(MAKEAAA) ../html/index.html | $(HT2READ) | $(DETAB) >$@
+
+../man/man5/postconf.5: postconf.man.prolog postconf.proto postconf.man.epilog \
+ ../mantools/xpostconf ../mantools/postconf2html ../mantools/postconf2man
+ (cat postconf.man.prolog; ../mantools/xpostconf postconf.proto | \
+ $(DETAB) | ../mantools/postconf2html -n | \
+ ../mantools/postconf2man | \
+ sed 's/\\e&/\\\&/'; cat postconf.man.epilog ) > $@
+
+../html/postconf.5.html: postconf.html.prolog postconf.proto \
+ postconf.html.epilog ../mantools/xpostconf ../mantools/postconf2html \
+ ../mantools/postlink
+ (cat postconf.html.prolog; ../mantools/xpostconf postconf.proto | \
+ ../mantools/postconf2html | ../mantools/postlink; \
+ cat postconf.html.epilog ) | $(DETAB) > $@
+
+../INSTALL: ../README_FILES/INSTALL
+ rm -f $@
+ col -b < $? > $@
diff --git a/proto/NFS_README.html b/proto/NFS_README.html
new file mode 100644
index 0000000..0f970ee
--- /dev/null
+++ b/proto/NFS_README.html
@@ -0,0 +1,137 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix and NFS</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix and NFS</h1>
+
+<hr>
+
+<h2> Postfix support status for NFS </h2>
+
+<p> What is the status of support for Postfix on NFS? The answer
+is that Postfix itself is supported when you use NFS, but there is
+no promise that an NFS-related problem will promptly receive a
+Postfix workaround, or that a workaround will even be possible.
+</p>
+
+<p> That said, Postfix will in many cases work very well on NFS,
+because Postfix implements a number of workarounds (see below).
+Good NFS implementations seldom if ever give problems with Postfix,
+so Wietse recommends that you spend your money wisely. </p>
+
+<h2> Postfix file locking and NFS </h2>
+
+<p> For the Postfix mail queue, it does not matter how well NFS
+file locking works. The reason is that you cannot share Postfix
+queues among multiple running Postfix instances. You can use NFS
+to switch a Postfix mail queue from one NFS client to another one,
+but only one NFS client can access a Postfix mail queue at any
+particular point in time. </p>
+
+<p> For mailbox file sharing with NFS, your options are to use
+<b>fcntl</b> (kernel locks), <b>dotlock</b> (<i>username</i>.lock
+files), to use both locking methods simultaneously, or to switch
+to maildir format. The maildir format uses one file per message and
+needs no file locking support in Postfix or in other mail software.
+</p>
+
+<p> Many sites that use mailbox format play safe and use both locking
+methods simultaneously. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ virtual_mailbox_lock = fcntl, dotlock
+ mailbox_delivery_lock = fcntl, dotlock
+</pre>
+</blockquote>
+
+<h2> Postfix NFS workarounds </h2>
+
+<p> The list below summarizes the workarounds that exist for running
+Postfix on NFS as of the middle of 2003. As a reminder, Postfix
+itself is still supported when it runs on NFS, but there is no
+promise that an NFS-related problem will promptly receive a Postfix
+workaround, or that a workaround will even be possible. </p>
+
+<ul>
+
+<li> <p> Problem: when renaming a file, the operation may succeed
+but report an error anyway<sup>[1]</sup>. </p>
+
+<p> Workaround: when rename(old, new) reports an error, Postfix
+checks if the new name exists and the old name is gone. If the check
+succeeds, Postfix assumes that the rename() operation completed
+normally. </p>
+
+<li> <p> Problem: when creating a directory, the operation may succeed
+but report an error anyway<sup>[1]</sup>. </p>
+
+<p> Workaround: when mkdir(new) reports an EEXIST error, Postfix
+checks if the new name resolves to a directory. If the check succeeds,
+Postfix assumes that the mkdir() operation completed normally. </p>
+
+<li> <p> Problem: when creating a hardlink to a file, the operation
+may succeed but report an error anyway<sup>[1]</sup>. </p>
+
+<p> Workaround: when link(old, new) fails, Postfix compares the
+device and inode number of the old and new files. When the two files
+are identical, Postfix assumes that the link() operation completed
+normally. </p>
+
+<li> <p> Problem: when creating a dotlock (<i>username</i>.lock)
+file, the operation may succeed but report an error anyway<sup>[1]</sup>.
+</p>
+
+<p> Workaround: in this case, the only safe action is to back off
+and try again later. </p>
+
+<li> <p> Problem: when a file server's "time of day" clock is not
+synchronized with the client's "time of day" clock, email deliveries
+are delayed by a minute or more. </p>
+
+<p> Workaround: Postfix explicitly sets file time stamps to avoid
+delays with new mail (Postfix uses "last modified" file time stamps
+to decide when a queue file is ready for delivery). </p>
+
+</ul>
+
+<p> <sup>[1]</sup> How can an operation succeed and report an error
+anyway? </p>
+
+<p> Suppose that an NFS server executes a client request successfully,
+and that the server's reply to the client is lost. After some time
+the client retransmits the request to the server. Normally, the
+server remembers that it already completed the request (it keeps a
+list of recently-completed requests and replies), and simply
+retransmits the reply. </p>
+
+<p> However, when the server has rebooted or when it has been very
+busy, the server no longer remembers that it already completed the
+request, and repeats the operation. This causes no problems with
+file read/write requests (they contain a file offset and can therefore
+be repeated safely), but fails with non-idempotent operations. For
+example, when the server executes a retransmitted rename() request,
+the server reports an ENOENT error because the old name does not
+exist; and when the server executes a retransmitted link(), mkdir()
+or create() request, the server reports an EEXIST error because the
+name already exists. </p>
+
+<p> Thus, successful, non-idempotent, NFS operations will report
+false errors when the server reply is lost, the client retransmits
+the request, and the server does not remember that it already
+completed the request. </p>
+
+</body>
+</html>
diff --git a/proto/OVERVIEW.html b/proto/OVERVIEW.html
new file mode 100644
index 0000000..af743aa
--- /dev/null
+++ b/proto/OVERVIEW.html
@@ -0,0 +1,936 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Architecture Overview </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1> <img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Architecture Overview </h1>
+
+<hr>
+
+<h2> Introduction </h2>
+
+<p> This document presents an overview of the Postfix architecture,
+and provides pointers to descriptions of every Postfix command
+or server program. The text gives the general context in which
+each command or server program is used, and provides pointers to
+documents with specific usage examples and background information.
+</p>
+
+<p> Topics covered by this document: </p>
+
+<ul>
+
+<li> <a href="#receiving"> How Postfix receives mail </a>
+
+<li> <a href="#delivering"> How Postfix delivers mail </a>
+
+<li> <a href="#behind"> Postfix behind the scenes </a>
+
+<li> <a href="#commands"> Postfix support commands </a>
+
+</ul>
+
+<h2><a name="receiving"> How Postfix receives mail </a> </h2>
+
+<p> When a message enters the Postfix mail system, the first stop
+on the inside is the incoming queue. The figure below shows the
+main processes that are involved with new mail. Names followed by
+a number are Postfix commands or server programs, while unnumbered
+names inside shaded areas represent Postfix queues. </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+<td colspan="4"> </td>
+
+<td bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8) </td>
+
+</tr>
+
+<tr>
+
+<td> Network </td> <td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> smtpd(8)
+</td>
+
+<td> </td>
+
+<td rowspan="2" align="center"> <table> <tr> <td align="center">
+^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt>
+</td> </tr> </table> </td>
+
+</tr>
+
+<tr>
+
+<td colspan="3"> </td> <td> <tt> \ </tt> </td>
+
+</tr>
+
+<tr>
+
+<td> Network </td> <td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> qmqpd(8)
+</td>
+
+<td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> cleanup(8)
+</td>
+
+<td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> <a
+href="QSHAPE_README.html#incoming_queue"> incoming </a> </td>
+
+</tr>
+
+<tr>
+
+<td colspan="3"> </td> <td> <tt> / </tt> </td>
+
+</tr>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> pickup(8)
+</td>
+
+<td> <tt> &lt;- </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> <a
+href="QSHAPE_README.html#maildrop_queue"> maildrop </a> </td>
+
+</tr>
+
+<tr>
+
+<td colspan="4" align="center"> </td>
+
+<td align="center"> ^<br> <tt> | </tt> </td>
+
+</tr>
+
+<tr>
+
+<td> Local </td> <td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> sendmail(1)
+</td>
+
+<td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center" valign="middle"> postdrop(1)
+</td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<ul>
+
+<li> <p> Network mail enters Postfix via the smtpd(8) or qmqpd(8)
+servers. These servers remove the SMTP or QMQP protocol encapsulation,
+enforce some sanity checks to protect Postfix, and give the sender,
+recipients and message content to the cleanup(8) server. The
+smtpd(8) server can be configured to block unwanted mail, as
+described in the SMTPD_ACCESS_README document. </p>
+
+<li> <p> Local submissions are received with the Postfix sendmail(1)
+compatibility command, and are queued in the maildrop queue by
+the privileged postdrop(1) command. This arrangement even works
+while the Postfix mail system is not running. The local pickup(8)
+server picks up local submissions, enforces some sanity checks to
+protect Postfix, and gives the sender, recipients and message
+content to the cleanup(8) server. </p>
+
+<li> <p> Mail from internal sources is given directly to the
+cleanup(8) server. These sources are not shown in the figure, and
+include: mail that is forwarded by the local(8) delivery agent (see
+next section), messages that are returned to the sender by the
+bounce(8) server (see second-next section), and postmaster
+notifications about problems with Postfix. </p>
+
+<li> <p> The cleanup(8) server implements the final processing
+stage before mail is queued. It adds missing From: and other message
+headers, and transforms addresses as described in the
+ADDRESS_REWRITING_README
+document. Optionally, the cleanup(8) server can be configured to
+do light-weight content inspection with regular expressions as
+described in the BUILTIN_FILTER_README document. The cleanup(8)
+server places the result as a single file into the incoming queue,
+and notifies the queue manager (see next section) of the arrival
+of new mail. </p>
+
+<li> <p> The trivial-rewrite(8) server rewrites addresses to the
+standard "user@fully.qualified.domain" form, as described in the
+ADDRESS_REWRITING_README document. Postfix currently does not
+implement a rewriting language, but a lot can be done via table
+lookups and, if need be, regular expressions. </p>
+
+</ul>
+
+<h2> <a name="delivering"> How Postfix delivers mail </a> </h2>
+
+<p> Once a message has reached the incoming queue the next step is
+to deliver it. The figure shows the main components of the Postfix
+mail delivery apparatus. Names followed by a number are Postfix
+commands or server programs, while unnumbered names inside shaded
+areas represent Postfix queues. </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+<td rowspan="2" colspan="4"> </td>
+
+<td rowspan="2" bgcolor="#f0f0ff" align="center"> trivial-<br>rewrite(8)
+</td>
+
+<td> </td>
+
+<td bgcolor="#f0f0ff" align="center"> smtp(8) </td>
+
+<td> <tt> -&gt; </tt> </td> <td> Network </td>
+
+</tr>
+
+<tr>
+
+<td align="right"> <tt> / </tt> </td>
+
+</tr>
+
+<tr>
+
+<td rowspan="2" colspan="4"> </td>
+
+<td rowspan="2" align="center"> <table> <tr> <td align="center">
+^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt>
+</td> </tr> </table> </td>
+
+<td align="right"> <tt> - </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center"> lmtp(8) </td>
+
+<td> <tt> -&gt; </tt> </td> <td> Network </td>
+
+</tr>
+
+<tr>
+
+<td align="left"> <tt> / </tt> </td>
+
+</tr>
+
+<tr>
+
+<td bgcolor="#f0f0ff" align="center"> <a
+href="QSHAPE_README.html#incoming_queue"> incoming </a> </td>
+
+<td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center"> <a
+href="QSHAPE_README.html#active_queue"> active </a> </td>
+
+<td> <tt> -&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center"> qmgr(8) </td>
+
+<td align="right"> <tt> --- </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center"> local(8) </td>
+
+<td> <tt> -&gt; </tt> </td> <td> File, command </td>
+
+</tr>
+
+<tr>
+
+<td rowspan="2" colspan="2"> </td>
+
+<td rowspan="2" align="center"> <table> <tr> <td align="center">
+^<br> <tt> | </tt> </td> <td align="center"> <tt> |<br> v </tt>
+</td> </tr> </table> </td>
+
+<td rowspan="2" colspan="2"> </td>
+
+<td align="left"> <tt> \ </tt> </td>
+
+</tr>
+
+<tr>
+
+<td align="right"> <tt> - </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center"> virtual(8) </td>
+
+<td> <tt> -&gt; </tt> </td> <td> File </td>
+
+</tr>
+
+<tr>
+
+<td colspan="2"> </td>
+
+<td bgcolor="#f0f0ff" align="center"> <a
+href="QSHAPE_README.html#deferred_queue"> deferred </a> </td>
+
+<td colspan="2"> </td>
+
+<td align="right"> <tt> \ </tt> </td>
+
+</tr>
+
+<tr>
+
+<td colspan="6">
+
+<td bgcolor="#f0f0ff" align="center"> pipe(8) </td>
+
+<td> <tt> -&gt; </tt> </td> <td> Command </td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<ul>
+
+<li> <p> The queue manager (the qmgr(8) server process in the
+figure) is the heart of Postfix mail delivery. It contacts the
+smtp(8), lmtp(8), local(8), virtual(8), pipe(8), discard(8) or
+error(8) delivery agents, and sends a delivery request for one
+or more recipient addresses. The discard(8) and error(8) delivery
+agents are special: they discard or bounce all mail, and are not
+shown in the figure above. </p>
+
+<p> The queue manager maintains a small active queue with the
+messages that it has opened for delivery. The active queue acts as
+a limited window on potentially large incoming or deferred queues.
+The limited active queue prevents the queue manager from running
+out of memory under heavy load. </p>
+
+<p> The queue manager maintains a separate deferred queue for mail
+that cannot be delivered, so that a large mail backlog will not
+slow down normal queue accesses. The queue manager's strategy for
+delayed mail delivery attempts is described in the QSHAPE_README
+and TUNING_README documents. </p>
+
+<li> <p> The trivial-rewrite(8) server resolves each recipient
+address according to its local or remote address class, as defined
+in the ADDRESS_CLASS_README document. Additional routing information
+can be specified with the optional transport(5) table. The
+trivial-rewrite(8) server optionally queries the relocated(5) table
+for recipients whose address has changed; mail for such recipients is
+returned to the sender with an explanation. </p>
+
+<li> <p> The smtp(8) client looks up a list of mail exchangers for
+the destination host, sorts the list by preference, and tries each
+server in turn until it finds a server that responds. It then
+encapsulates the sender, recipient and message content as required
+by the SMTP protocol; this includes conversion of 8-bit MIME to
+7-bit encoding. </p>
+
+<li> <p> The lmtp(8) client speaks a protocol similar to SMTP that
+is optimized for delivery to mailbox servers such as Cyrus. The
+advantage of this setup is that one Postfix machine can feed multiple
+mailbox servers over LMTP. The opposite is true as well: one
+mailbox server can be fed over LMTP by multiple Postfix machines.
+</p>
+
+<li> <p> The local(8) delivery agent understands UNIX-style mailboxes,
+qmail-compatible maildir files, Sendmail-style system-wide aliases(5)
+databases, and Sendmail-style per-user .forward files. Multiple
+local delivery agents can be run in parallel, but parallel delivery
+to the same user is usually limited. </p>
+
+<p> The local(8) delivery agent has hooks for alternative forms of
+local delivery: you can configure it to deliver to mailbox files
+in user home directories, you can configure it to delegate mailbox
+delivery to an external command such as procmail, or you can delegate
+delivery to a different Postfix delivery agent. </p>
+
+<li> <p> The virtual(8) delivery agent is a bare-bones delivery
+agent that delivers to UNIX-style mailbox or qmail-style maildir
+files only. This delivery agent can deliver mail for multiple
+domains, which makes it especially suitable for hosting lots of
+small domains on a single machine. This is described in the
+VIRTUAL_README document. </p>
+
+<li> <p> The pipe(8) mailer is the outbound interface to other mail
+processing systems (the Postfix sendmail(1) command being the
+inbound interface). The interface is UNIX compatible: it provides
+information on the command line and on the standard input stream,
+and expects a process exit status code as defined in &lt;sysexits.h&gt;.
+Examples of delivery via the pipe(8) mailer are in the MAILDROP_README
+and UUCP_README documents.
+
+</ul>
+
+<h2> <a name="behind"> Postfix behind the scenes </a> </h2>
+
+<p> The previous sections gave an overview of how Postfix server
+processes send and receive mail. These server processes rely on
+other server processes that do things behind the scenes. The text
+below attempts to visualize each service in its own context. As
+before, names followed by a number are Postfix commands or server
+programs, while unnumbered names inside shaded areas represent
+Postfix queues. </p>
+
+<ul>
+
+<li> <p> The resident master(8) server is the supervisor that keeps
+an eye on the well-being of the Postfix mail system. It is typically
+started at system boot time with the "postfix start" command, and
+keeps running until the system goes down. The master(8) server is
+responsible for starting Postfix server processes to receive and
+deliver mail, and for restarting servers that terminate prematurely
+because of some problem. The master(8) server is also responsible
+for enforcing the server process count limits as specified in the
+<b>master.cf</b> configuration file. The picture below gives the
+program hierarchy when Postfix is started up. Only some of the mail
+handling daemon processes are shown. </p>
+
+<table>
+
+<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff">
+postfix(1) </td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center"> |<br> |</td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff">
+postfix-script(1) </td> </tr>
+
+<tr> <td> </td> <td> <table> <tr> <td> </td> <td> / </td> </tr>
+<tr> <td> / </td> <td> </td> </tr> </table> </td> <td align="center">
+|<br> |</td> <td> <table> <tr> <td> \ </td> <td> </td> </tr> <tr>
+<td> </td> <td> \ </td> </tr> </table> </td> </tr>
+
+<tr> <td align="center" bgcolor="#f0f0ff"> postsuper(1) </td> <td>
+</td> <td align="center" bgcolor="#f0f0ff"> master(8) </td> <td>
+</td> <td align="center" bgcolor="#f0f0ff"> postlog(1) </td> </tr>
+
+<tr> <td> </td> <td> <table> <tr> <td> </td> <td> / </td> </tr>
+<tr> <td> / </td> <td> </td> </tr> </table> </td> <td align="center">
+|<br> |</td> <td> <table> <tr> <td> \ </td> <td> </td> </tr> <tr>
+<td> </td> <td> \ </td> </tr> </table> </td> </tr>
+
+<tr> <td align="center" bgcolor="#f0f0ff"> smtpd(8) </td> <td>
+</td> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td>
+</td> <td align="center" bgcolor="#f0f0ff"> local(8) </td> </tr>
+
+</table>
+
+<li> <p> The anvil(8) server implements client connection and
+request rate
+limiting for all smtpd(8) servers. The TUNING_README document
+provides guidance for dealing with mis-behaving SMTP clients. The
+anvil(8) service is available in Postfix version 2.2 and later.
+</p>
+
+<table>
+
+<tr> <td> Network </td> <td> <tt> -&gt; </tt> </td> <td align="center"
+bgcolor="#f0f0ff"> <br> smtpd(8)<br><br> </td> <td> <tt> &lt;-&gt;
+</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> anvil(8)<br><br>
+</td> </tr>
+
+</table>
+
+<li> <p> The bounce(8), defer(8) and trace(8) services each maintain
+their own queue directory trees with per-message logfiles. Postfix
+uses this information when sending "failed", "delayed" or "success"
+delivery status notifications to the sender. </p>
+
+<p> The trace(8) service also implements support for the Postfix
+"sendmail
+-bv" and "sendmail -v" commands which produce reports about how
+Postfix delivers mail, and is available with Postfix version 2.1
+and later. See <a href="DEBUG_README.html#trace_mail"> DEBUG_README
+</a> for examples. </p>
+
+<table>
+
+<tr> <td align="center" bgcolor="#f0f0ff"> cleanup(8) </td> <td
+valign="middle"> <tt> -&gt; </tt> </td> <td align="center"
+bgcolor="#f0f0ff"> qmgr(8)<br> Postfix<br> queue </td> <td
+valign="middle"> <tt> -&gt; </tt> </td> <td align="center"
+bgcolor="#f0f0ff"> Delivery<br> agents</td> </tr>
+
+<tr> <td align="center"> ^<br> <tt> | </tt> </td> <td> </td> <td
+align="center"> <tt> |<br> v </tt> </td> <td> </td> <td align="center">
+<tt> |<br> v </tt> </td> </tr>
+
+<tr> <td align="center"> (Non-)<br> delivery<br> notice </td> <td
+valign="middle"> <tt> &lt;- </tt> </td> <td align="center"
+bgcolor="#f0f0ff"> bounce(8)<br> defer(8)<br> trace(8) </td> <td
+valign="middle"> <tt> &lt;- </tt> </td> <td align="center"> Queue
+id,<br> recipient,<br> status</td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center"> <table> <tr> <td
+align="center"> ^<br> <tt> | </tt> </td> <td align="center"> <tt>
+|<br> v </tt> </td> </tr> </table> </td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff">
+Per- <br> message<br> logfiles </td> </tr>
+
+</table>
+
+<li> <p> The flush(8) servers maintain per-destination logs and
+implement both ETRN and "sendmail -qRdestination", as described
+in the ETRN_README document. This moves selected queue files from
+the deferred queue back to the incoming queue and requests their
+delivery. The flush(8) service is available with Postfix version
+1.0 and later. </p>
+
+<table>
+
+<tr> <td colspan="4"> </td> <td align="center" bgcolor="#f0f0ff">
+<a href="QSHAPE_README.html#incoming_queue"> incoming </a><br>^
+<br><a href="QSHAPE_README.html#deferred_queue"> deferred </a>
+</td> </tr>
+
+<tr> <td colspan="4"> </td> <td align="center"> ^<br> |</td> </tr>
+
+<tr> <td align="center" bgcolor="#f0f0ff"> smtpd(8)<br> sendmail(1)<br>
+postqueue(1) </td> <td> <tt> - </tt> </td> <td align="center">
+Destination<br> to flush</td> <td> <tt> -&gt; </tt> </td> <td
+align="center" bgcolor="#f0f0ff"> flush(8) </td> <td> <tt> &lt;-
+</tt> </td> <td align="center"> Deferred<br> destination,<br> queue
+id </td> <td> <tt> - </tt> </td> <td align="center" bgcolor="#f0f0ff">
+Delivery<br> agents,<br> qmgr(8) </td> </tr>
+
+<tr> <td colspan="4"> </td> <td align="center"> <table> <tr> <td
+align="center"> ^<br> <tt> | </tt> </td> <td align="center"> <tt>
+|<br> v </tt> </td> </tr> </table> </td> </tr>
+
+<tr> <td colspan="4"> </td> <td align="center"> Per-dest-<br>
+ination<br> logs </td> </tr>
+
+</table>
+
+<li> <p> The proxymap(8) servers provide read-only and read-write
+table lookup
+service to Postfix processes. This overcomes chroot restrictions,
+reduces the number of open lookup tables by sharing one open
+table among multiple processes, and implements single-updater
+tables. </p>
+
+<li> <p> The scache(8) server maintains the connection cache for
+the Postfix smtp(8) client. When connection caching is enabled for
+selected destinations, the smtp(8) client does not disconnect
+immediately after a mail transaction, but gives the connection to
+the connection cache server which keeps the connection open for a
+limited amount of time. The smtp(8) client continues with some
+other mail delivery request. Meanwhile, any smtp(8) process can
+ask the scache(8) server for that cached connection and reuse it
+for mail delivery. As a safety measure, Postfix limits the number
+of times that a connection may be reused. </p>
+
+<p> When delivering mail to a destination with multiple mail servers,
+connection caching can help to skip over a non-responding server,
+and thus dramatically speed up delivery. SMTP connection caching
+is available in Postfix version 2.2 and later. More information
+about this feature is in the CONNECTION_CACHE_README document. </p>
+
+<table>
+
+<tr> <td> </td> <td> <tt> /-- </tt> </td> <td align="center"
+colspan="3" bgcolor="#f0f0ff"> smtp(8) </td> <td colspan="2"> <tt>
+--&gt; </tt> </td> <td> Internet </td> </tr>
+
+<tr> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> </td>
+<td align="center" rowspan="3"><tt>|<br>|<br>|<br>|<br>v</tt></td>
+</tr>
+
+<tr> <td> &nbsp; </td> <td> <tt> \-- </tt> </td> <td align="center"
+colspan="4" bgcolor="#f0f0ff"> smtp(8) </td> <td align="left">
+&nbsp; </td> </tr>
+
+<tr> <td colspan="2"> &nbsp; </td> <td> </td> <td
+align="center"><tt>^<br>|</tt></td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" colspan="3"
+bgcolor="#f0f0ff"> scache(8) </td> </tr>
+
+</table>
+
+<p> A Postfix smtp(8) client can reuse a TLS-encrypted connection
+(with "smtp_tls_connection_reuse = yes"). This can greatly reduce
+the overhead of connection setup and improves message delivery
+rates. After a Postfix smtp(8) client connects to a remote SMTP
+server and sends plaintext EHLO and STARTTLS commands, the smtp(8)
+client inserts a tlsproxy(8) process into the connection as shown
+below. </p>
+
+<p> After the mail transaction completes, the Postfix smtp(8) client
+gives the smtp(8)-to-tlsproxy(8) connection to the scache(8)
+server, which keeps the connection open for a limited amount of
+time. The smtp(8) client continues with some other mail delivery
+request. Meanwhile, any Postfix smtp(8) client can ask the scache(8)
+server for that cached connection and reuse it for mail delivery.
+</p>
+
+<table>
+
+<tr> <td> </td> <td> <tt> /-- </tt> </td> <td align="center"
+colspan="3" bgcolor="#f0f0ff"> smtp(8) </td> <td colspan="2"> <tt>
+--&gt; </tt> </td> <td align="center"bgcolor="#f0f0ff"> tlsproxy(8)
+</td> <td> <tt> --&gt; </tt> </td> <td> Internet </td> </tr>
+
+<tr> <td align="center" bgcolor="#f0f0ff"> qmgr(8) </td> <td> </td>
+<td align="center" rowspan="3"><tt>|<br>|<br>|<br>|<br>v</tt></td>
+</tr>
+
+<tr> <td> &nbsp; </td> <td> <tt> \-- </tt> </td> <td align="center"
+colspan="4" bgcolor="#f0f0ff"> smtp(8) </td> <td align="left">
+&nbsp; </td> </tr>
+
+<tr> <td colspan="2"> &nbsp; </td> <td> </td> <td
+align="center"><tt>^<br>|</tt></td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" colspan="3"
+bgcolor="#f0f0ff"> scache(8) </td> </tr>
+
+</table>
+
+<li> <p> The showq(8) servers list the Postfix queue status. This
+is the queue listing service that does the work for the mailq(1)
+and postqueue(1) commands. </p>
+
+<table>
+
+<tr> <td> Output </td> <td> <tt> &lt;- </tt> </td> <td align="center"
+bgcolor="#f0f0ff"> mailq(1)<br>
+
+<a href="postqueue.1.html"> post-<br>queue(1) </a> <br> </td> <td>
+<tt> &lt;- </tt> </td> <td align="center" valign="middle"
+bgcolor="#f0f0ff"> showq(8) </td> <td> <tt> &lt;- </tt></td> <td
+align="center" valign="middle" bgcolor="#f0f0ff"> Postfix<br> queue
+</td> </tr>
+
+</table>
+
+<li> <p> The spawn(8) servers run non-Postfix commands on request,
+with the client connected via socket or FIFO to the command's
+standard input, output and error streams. You can find examples of
+its use in the SMTPD_POLICY_README document. </p>
+
+<li> <p> The tlsmgr(8) server runs when TLS (Transport Layer
+Security, formerly known as SSL) is turned on in the Postfix smtp(8)
+client or smtpd(8) server. This process has two duties: </p>
+
+<ul>
+
+<li> <p> Maintain the pseudo-random number generator (PRNG) that
+is used to seed the TLS engines in Postfix smtp(8) client or smtpd(8)
+server processes. The state of this PRNG is periodically saved to
+a file, and is read when tlsmgr(8) starts up. </p>
+
+<li> <p> Maintain the optional Postfix smtp(8) client or smtpd(8)
+server caches with TLS session keys. Saved keys can improve
+performance by reducing the amount of computation at the start of
+a TLS session. </p>
+
+</ul>
+
+<p> TLS support is available in Postfix version 2.2 and later.
+Information about the Postfix TLS implementation is in the TLS_README
+document. </p>
+
+<table>
+
+<tr> <td>Network<tt>-&gt; </tt> </td> <td align="center"
+bgcolor="#f0f0ff"> <br> smtpd(8) <br> &nbsp; </td> <td colspan="2">
+<tt> &lt;---seed---<br><br>&lt;-session-&gt; </tt> </td> <td
+align="center" bgcolor="#f0f0ff"> <br> tlsmgr(8) <br> &nbsp; </td>
+<td colspan="3"> <tt> ---seed---&gt;<br> <br>&lt;-session-&gt;
+</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> smtp(8) <br>
+&nbsp; </td> <td> <tt> -&gt;</tt>Network </td> </tr>
+
+<tr> <td colspan="3"> </td> <td align="right"> <table> <tr> <td>
+</td> <td> / </td> </tr> <tr> <td> / </td> <td> </td> </tr> </table>
+</td> <td align="center"> |<br> |</td> <td align="left"> <table>
+<tr> <td> \ </td> <td> </td> </tr> <tr> <td> </td> <td> \ </td>
+</tr> </table> </td> <td colspan="3"> </td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff">
+smtpd<br> session<br> cache </td> <td> </td> <td align="center"
+bgcolor="#f0f0ff"> PRNG<br> state <br>file </td> <td> </td> <td
+align="center" bgcolor="#f0f0ff"> smtp<br> session<br> cache </td>
+<td colspan="2"> </td> </tr>
+
+</table>
+
+
+<li> <p> The verify(8) server verifies that a sender or recipient
+address is deliverable before the smtpd(8) server accepts it. The
+verify(8) server queries a cache with address verification results.
+If a result is not found, the verify(8) server injects a probe
+message into the Postfix queue and processes the status update from
+a delivery agent or queue manager.
+This process is described in the ADDRESS_VERIFICATION_README
+document. The verify(8) service is available with Postfix version
+2.1 and later. </p>
+
+<table>
+
+<tr>
+
+ <td rowspan="2" colspan="5" align="center" valign="middle">
+ &nbsp; </td> <td rowspan="3" align="center" valign="bottom">
+ <tt> -&gt; </tt> </td> <td rowspan="3" align="center"
+ valign="middle"> probe<br> message </td> <td rowspan="3"
+ align="center" valign="middle"> <tt> -&gt; </tt> </td> <td
+ rowspan="3" bgcolor="#f0f0ff" align="center" valign="middle">
+ Postfix<br> mail<br> queue </td>
+
+</tr>
+
+<tr> <td> </td> </tr>
+
+<tr>
+
+ <td rowspan="3" align="center" valign="middle"> Network </td>
+ <td rowspan="3" align="center" valign="middle"> <tt> -&gt; </tt>
+ </td> <td rowspan="3" bgcolor="#f0f0ff" align="center"
+ valign="middle"> smtpd(8) </td> <td rowspan="3" align="center"
+ valign="middle"> <tt> &lt;-&gt; </tt> </td> <td rowspan="3"
+ bgcolor="#f0f0ff" align="center" valign="middle"> verify(8)
+ </td>
+
+</tr>
+
+<tr>
+
+ <td rowspan="1" colspan="3"> </td> <td rowspan="1" align="center"
+ valign="middle"> <tt> |</tt><br> <tt> v</tt> </td>
+
+</tr>
+
+<tr>
+
+ <td rowspan="3" align="center" valign="top"> <tt> &lt;- </tt>
+ </td> <td rowspan="3" align="center" valign="middle"> probe<br>
+ status </td> <td rowspan="3" align="center" valign="middle">
+ <tt> &lt;- </tt> </td> <td rowspan="3" bgcolor="#f0f0ff"
+ align="center" valign="middle"> Postfix<br> delivery<br> agents
+ </td> <td rowspan="3" align="left" valign="middle"> <tt>-&gt;</tt>
+ Local<br> <tt>-&gt;</tt> Network</td>
+
+</tr>
+
+<tr>
+
+ <td rowspan="3" colspan="4" align="center" valign="middle">
+ &nbsp; </td> <td rowspan="3" align="center" valign="middle">
+ <tt> ^</tt><br> <tt> |</tt><br> <tt> v</tt> </td>
+
+</tr>
+
+<tr> <td> </td> </tr>
+
+<tr> <td colspan="4"> &nbsp; </td> </tr>
+
+<tr>
+
+ <td colspan="4" align="center" valign="middle"> &nbsp; </td>
+ <td bgcolor="#f0f0ff" align="center" valign="middle"> Address<br>
+ verification<br> cache </td>
+
+</tr>
+
+</table>
+
+<li> <p> The postscreen(8) server can be put "in front" of Postfix
+smtpd(8) processes. Its purpose is to accept connections from the
+network and to decide what SMTP clients are allowed to talk to
+Postfix. According to the 2008 MessageLabs annual report, 81% of
+all email was spam, and 90% of that was sent by botnets; by 2010,
+those numbers were 92% and 95%, respectively. While postscreen(8)
+keeps the zombies away, more smtpd(8) processes remain available
+for legitimate clients. </p>
+
+<p> postscreen(8) maintains a temporary allowlist for clients that
+pass its tests; by allowing allowlisted clients to skip tests,
+postscreen(8) minimizes its impact on legitimate email traffic.
+</p>
+
+<p> The postscreen(8) server is available with Postfix 2.8 and
+later. To keep the implementation simple, postscreen(8) delegates
+DNS allow/denylist lookups to dnsblog(8) server processes, and
+delegates TLS encryption/decryption to tlsproxy(8) server processes.
+This delegation is invisible to the remote SMTP client. </p>
+
+<table>
+
+<tr> <td colspan="2"> </td> <td align="center"> zombie </td> </tr>
+
+<tr> <td colspan="3"> </td> <td align="left"> <tt> \ </tt> </td> </tr>
+
+<tr> <td> zombie </td> <td> <tt> - </tt> </td> <td bgcolor="#f0f0ff" align="center"> tlsproxy(8) </td> <td align="left"> <tt> - </tt> </td> <td>
+</td> <td> </td> <td> </td> <td align="right"> <tt> - </tt> </td>
+<td bgcolor="#f0f0ff" align="center"> smtpd(8) </td> </tr>
+
+<tr> <td colspan="3"> </td> <td align="right"> <tt> \ </tt> </td> <td> </td>
+<td align="left"> <tt> / </tt> </td> </tr>
+
+<tr> <td colspan="2"> </td> <td bgcolor="#f0f0ff" align="center"> other </td> <td> <tt>
+--- </tt> </td> <td bgcolor="#f0f0ff" align="center" valign="middle">
+postscreen(8) </td> </tr>
+
+<tr> <td colspan="3"> </td> <td align="right"> <tt> / </tt> </td> <td> </td>
+<td align="right"> <tt> \ </tt> </td> </tr>
+
+<tr> <td colspan="2"> </td> <td bgcolor="#f0f0ff" align="center"> other </td> <td align="left">
+<tt> - </tt> </td> <td> </td> <td> </td> <td> </td> <td align="right">
+<tt> - </tt> </td> <td bgcolor="#f0f0ff" align="center"> smtpd(8)
+</td> </tr>
+
+<tr> <td colspan="3"> </td> <td align="left"> <tt> / </tt> </td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center"> zombie </td> </tr>
+
+</table>
+
+<li> <p>The postlogd(8) server provides an alternative to syslog
+logging, which remains the default. This feature is available with
+Postfix version 3.4 or later, and supports the following modes:
+</p>
+
+
+<ul>
+
+<li> <p>Logging to file, which addresses a usability problem with
+MacOS, and eliminates information loss caused by systemd rate limits.
+</p>
+
+<table>
+
+<tr> <td bgcolor="#f0f0ff" rowspan="3" valign="middle" align="center">
+commands<br>or daemons</td> <td colspan="4"> &nbsp; </td> </tr>
+
+<tr> <td colspan="2"> <td> <tt> -&gt; </tt> </td> <td bgcolor="#f0f0ff">
+postlogd(8) </td> <td> <tt> -&gt; </tt> </td> <td> /path/to/file
+</td> </tr>
+
+<tr> <td colspan=6> &nbsp; </td> </tr>
+
+</table>
+
+<li> <p>Logging to stdout, which eliminates a syslog dependency
+when Postfix runs inside a container. </p>
+
+<table>
+
+<tr> <td bgcolor="#f0f0ff" rowspan="3" valign="middle" align="center">
+commands<br>or daemons</td> <td colspan="4"> &nbsp; </td> <td
+rowspan="3" align="center"> stdout inherited<br>from "postfix
+start-fg" </td> </tr>
+
+<tr> <td colspan="2"> <tt> -&gt; </tt> </td> <td bgcolor="#f0f0ff">
+postlogd(8) </td> <td> <tt> -&gt; </tt> </td> </tr>
+
+<tr> <td colspan=5> &nbsp; </td> </tr>
+
+</table>
+
+</ul>
+
+<p> See MAILLOG_README for details and limitations. </p>
+
+</ul>
+
+<h2> <a name="commands"> Postfix support commands </a> </h2>
+
+<p> The Postfix architecture overview ends with a summary of
+command-line utilities for day-to-day use of the Postfix mail
+system. Besides the Sendmail-compatible sendmail(1), mailq(1), and
+newaliases(1) commands, the Postfix system comes with it own
+collection of command-line utilities. For consistency, these are
+all named post<i>something</i>. </p>
+
+<ul>
+
+<li> <p> The postfix(1) command controls the operation of the mail
+system. It is the interface for starting, stopping, and restarting
+the mail system, as well as for some other administrative operations.
+This command is reserved to the super-user. </p>
+
+<li> <p> The postalias(1) command maintains Postfix aliases(5) type
+databases. This is the program that does the work for the
+newaliases(1) command. </p>
+
+<li> <p> The postcat(1) command displays the contents of Postfix
+queue files. This is a limited, preliminary utility. This program
+is likely to be superseded by something more powerful that can also
+edit Postfix queue files. </p>
+
+<li> <p> The postconf(1) command displays or updates Postfix main.cf
+parameters and displays system dependent information about the
+supported file locking methods, and the supported types of lookup
+tables. </p>
+
+<li> <p> The postdrop(1) command is the mail posting utility that
+is run by the Postfix sendmail(1) command in order to deposit mail
+into the maildrop queue directory. </p>
+
+<li> <p> The postkick(1) command makes some Postfix internal
+communication channels available for use in, for example, shell
+scripts. </p>
+
+<li> <p> The postlock(1) command provides Postfix-compatible mailbox
+locking for use in, for example, shell scripts. </p>
+
+<li> <p> The postlog(1) command provides Postfix-compatible logging
+for shell scripts. </p>
+
+<li> <p> The postmap(1) command maintains Postfix lookup tables
+such as canonical(5), virtual(5) and others. It is a cousin of the
+UNIX makemap command. </p>
+
+<li> <p> The postmulti(1) command repeats the "postfix start" etc.
+command for each Postfix instance, and supports creation, deletion
+etc. of Postfix instances. For a tutorial, see MULTI_INSTANCE_README.
+</p>
+
+<li> <p> The postqueue(1) command is the privileged command that
+is run by Postfix sendmail(1) and mailq(1) in order to flush or
+list the
+mail queue. </p>
+
+<li> <p> The postsuper(1) command maintains the Postfix queue. It
+removes old temporary files, and moves queue files into the right
+directory after a change in the hashing depth of queue directories.
+This command is run at mail system startup time and when Postfix
+is restarted. </p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/PACKAGE_README.html b/proto/PACKAGE_README.html
new file mode 100644
index 0000000..a30d072
--- /dev/null
+++ b/proto/PACKAGE_README.html
@@ -0,0 +1,154 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Guidelines for Package Builders</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Guidelines for Package Builders</h1>
+
+<hr>
+
+<h2>Purpose of this document</h2>
+
+<p> This document has hints and tips for those who manage their
+own Postfix binary distribution for internal use, and for those who
+maintain Postfix binary distributions for general use. </p>
+
+<h2>General distributions: please provide a small default main.cf
+file</h2>
+
+<p> The installed main.cf file must be small. PLEASE resist the
+temptation to list all parameters in the main.cf file. Postfix
+is supposed to be easy to configure. Listing all parameters in main.cf
+defeats the purpose. It is an invitation for hobbyists to make
+random changes without understanding what they do, and gets them
+into endless trouble. </p>
+
+<h2>General distributions: please include README or HTML files</h2>
+
+<p> Please provide the applicable README or HTML files. They are
+referenced by the Postfix manual pages and by other files. Without
+README or HTML files, Postfix will be difficult if not impossible
+to configure. </p>
+
+<h2>Postfix Installation parameters</h2>
+
+<p> Postfix installation is controlled by a dozen installation
+parameters. See the postfix-install and post-install files for
+details. Most parameters have system-dependent default settings
+that are configurable at compile time, as described in the INSTALL
+file. </p>
+
+<h2>Preparing a pre-built package for distribution to other
+systems</h2>
+
+<p> You can build a Postfix package on a machine that does not have
+Postfix installed on it. All you need is Postfix source code and
+a compilation environment that is compatible with the target system.
+</p>
+
+<p> You can build a pre-built Postfix package as an unprivileged
+user. </p>
+
+<p> First compile Postfix. After successful compilation, execute:
+</p>
+
+<blockquote> <pre> % <b>make package</b> </pre>
+</blockquote>
+
+<p> With Postfix versions before 2.2 you must invoke the post-install
+script directly (<tt>% <b>sh post-install</b></tt>). </p>
+
+<p> You will be prompted for installation parameters. Specify an
+install_root directory other than /. The mail_owner and setgid_group
+installation parameter settings will be recorded in the main.cf
+file, but they won't take effect until the package is unpacked and
+installed on the destination machine. </p>
+
+<p> If you want to fully automate this process, specify all the
+non-default installation parameters on the command line: </p>
+
+<blockquote>
+<pre> % <b>make non-interactive-package install_root=/some/where</b>...
+</pre> </blockquote>
+
+<p> With Postfix versions before 2.2 you must invoke the post-install
+script directly (<tt>% <b>sh post-install -non-interactive
+install_root...</b></tt>). </p>
+
+<p> With Postfix 3.0 and later, the command "make package name=value
+..." will replace the string MAIL_VERSION in a configuration parameter
+value with the Postfix release version. Do not try to specify
+something like $mail_version on this command line. This produces
+inconsistent results with different versions of the make(1) command.
+</p>
+
+<h2>Begin Security Alert</h2>
+
+<p> <b> When building an archive for distribution, be sure to
+archive only files and symbolic links, not their parent directories.
+Otherwise, unpacking a pre-built Postfix package may mess up
+permission and/or ownership of system directories such as / /etc
+/usr /usr/bin /var /var/spool and so on. This is especially an
+issue if you executed postfix-install (see above) as an unprivileged
+user. </b> </p>
+
+<h2>End Security Alert</h2>
+
+<p> Thus, to tar up the pre-built package, take the following steps:
+</p>
+
+<blockquote> <pre>
+% cd INSTALL_ROOT
+% rm -f SOMEWHERE/outputfile
+% find . \! -type d -print | xargs tar rf SOMEWHERE/outputfile
+% gzip SOMEWHERE/outputfile </pre> </blockquote>
+
+<p>This way you will not include any directories that might cause
+trouble upon extraction. </p>
+
+<h2>Installing a pre-built Postfix package</h2>
+
+<ul>
+
+<li> <p> To unpack a pre-built Postfix package, execute the equivalent
+of: </p>
+
+<pre>
+# umask 022
+# gzip -d &lt;outputfile.tar.gz | (cd / ; tar xvpf -) </pre>
+
+<p> The umask command is necessary for getting the correct permissions
+on non-Postfix directories that need to be created in the process.
+</p>
+
+<li> <p> Create the necessary mail_owner account and setgid_group
+group for exclusive use by Postfix. </p>
+
+<li> <p> Execute the postfix command to set ownership and permission
+of Postfix files and directories, and to update Postfix configuration
+files. If necessary, specify any non-default settings for mail_owner
+or setgid_group on the postfix command line: </p>
+
+<pre>
+# postfix set-permissions upgrade-configuration \
+ setgid_group=xxx mail_owner=yyy
+</pre>
+
+<p> With Postfix versions before 2.1 you achieve the same result
+by invoking the post-install script directly. </p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/PCRE_README.html b/proto/PCRE_README.html
new file mode 100644
index 0000000..1741826
--- /dev/null
+++ b/proto/PCRE_README.html
@@ -0,0 +1,123 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix PCRE Support</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix PCRE Support</h1>
+
+<hr>
+
+<h2>PCRE (Perl Compatible Regular Expressions) map support</h2>
+
+<p> The optional "pcre" map type allows you to specify regular
+expressions with the PERL style notation such as \s for space and
+\S for non-space. The main benefit, however, is that pcre lookups
+are often faster than regexp lookups. This is because the pcre
+implementation is often more efficient than the POSIX regular
+expression implementation that you find on many systems. </p>
+
+<p> A description of how to use pcre tables, including examples,
+is given in the pcre_table(5) manual page. Information about PCRE
+itself can be found at http://www.pcre.org/. </p>
+
+<h2>Using Postfix packages with PCRE support</h2>
+
+<p> To use pcre with Debian GNU/Linux's Postfix, or with Fedora or
+RHEL 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 from source with PCRE support</h2>
+
+<p> These instructions assume that you build Postfix from source
+code as described in the INSTALL document. </p>
+
+<p> To build Postfix from source with pcre support, you need a pcre
+library. Install a vendor package, or download the source code from
+locations in https://www.pcre.org/ and build that yourself.
+
+<p> Postfix can build with the pcre2 library or the legacy pcre
+library. It's probably easiest to let the Postfix build procedure
+pick one. The following commands will first discover if the pcre2
+library is installed, and if that is not available, will discover
+if the legacy pcre library is installed. </p>
+
+<blockquote>
+<pre>
+$ make -f Makefile.init makefiles
+$ make
+</pre>
+</blockquote>
+
+<p> To build Postfix explicitly with a pcre2 library (Postfix 3.7
+and later): </p>
+
+<blockquote>
+<pre>
+$ make -f Makefile.init makefiles \
+ "CCARGS=-DHAS_PCRE=2 `pcre2-config --cflags`" \
+ "AUXLIBS_PCRE=`pcre2-config --libs8`"
+$ make
+</pre>
+</blockquote>
+
+<p> To build Postfix explicitly with a legacy pcre library (all
+Postfix versions): </p>
+
+<blockquote>
+<pre>
+$ make -f Makefile.init makefiles \
+ "CCARGS=-DHAS_PCRE=1 `pcre-config --cflags`" \
+ "AUXLIBS_PCRE=`pcre-config --libs`"
+$ make
+</pre>
+</blockquote>
+
+<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_PCRE.
+With Postfix 3.0 and later, the old AUXLIBS variable still supports
+building a statically-loaded PCRE database client, but only the new
+AUXLIBS_PCRE variable supports building a dynamically-loaded or
+statically-loaded PCRE database client. </p>
+
+<blockquote>
+
+<p> Failure to use the AUXLIBS_PCRE variable will defeat the purpose
+of dynamic database client loading. Every Postfix executable file
+will have PCRE library dependencies. And that was exactly
+what dynamic database client loading was meant to avoid. </p>
+
+</blockquote>
+
+<h2>Things to know</h2>
+
+<ul>
+
+<li> <p> When Postfix searches a pcre: or regexp: lookup table,
+each pattern is applied to the entire input string. Depending on
+the application, that string is an entire client hostname, an entire
+client IP address, or an entire mail address. Thus, no parent domain
+or parent network search is done, "user@domain" mail addresses are
+not broken up into their user and domain constituent parts, and
+"user+foo" is not broken up into user and foo. </p>
+
+<li> <p> Regular expression tables such as pcre: or regexp: are
+not allowed to do $number substitution in lookup results that can
+be security sensitive: currently, that restriction applies to the
+local aliases(5) database or the virtual(8) delivery agent tables.
+</p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/PGSQL_README.html b/proto/PGSQL_README.html
new file mode 100644
index 0000000..61445ba
--- /dev/null
+++ b/proto/PGSQL_README.html
@@ -0,0 +1,174 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix PostgreSQL Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix PostgreSQL Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> The Postfix pgsql map type allows you to hook up Postfix to a
+PostgreSQL database. This implementation allows for multiple pgsql
+databases: you can use one for a virtual(5) table, one for an
+access(5) table, and one for an aliases(5) table if you want. You
+can specify multiple servers for the same database, so that Postfix
+can switch to a good database server if one goes bad. </p>
+
+<p> Busy mail servers using pgsql maps will generate lots of
+concurrent pgsql clients, so the pgsql server(s) should be run with
+this fact in mind. You can reduce the number of concurrent pgsql
+clients by using the Postfix proxymap(8) service. </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>
+
+<p> In order to build Postfix with pgsql map support, you specify
+-DHAS_PGSQL, the directory with the PostgreSQL header files, and
+the location of the libpq library file. </p>
+
+<p> For example: </p>
+
+<blockquote>
+<pre>
+% make tidy
+% make -f Makefile.init makefiles \
+ 'CCARGS=-DHAS_PGSQL -I/usr/local/include/pgsql' \
+ 'AUXLIBS_PGSQL=-L/usr/local/lib -lpq'
+</pre>
+</blockquote>
+
+<p> If your PostgreSQL shared library is in a directory that the RUN-TIME
+linker does not know about, add a "-Wl,-R,/path/to/directory" option after
+"-lpq". </p>
+
+<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_PGSQL.
+With Postfix 3.0 and later, the old AUXLIBS variable still supports
+building a statically-loaded PostgreSQL database client, but only
+the new AUXLIBS_PGSQL variable supports building a dynamically-loaded
+or statically-loaded PostgreSQL database client. </p>
+
+<blockquote>
+
+<p> Failure to use the AUXLIBS_PGSQL variable will defeat the purpose
+of dynamic database client loading. Every Postfix executable file
+will have PGSQL database library dependencies. And that was exactly
+what dynamic database client loading was meant to avoid. </p>
+
+</blockquote>
+
+<p> Then just run 'make'. </p>
+
+<h2>Configuring PostgreSQL lookup tables</h2>
+
+<p> Once Postfix is built with pgsql support, you can specify a
+map type in main.cf like this: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ alias_maps = pgsql:/etc/postfix/pgsql-aliases.cf
+</pre>
+</blockquote>
+
+<p> The file /etc/postfix/pgsql-aliases.cf specifies lots of
+information telling postfix how to reference the pgsql database.
+For a complete description, see the pgsql_table(5) manual page. </p>
+
+<h2>Example: local aliases </h2>
+
+<pre>
+#
+# pgsql config file for local(8) aliases(5) lookups
+#
+
+#
+# The hosts that Postfix will try to connect to
+hosts = host1.some.domain host2.some.domain
+
+# The user name and password to log into the pgsql server.
+user = someone
+password = some_password
+
+# The database name on the servers.
+dbname = customer_database
+
+# Postfix 2.2 and later The SQL query template. See pgsql_table(5).
+query = SELECT forw_addr FROM mxaliases WHERE alias='%s' AND status='paid'
+
+# For Postfix releases prior to 2.2. See pgsql_table(5) for details.
+select_field = forw_addr
+table = mxaliases
+where_field = alias
+# Don't forget the leading "AND"!
+additional_conditions = AND status = 'paid'
+</pre>
+
+<h2>Using mirrored databases</h2>
+
+<p> Sites that have a need for multiple mail exchangers may enjoy
+the convenience of using a networked mailer database, but do not
+want to introduce a single point of failure to their system. </p>
+
+<p> For this reason we've included the ability to have Postfix
+reference multiple hosts for access to a single pgsql map. This
+will work if sites set up mirrored pgsql databases on two or more
+hosts. </p>
+
+<p> Whenever queries fail with an error at one host, the rest of
+the hosts will be tried in random order. If no pgsql server hosts
+are reachable, then mail will be deferred until at least one of
+those hosts is reachable. </p>
+
+<h2>Credits</h2>
+
+<ul>
+
+<li> This code is based upon the Postfix mysql map by Scott Cotton
+and Joshua Marcus, IC Group, Inc.</li>
+
+<li> The PostgreSQL changes were done by Aaron Sethman.</li>
+
+<li> Updates for Postfix 1.1.x and PostgreSQL 7.1+ and support for
+calling stored procedures were added by Philip Warner.</li>
+
+<li> LaMont Jones was the initial Postfix pgsql maintainer.</li>
+
+<li> Liviu Daia revised the configuration interface and added the
+main.cf configuration feature.</li>
+
+<li> Liviu Daia revised the configuration interface and added the main.cf
+configuration feature.</li>
+
+<li> Liviu Daia with further refinements from Jose Luis Tallon and
+Victor Duchovni developed the common query, result_format, domain and
+expansion_limit interface for LDAP, MySQL and PosgreSQL.</li>
+
+<li> Leandro Santi updated the PostgreSQL client after the PostgreSQL
+developers made major database API changes in response to SQL
+injection problems, and made PQexec() handling more robust. </li>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/POSTSCREEN_3_5_README.html b/proto/POSTSCREEN_3_5_README.html
new file mode 100644
index 0000000..56db379
--- /dev/null
+++ b/proto/POSTSCREEN_3_5_README.html
@@ -0,0 +1,1198 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<head>
+
+<title>Postfix Postscreen Howto (Postfix 2.8 - 3.5)</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Postscreen Howto (Postfix 2.8 - 3.5)</h1>
+
+<hr>
+
+<h2> <a name="intro">Introduction</a> </h2>
+
+<p> This document describes features that are available in Postfix
+2.8 - 3.5. </p>
+
+<p> The Postfix postscreen(8) daemon provides additional protection
+against mail server overload. One postscreen(8) process handles
+multiple inbound SMTP connections, and decides which clients may
+talk to a Postfix SMTP server process. By keeping spambots away,
+postscreen(8) leaves more SMTP server processes available for
+legitimate clients, and delays the onset of <a
+href="STRESS_README.html">server overload</a> conditions. </p>
+
+<p> postscreen(8) should not be used on SMTP ports that receive
+mail from end-user clients (MUAs). In a typical deployment,
+postscreen(8) handles the MX service on TCP port 25, while MUA
+clients submit mail via the submission service on TCP port 587 which
+requires client authentication. Alternatively, a site could set up
+a dedicated, non-postscreen, "port 25" server that provides submission
+service and client authentication, but no MX service. </p>
+
+<p> postscreen(8) maintains a temporary allowlist for clients that
+pass its tests; by allowing allowlisted clients to skip tests,
+postscreen(8) minimizes its impact on legitimate email traffic.
+</p>
+
+<p> postscreen(8) is part of a multi-layer defense. <p>
+
+<ul>
+
+<li> <p> As the first layer, postscreen(8) blocks connections from
+zombies and other spambots that are responsible for about 90% of
+all spam. It is implemented as a single process to make this defense
+as inexpensive as possible. </p>
+
+<li> <p> The second layer implements more complex SMTP-level access
+checks with <a href="SMTPD_ACCESS_README.html">Postfix SMTP servers</a>,
+<a href="SMTPD_POLICY_README.html">policy daemons</a>, and
+<a href="MILTER_README.html">Milter applications</a>. </p>
+
+<li> <p> The third layer performs light-weight content inspection
+with the Postfix built-in header_checks and body_checks. This can
+block unacceptable attachments such as executable programs, and
+worms or viruses with easy-to-recognize signatures. </p>
+
+<li> <p> The fourth layer provides heavy-weight content inspection
+with external content filters. Typical examples are <a
+href="http://www.ijs.si/software/amavisd/">Amavisd-new</a>, <a
+href="http://spamassassin.apache.org/">SpamAssassin</a>, and <a
+href="MILTER_README.html">Milter applications</a>. </p>
+
+</ul>
+
+<p> Each layer reduces the spam volume. The general strategy is to
+use the less expensive defenses first, and to use the more expensive
+defenses only for the spam that remains. </p>
+
+<p> Topics in this document: </p>
+
+<ul>
+
+<li> <a href="#intro">Introduction</a>
+
+<li> <a href="#basic">The basic idea behind postscreen(8)</a>
+
+<li> <a href="#general"> General operation </a>
+
+<li> <a href="#quick">Quick tests before everything else</a>
+
+<li> <a href="#before_220"> Tests before the 220 SMTP server greeting </a>
+
+<li> <a href="#after_220">Tests after the 220 SMTP server greeting</a>
+
+<li> <a href="#other_error">Other errors</a>
+
+<li> <a href="#victory">When all tests succeed</a>
+
+<li> <a href="#config"> Configuring the postscreen(8) service</a>
+
+<li> <a href="#historical"> Historical notes and credits </a>
+
+</ul>
+
+<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2>
+
+<p> Most email is spam, and most spam is sent out by zombies (malware
+on compromised end-user computers). Wietse expects that the zombie
+problem will get worse before things improve, if ever. Without a
+tool like postscreen(8) that keeps the zombies away, Postfix would be
+spending most of its resources not receiving email. </p>
+
+<p> The main challenge for postscreen(8) is to make an is-a-zombie
+decision based on a single measurement. This is necessary because
+many zombies try to fly under the radar and avoid spamming the same
+site repeatedly. Once postscreen(8) decides that a client is
+not-a-zombie, it allowlists the client temporarily to avoid further
+delays for legitimate mail. </p>
+
+<p> Zombies have challenges too: they have only a limited amount
+of time to deliver spam before their IP address becomes denylisted.
+To speed up spam deliveries, zombies make compromises in their SMTP
+protocol implementation. For example, they speak before their turn,
+or they ignore responses from SMTP servers and continue sending
+mail even when the server tells them to go away. </p>
+
+<p> postscreen(8) uses a variety of measurements to recognize
+zombies. First, postscreen(8) determines if the remote SMTP client
+IP address is denylisted. Second, postscreen(8) looks for protocol
+compromises that are made to speed up delivery. These are good
+indicators for making is-a-zombie decisions based on single
+measurements. </p>
+
+<p> postscreen(8) does not inspect message content. Message content
+can vary from one delivery to the next, especially with clients
+that (also) send legitimate email. Content is not a good indicator
+for making is-a-zombie decisions based on single measurements,
+and that is the problem that postscreen(8) is focused on. </p>
+
+<h2> <a name="general"> General operation </a> </h2>
+
+<p> For each connection from an SMTP client, postscreen(8) performs
+a number of tests
+in the order as described below. Some tests introduce a delay of
+a few seconds. postscreen(8) maintains a temporary allowlist for
+clients that pass its tests; by allowing allowlisted clients to
+skip tests, postscreen(8) minimizes its impact on legitimate email
+traffic. </p>
+
+<p> By default, postscreen(8) hands off all connections to a Postfix
+SMTP server process after logging its findings. This mode is useful
+for non-destructive testing. </p>
+
+<p> In a typical production setting, postscreen(8) is configured
+to reject mail from clients that fail one or more tests, after
+logging the helo, sender and recipient information. </p>
+
+<p> Note: postscreen(8) is not an SMTP proxy; this is intentional.
+The purpose is to keep zombies away from Postfix, with minimal
+overhead for legitimate clients. </p>
+
+<h2> <a name="quick">Quick tests before everything else</a> </h2>
+
+<p> Before engaging in SMTP-level tests. postscreen(8) queries a
+number of local deny and allowlists. These tests speed up the
+handling of known clients. </p>
+
+<ul>
+
+<li> <a href="#perm_white_black"> Permanent allow/denylist test </a>
+
+<li> <a href="#temp_white"> Temporary allowlist test </a>
+
+<li> <a href="#white_veto"> MX Policy test </a>
+
+</ul>
+
+<h3> <a name="perm_white_black"> Permanent allow/denylist test </a> </h3>
+
+<p> The postscreen_access_list parameter (default: permit_mynetworks)
+specifies a permanent access list for SMTP client IP addresses. Typically
+one would specify something that allowlists local networks, followed
+by a CIDR table for selective allow- and denylisting. </p>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_access_list = permit_mynetworks,
+ cidr:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+ # Rules are evaluated in the order as specified.
+ # Denylist 192.168.* except 192.168.0.1.
+ 192.168.0.1 permit
+ 192.168.0.0/16 reject
+</pre>
+
+<p> See the postscreen_access_list manpage documentation for more
+details. </p>
+
+<p> When the SMTP client address matches a "permit" action,
+postscreen(8) logs this with the client address and port number as:
+</p>
+
+<pre>
+ <b>WHITELISTED</b> <i>[address]:port</i>
+</pre>
+
+<p> The allowlist action is not configurable: immediately hand off the
+connection to a Postfix SMTP server process. </p>
+
+<p> When the SMTP client address matches a "reject" action,
+postscreen(8) logs this with the client address and port number as:
+</p>
+
+<pre>
+ <b>BLACKLISTED</b> <i>[address]:port</i>
+</pre>
+
+<p> The postscreen_blacklist_action parameter specifies the action
+that is taken next. See "<a href="#fail_before_220">When tests
+fail before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="temp_white"> Temporary allowlist test </a> </h3>
+
+<p> The postscreen(8) daemon maintains a <i>temporary</i>
+allowlist for SMTP client IP addresses that have passed all
+the tests described below. The postscreen_cache_map parameter
+specifies the location of the temporary allowlist. The
+temporary allowlist is not used for SMTP client addresses
+that appear on the <i>permanent</i> access list. </p>
+
+<p> By default the temporary allowlist is not shared with other
+postscreen(8) daemons. See
+<a href="#temp_white_sharing"> Sharing
+the temporary allowlist </a> below for alternatives. </p>
+
+<p> When the SMTP client address appears on the temporary
+allowlist, postscreen(8) logs this with the client address and port
+number as: </p>
+
+<pre>
+ <b>PASS OLD</b> <i>[address]:port</i>
+</pre>
+
+<p> The action is not configurable: immediately hand off the
+connection to a Postfix SMTP server process. The client is
+excluded from further tests until its temporary allowlist
+entry expires, as controlled with the postscreen_*_ttl
+parameters. Expired entries are silently renewed if possible. </p>
+
+<h3> <a name="white_veto"> MX Policy test </a> </h3>
+
+<p> When the remote SMTP client is not on the static access list
+or temporary allowlist, postscreen(8) can implement a number of
+allowlist tests, before it grants the client a temporary allowlist
+status that allows it to talk to a Postfix SMTP server process. </p>
+
+<p> When postscreen(8) is configured to monitor all primary and
+backup MX addresses, it can refuse to allowlist clients that connect
+to a backup MX address only (an old spammer trick to take advantage
+of backup MX hosts with weaker anti-spam policies than primary MX
+hosts). </p>
+
+<blockquote> <p> NOTE: The following solution is for small sites.
+Larger sites would have to share the postscreen(8) cache between
+primary and backup MTAs, which would introduce a common point of
+failure. </p> </blockquote>
+
+<ul>
+
+<li> <p> First, configure the host to listen on both primary and
+backup MX addresses. Use the appropriate <tt>ifconfig</tt> or <tt>ip</tt>
+command for the local operating system, or update the appropriate
+configuration files and "refresh" the network protocol stack. </p>
+
+<p> <p> Second, configure Postfix to listen on the new IP address
+(this step is needed when you have specified inet_interfaces in
+main.cf). </p>
+
+<li> <p> Then, configure postscreen(8) to deny the temporary allowlist
+status on the backup MX address(es). An example for Wietse's
+server is: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_whitelist_interfaces = !168.100.189.8 static:all
+</pre>
+
+<p> Translation: allow clients to obtain the temporary allowlist
+status on all server IP addresses except 168.100.189.8, which is a
+backup MX address. </p>
+
+</ul>
+
+<p> When a non-allowlisted client connects the backup MX address,
+postscreen(8) logs this with the client address and port number as:
+</p>
+
+<pre>
+ <b>CONNECT from</b> <i>[address]:port</i> <b>to [168.100.189.8]:25</b>
+ <b>WHITELIST VETO</b> <i>[address]:port</i>
+</pre>
+
+<p> Translation: the client at <i>[address]:port</i> connected to
+the backup MX address 168.100.189.8 while it was not allowlisted.
+The client will not be granted the temporary allowlist status, even
+if passes all the allowlist tests described below. </p>
+
+<h2> <a name="before_220"> Tests before the 220 SMTP server greeting </a> </h2>
+
+<p> The postscreen_greet_wait parameter specifies a short time
+interval before the "220 <i>text</i>..." server greeting, where
+postscreen(8) can run a number of tests in parallel. </p>
+
+<p> When a good client passes these tests, and no "<a
+href="#after_220">deep protocol tests</a>"
+are configured, postscreen(8)
+adds the client to the temporary allowlist and hands off the "live"
+connection to a Postfix SMTP server process. The client can then
+continue as if postscreen(8) never even existed (except of course
+for the short postscreen_greet_wait delay). </p>
+
+<ul>
+
+<li> <a href="#pregreet"> Pregreet test </a>
+
+<li> <a href="#dnsbl"> DNS Allow/denylist test </a>
+
+<li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a>
+
+</ul>
+
+<h3> <a name="pregreet"> Pregreet test </a> </h3>
+
+<p> The SMTP protocol is a classic example of a protocol where the
+server speaks before the client. postscreen(8) detects zombies
+that are in a hurry and that speak before their turn. This test is
+enabled by default. </p>
+
+<p> The postscreen_greet_banner parameter specifies the <i>text</i>
+portion of a "220-<i>text</i>..." teaser banner (default: $smtpd_banner).
+Note that this becomes the first part of a multi-line server greeting.
+The postscreen(8) daemon sends this before the postscreen_greet_wait
+timer is started. The purpose of the teaser banner is to confuse
+zombies so that they speak before their turn. It has no effect on
+SMTP clients that correctly implement the protocol. </p>
+
+<p> To avoid problems with poorly-implemented SMTP engines in network
+appliances or network testing tools, either exclude them from all
+tests with the postscreen_access_list feature or else specify
+an empty teaser banner: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Exclude broken clients by allowlisting. Clients in mynetworks
+ # should always be allowlisted.
+ postscreen_access_list = permit_mynetworks,
+ cidr:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+ 192.168.254.0/24 permit
+</pre>
+
+<pre>
+/etc/postfix/main.cf:
+ # Disable the teaser banner (try allowlisting first if you can).
+ postscreen_greet_banner =
+</pre>
+
+<p> When an SMTP client sends a command before the
+postscreen_greet_wait time has elapsed, postscreen(8) logs this as:
+</p>
+
+<pre>
+ <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
+</pre>
+
+<p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
+bytes before its turn to speak. This happened <i>time</i> seconds
+after the postscreen_greet_wait timer was started. The <i>text</i>
+is what the client sent (truncated to 100 bytes, and with non-printable
+characters replaced with C-style escapes such as \r for carriage-return
+and \n for newline). </p>
+
+<p> The postscreen_greet_action parameter specifies the action that
+is taken next. See "<a href="#fail_before_220">When tests fail
+before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="dnsbl"> DNS Allow/denylist test </a> </h3>
+
+<p> The postscreen_dnsbl_sites parameter (default: empty) specifies
+a list of DNS blocklist servers with optional filters and weight
+factors (positive weights for denylisting, negative for allowlisting).
+These servers will be queried in parallel with the reverse client
+IP address. This test is disabled by default. </p>
+
+<blockquote>
+<p>
+CAUTION: when postscreen rejects mail, its SMTP reply contains the
+DNSBL domain name. Use the postscreen_dnsbl_reply_map feature to
+hide "password" information in DNSBL domain names.
+</p>
+</blockquote>
+
+<p> When the postscreen_greet_wait time has elapsed, and the combined
+DNSBL score is equal to or greater than the postscreen_dnsbl_threshold
+parameter value, postscreen(8) logs this as: </p>
+
+<pre>
+ <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> has a combined
+DNSBL score of <i>count</i>. </p>
+
+<p> The postscreen_dnsbl_action parameter specifies the action that
+is taken when the combined DNSBL score is equal to or greater than
+the threshold. See "<a href="#fail_before_220">When tests fail
+before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="fail_before_220">When tests fail before the 220 SMTP server greeting</a> </h3>
+
+<p> When the client address matches the permanent denylist, or
+when the client fails the pregreet or DNSBL tests, the action is
+specified with postscreen_blacklist_action, postscreen_greet_action,
+or postscreen_dnsbl_action, respectively. </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default) </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Repeat this test the next time the client connects. This option
+is useful for testing and collecting statistics without blocking
+mail. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. </dd>
+
+</dl>
+
+<h2> <a name="after_220">Tests after the 220 SMTP server greeting</a> </h2>
+
+<p> In this phase of the protocol, postscreen(8) implements a
+number of "deep protocol" tests. These tests use an SMTP protocol
+engine that is built into the postscreen(8) server. </p>
+
+<p> Important note: these protocol tests are disabled by default.
+They are more intrusive than the pregreet and DNSBL tests, and they
+have limitations as discussed next. </p>
+
+<ul>
+
+<li> <p> The main limitation of "after 220 greeting" tests is that
+a new client must disconnect after passing these tests (reason:
+postscreen is not a proxy). Then the client must reconnect from
+the same IP address before it can deliver mail. The following
+measures may help to avoid email delays: </p>
+
+<ul>
+
+<li> <p> Allow "good" clients to skip tests with the
+postscreen_dnsbl_whitelist_threshold feature (Postfix 2.11 and
+later). This is especially effective for sites such as Google that
+never retry immediately from the same IP address. </p>
+
+<li> <p> Small sites: Configure postscreen(8) to listen on multiple
+IP addresses, published in DNS as different IP addresses for the
+same MX hostname or for different MX hostnames. This avoids mail
+delivery delays with clients that reconnect immediately from the
+same IP address. </p>
+
+<li> <p> Large sites: Share the postscreen(8) cache between different
+Postfix MTAs with a large-enough memcache_table(5). Again, this
+avoids mail delivery delays with clients that reconnect immediately
+from the same IP address. </p>
+
+</ul>
+
+<li> <p> postscreen(8)'s built-in SMTP engine does not implement the
+AUTH, XCLIENT, and XFORWARD features. If you need to make these
+services available on port 25, then do not enable the tests after
+the 220 server greeting. </p>
+
+<li> <p> End-user clients should connect directly to the submission
+service, so that they never have to deal with postscreen(8)'s tests.
+</p>
+
+</ul>
+
+<p> The following "after 220 greeting" tests are available: </p>
+
+<ul>
+
+<li> <a href="#pipelining">Command pipelining test</a>
+
+<li> <a href="#non_smtp">Non-SMTP command test</a>
+
+<li> <a href="#barelf">Bare newline test</a>
+
+<li> <a href="#fail_after_220">When tests fail after the 220 SMTP server greeting</a>
+
+</ul>
+
+<h3> <a name="pipelining">Command pipelining test</a> </h3>
+
+<p> By default, SMTP is a half-duplex protocol: the sender and
+receiver send one command and one response at a time. Unlike the
+Postfix SMTP server, postscreen(8) does not announce support
+for ESMTP command pipelining. Therefore, clients are not allowed
+to send multiple commands. postscreen(8)'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "postscreen_pipelining_enable = yes", postscreen(8) detects
+zombies that send multiple commands, instead of sending one command
+and waiting for the server to reply. </p>
+
+<p> This test is opportunistically enabled when postscreen(8) has
+to use the built-in SMTP engine anyway. This is to make postscreen(8)
+logging more informative. </p>
+
+<p> When a client sends multiple commands, postscreen(8) logs this
+as: </p>
+
+<pre>
+ <b>COMMAND PIPELINING from</b> <i>[address]:port</i> <b>after</b> <i>command</i>: <i>text</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent
+multiple SMTP commands, instead of sending one command and then
+waiting for the server to reply. This happened after the client
+sent <i>command</i>. The <i>text</i> shows part of the input that
+was sent too early; it is not logged with Postfix 2.8. </p>
+
+<p> The postscreen_pipelining_action parameter specifies the action
+that is taken next. See "<a href="#fail_after_220">When tests fail
+after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="non_smtp">Non-SMTP command test</a> </h3>
+
+<p> Some spambots send their mail through open proxies. A symptom
+of this is the usage of commands such as CONNECT and other non-SMTP
+commands. Just like the Postfix SMTP server's smtpd_forbidden_commands
+feature, postscreen(8) has an equivalent postscreen_forbidden_commands
+feature to block these clients. postscreen(8)'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "postscreen_non_smtp_command_enable = yes", postscreen(8)
+detects zombies that send commands specified with the
+postscreen_forbidden_commands parameter. This also detects commands
+with the syntax of a message header label. The latter is a symptom
+that the client is sending message content after ignoring all the
+responses from postscreen(8) that reject mail. </p>
+
+<p> This test is opportunistically enabled when postscreen(8) has
+to use the built-in SMTP engine anyway. This is to make postscreen(8)
+logging more informative. </p>
+
+<p> When a client sends non-SMTP commands, postscreen(8) logs this
+as: </p>
+
+<pre>
+ <b>NON-SMTP COMMAND from</b> <i>[address]:port</i> <b>after</b> <i>command: text</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a
+command that matches the postscreen_forbidden_commands
+parameter, or that has the syntax of a message header label (text
+followed by optional space and ":").
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> The postscreen_non_smtp_command_action parameter specifies
+the action that is taken next. See "<a href="#fail_after_220">When
+tests fail after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="barelf">Bare newline test</a> </h3>
+
+<p> SMTP is a line-oriented protocol: lines have a limited length,
+and are terminated with &lt;CR&gt;&lt;LF&gt;. Lines ending in a
+"bare" &lt;LF&gt;, that is newline not preceded by carriage return,
+are not allowed in SMTP. postscreen(8)'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "postscreen_bare_newline_enable = yes", postscreen(8)
+detects clients that send lines ending in bare newline characters.
+</p>
+
+<p> This test is opportunistically enabled when postscreen(8) has
+to use the built-in SMTP engine anyway. This is to make postscreen(8)
+logging more informative. </p>
+
+<p> When a client sends bare newline characters, postscreen(8) logs
+this as:
+</p>
+
+<pre>
+ <b>BARE NEWLINE from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
+newline character, that is newline not preceded by carriage
+return.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> The postscreen_bare_newline_action parameter specifies the
+action that is taken next. See "<a href="#fail_after_220">When
+tests fail after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="fail_after_220">When tests fail after the 220 SMTP server greeting</a> </h3>
+
+<p> When the client fails the pipelining, non-SMTP command or bare
+newline tests, the action is specified with postscreen_pipelining_action,
+postscreen_non_smtp_command_action or postscreen_bare_newline_action,
+respectively. </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default for bare newline) </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Do NOT repeat this test before the result from some other test
+expires.
+
+This option is useful for testing and collecting statistics without
+blocking mail permanently. </dd>
+
+<dt> <b>enforce</b> (default for pipelining) </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver
+mail with a 550 SMTP reply, and log the helo/sender/recipient
+information. Repeat this test the next time the client connects.
+</dd>
+
+<dt> <b>drop</b> (default for non-SMTP commands) </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. This action is
+compatible with the Postfix SMTP server's smtpd_forbidden_commands
+feature. </dd>
+
+</dl>
+
+<h2> <a name="other_error">Other errors</a> </h2>
+
+<p> When an SMTP client hangs up unexpectedly, postscreen(8) logs
+this as: </p>
+
+<pre>
+ <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> disconnected
+unexpectedly, <i>time</i> seconds after the start of the
+test named <i>test name</i>. </p>
+
+<p> There is no punishment for hanging up. A client that hangs up
+without sending the QUIT command can still pass all postscreen(8)
+tests. </p>
+
+<!--
+
+<p> While an unexpired penalty is in effect, an SMTP client is not
+allowed to pass any tests, and postscreen(8) logs each connection
+with the remaining amount of penalty time as: </p>
+
+<pre>
+ <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
+</pre>
+
+<p> During this time, all attempts by the client to deliver mail
+will be deferred with a 450 SMTP status. </p>
+
+-->
+
+<p> The following errors are reported by the built-in SMTP engine.
+This engine never accepts mail, therefore it has per-session limits
+on the number of commands and on the session length. </p>
+
+<pre>
+ <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-command time limit as specified with the postscreen_command_time_limit
+parameter. The session is terminated immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<pre>
+ <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-session command count limit as specified with the
+postscreen_command_count_limit parameter. The session is terminated
+immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<pre>
+ <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-command length limit, as specified with the line_length_limit
+parameter. The session is terminated immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> When an SMTP client makes too many connections at the same time,
+postscreen(8) rejects the connection with a 421 status code and logs: </p>
+
+<pre>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
+</pre>
+
+<p> The postscreen_client_connection_count_limit parameter controls this limit. </p>
+
+<p> When an SMTP client connects after postscreen(8) has reached a
+connection count limit, postscreen(8) rejects the connection with
+a 421 status code and logs: </p>
+
+<pre>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all screening ports busy</b>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
+</pre>
+
+<p> The postscreen_pre_queue_limit and postscreen_post_queue_limit
+parameters control these limits. </p>
+
+<h2> <a name="victory">When all tests succeed</a> </h2>
+
+<p> When a new SMTP client passes all tests (i.e. it is not allowlisted
+via some mechanism), postscreen(8) logs this as: </p>
+
+<pre>
+ <b>PASS NEW</b> <i>[address]:port</i>
+</pre>
+
+<p> Where <i>[address]:port</i> are the client IP address and port.
+Then, postscreen(8)
+creates a temporary allowlist entry that excludes the client IP
+address from further tests until the temporary allowlist entry
+expires, as controlled with the postscreen_*_ttl parameters. </p>
+
+<p> When no "<a href="#after_220">deep protocol tests</a>" are
+configured, postscreen(8) hands off the "live" connection to a Postfix
+SMTP server process. The client can then continue as if postscreen(8)
+never even existed (except for the short postscreen_greet_wait delay).
+</p>
+
+<p> When any "<a href="#after_220">deep protocol tests</a>" are
+configured, postscreen(8) cannot hand off the "live" connection to
+a Postfix SMTP server process in the middle of the session. Instead,
+postscreen(8) defers mail delivery attempts with a 4XX status, logs
+the helo/sender/recipient information, and waits for the client to
+disconnect. The next time the client connects it will be allowed
+to talk to a Postfix SMTP server process to deliver its mail.
+postscreen(8) mitigates the impact of this limitation by giving
+<a href="#after_220">deep protocol tests</a> a long expiration
+time. </p>
+
+<h2> <a name="config"> Configuring the postscreen(8) service</a>
+</h2>
+
+<p> postscreen(8) has been tested on FreeBSD [4-8], Linux 2.[4-6]
+and Solaris 9 systems. </p>
+
+<ul>
+
+<li> <a href="#enable"> Turning on postscreen(8) without blocking
+mail</a>
+
+<li> <a href="#starttls"> postscreen(8) TLS configuration </a>
+
+<li> <a href="#blocking"> Blocking mail with postscreen(8) </a>
+
+<li> <a href="#turnoff"> Turning off postscreen(8) </a>
+
+<li> <a href="#temp_white_sharing"> Sharing the temporary allowlist
+</a>
+
+</ul>
+
+<h3> <a name="enable"> Turning on postscreen(8) without blocking mail</a> </h3>
+
+<p> To enable the postscreen(8) service and log client information
+without blocking mail: </p>
+
+<ol>
+
+<li> <p> Make sure that local clients and systems with non-standard
+SMTP implementations are excluded from any postscreen(8) tests. The
+default is to exclude all clients in mynetworks. To exclude additional
+clients, for example, third-party performance monitoring tools (these
+tend to have broken SMTP implementations): </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Exclude broken clients by allowlisting. Clients in mynetworks
+ # should always be allowlisted.
+ postscreen_access_list = permit_mynetworks,
+ cidr:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+ 192.168.254.0/24 permit
+</pre>
+
+<li> <p> Comment out the "<tt>smtp inet ... smtpd</tt>" service
+in master.cf, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #smtp inet n - n - - smtpd
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the new "<tt>smtpd pass ... smtpd</tt>" service
+in master.cf, and duplicate any "<tt>-o parameter=value</tt>" entries
+from the smtpd service that was commented out in the previous step.
+</p>
+
+<pre>
+/etc/postfix/master.cf:
+ smtpd pass - - n - - smtpd
+ -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the new "<tt>smtp inet ... postscreen</tt>"
+service in master.cf. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - 1 postscreen
+</pre>
+
+<li> <p> Uncomment the new "<tt>tlsproxy unix ... tlsproxy</tt>"
+service in master.cf. This service implements STARTTLS support for
+postscreen(8). </p>
+
+<pre>
+/etc/postfix/master.cf:
+ tlsproxy unix - - n - 0 tlsproxy
+</pre>
+
+<li> <p> Uncomment the new "<tt>dnsblog unix ... dnsblog</tt>"
+service in master.cf. This service does DNSBL lookups for postscreen(8)
+and logs results. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ dnsblog unix - - n - 0 dnsblog
+</pre>
+
+<li> <p> To enable DNSBL lookups, list some DNS blocklist sites in
+main.cf, separated by whitespace. Different sites can have different
+weights. For example:
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_dnsbl_threshold = 2
+ postscreen_dnsbl_sites = zen.spamhaus.org*2
+ bl.spamcop.net*1 b.barracudacentral.org*1
+</pre>
+
+<p> Note: if your DNSBL queries have a "secret" in the domain name,
+you must censor this information from the postscreen(8) SMTP replies.
+For example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply
+</pre>
+
+<pre>
+/etc/postfix/dnsbl_reply:
+ # Secret DNSBL name Name in postscreen(8) replies
+ secret.zen.dq.spamhaus.net zen.spamhaus.org
+</pre>
+
+<p> The texthash: format is similar to hash: except that there is
+no need to run postmap(1) before the file can be used, and that it
+does not detect changes after the file is read. It is new with
+Postfix version 2.8. </p>
+
+<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
+</p>
+
+</ol>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Some postscreen(8) configuration parameters implement
+stress-dependent behavior. This is supported only when the default
+value is stress-dependent (that is, "postconf -d <i>parametername</i>"
+output shows
+"<i>parametername</i>&nbsp;=&nbsp;${stress?<i>something</i>}${stress:<i>something</i>}" or
+"<i>parametername</i>&nbsp;=&nbsp;${stress?{<i>something</i>}:{<i>something</i>}}").
+Other parameters always evaluate as if the stress value is the empty
+string. </p>
+
+<li> <p> See "<a href="#before_220">Tests before the 220 SMTP server
+greeting</a>" for details about the logging from these
+postscreen(8) tests. </p>
+
+<li> <p> If you run Postfix 2.6 or earlier you must stop and start
+the master daemon ("<tt>postfix stop; postfix start</tt>"). This
+is needed because the Postfix "pass" master service type did not
+work reliably on all systems. </p>
+
+</ul>
+
+<h3> <a name="starttls"> postscreen(8) TLS configuration </a> </h3>
+
+<p> postscreen(8) TLS support is available for remote SMTP clients
+that aren't allowlisted, including clients that need to renew their
+temporary allowlist status. When a remote SMTP client requests TLS
+service, postscreen(8) invisibly hands off the connection to a
+tlsproxy(8) process. Then, tlsproxy(8) encrypts and decrypts the
+traffic between postscreen(8) and the remote SMTP client. One
+tlsproxy(8) process can handle multiple SMTP sessions. The number
+of tlsproxy(8) processes slowly increases with server load, but it
+should always be much smaller than the number of postscreen(8) TLS
+sessions. </p>
+
+<p> TLS support for postscreen(8) and tlsproxy(8) uses the same
+parameters as with smtpd(8). We recommend that you keep the relevant
+configuration parameters in main.cf. If you must specify "-o
+smtpd_mumble=value" parameter overrides in master.cf for a
+postscreen-protected smtpd(8) service, then you should specify those
+same parameter overrides for the postscreen(8) and tlsproxy(8)
+services. </p>
+
+<h3> <a name="blocking"> Blocking mail with postscreen(8) </a> </h3>
+
+<p> For compatibility with smtpd(8), postscreen(8) implements the
+soft_bounce safety feature. This causes Postfix to reject mail with
+a "try again" reply code. </p>
+
+<ul>
+
+<li> <p> To turn this on for all of Postfix, specify "<tt>soft_bounce
+= yes</tt>" in main.cf. </p>
+
+<li> <p> To turn this on for postscreen(8) only, append "<tt>-o
+soft_bounce=yes</tt>" (note: NO SPACES around '=') to the postscreen
+entry in master.cf. <p>
+
+</ul>
+
+<p> Execute "<tt>postfix reload</tt>" to make the change effective. </p>
+
+<p> After testing, do not forget to remove the soft_bounce feature,
+otherwise senders won't receive their non-delivery notification
+until many days later. </p>
+
+<p> To use the postscreen(8) service to block mail, edit main.cf and
+specify one or more of: </p>
+
+<ul>
+
+<li> <p> "<tt>postscreen_dnsbl_action = enforce</tt>", to reject
+clients that are on DNS blocklists, and to log the helo/sender/recipient
+information. With good DNSBLs this reduces the amount of load on
+Postfix SMTP servers dramatically. </p>
+
+<li> <p> "<tt>postscreen_greet_action = enforce</tt>", to reject
+clients that talk before their turn, and to log the helo/sender/recipient
+information. This stops over half of all known-to-be illegitimate
+connections to Wietse's mail server. It is backup protection for
+zombies that haven't yet been denylisted. </p>
+
+<li> <p> You can also enable "<a href="#after_220">deep protocol
+tests</a>", but these are more intrusive than the pregreet or DNSBL
+tests. </p>
+
+<p> When a good client passes the "<a href="#after_220">deep
+protocol tests</a>",
+postscreen(8) adds the client to the temporary
+allowlist but it cannot hand off the "live" connection to a Postfix
+SMTP server process in the middle of the session. Instead, postscreen(8)
+defers mail delivery attempts with a 4XX status, logs the
+helo/sender/recipient information, and waits for the client to
+disconnect. </p>
+
+<p> When the good client comes back in a later session, it is allowed
+to talk directly to a Postfix SMTP server. See "<a href="#after_220">Tests
+after the 220 SMTP server greeting</a>" above for limitations with
+AUTH and other features that clients may need. </p>
+
+<p> An unexpected benefit from "<a href="#after_220">deep protocol
+tests</a>" is that some "good" clients don't return after the 4XX
+reply; these clients were not so good after all. </p>
+
+<p> Unfortunately, some senders will retry requests from different
+IP addresses, and may never get allowlisted. For this reason,
+Wietse stopped using "<a href="#after_220">deep protocol tests</a>"
+on his own internet-facing mail server. </p>
+
+<li> <p> There is also support for permanent denylisting and
+allowlisting; see the description of the postscreen_access_list
+parameter for details. </p>
+
+</ul>
+
+<h3> <a name="turnoff"> Turning off postscreen(8) </a> </h3>
+
+<p> To turn off postscreen(8) and handle mail directly with Postfix
+SMTP server processes: </p>
+
+<ol>
+
+<li> <p> Comment out the "<tt>smtp inet ... postscreen</tt>" service
+in master.cf, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #smtp inet n - n - 1 postscreen
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Comment out the "<tt>dnsblog unix ... dnsblog</tt>" service
+in master.cf. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #dnsblog unix - - n - 0 dnsblog
+</pre>
+
+<li> <p> Comment out the "<tt>smtpd pass ... smtpd</tt>" service
+in master.cf, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #smtpd pass - - n - - smtpd
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Comment out the "<tt>tlsproxy unix ... tlsproxy</tt>"
+service in master.cf, including any "<tt>-o parameter=value</tt>"
+entries that follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #tlsproxy unix - - n - 0 tlsproxy
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the "<tt>smtp inet ... smtpd</tt>" service in
+master.cf, including any "<tt>-o parameter=value</tt>" entries that
+may follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - - smtpd
+ -o parameter=value ...
+</pre>
+
+<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
+</p>
+
+</ol>
+
+<h3> <a name="temp_white_sharing"> Sharing the temporary allowlist </a> </h3>
+
+<p> By default, the temporary allowlist is not shared between
+multiple postscreen(8) daemons. To enable sharing, choose one
+of the following options: </p>
+
+<ul>
+
+<li> <p> A non-persistent memcache: temporary allowlist can be shared
+ between postscreen(8) daemons on the same host or different
+ hosts. Disable cache cleanup (postscreen_cache_cleanup_interval
+ = 0) in all postscreen(8) daemons because memcache: has no
+ first-next API (but see example 4 below for memcache: with
+ persistent backup). This requires Postfix 2.9 or later. </p>
+
+ <pre>
+ # Example 1: non-persistent memcache: allowlist.
+ /etc/postfix/main.cf:
+ postscreen_cache_map = memcache:/etc/postfix/postscreen_cache
+ postscreen_cache_cleanup_interval = 0
+
+ /etc/postfix/postscreen_cache:
+ memcache = inet:127.0.0.1:11211
+ key_format = postscreen:%s
+ </pre>
+
+<li> <p>
+ A persistent lmdb: temporary allowlist can be shared between
+ postscreen(8) daemons that run under the same master(8) daemon,
+ or under different master(8) daemons on the same host. Disable
+ cache cleanup (postscreen_cache_cleanup_interval = 0) in all
+ postscreen(8) daemons except one that is responsible for cache
+ cleanup. This requires Postfix 2.11 or later. </p>
+
+ <pre>
+ # Example 2: persistent lmdb: allowlist.
+ /etc/postfix/main.cf:
+ postscreen_cache_map = lmdb:$data_directory/postscreen_cache
+ # See note 1 below.
+ # postscreen_cache_cleanup_interval = 0
+ </pre>
+
+<li> <p> Other kinds of persistent temporary allowlist can be shared
+ only between postscreen(8) daemons that run under the same
+ master(8) daemon. In this case, temporary allowlist access must
+ be shared through the proxymap(8) daemon. This requires Postfix
+ 2.9 or later. </p>
+
+ <pre>
+ # Example 3: proxied btree: allowlist.
+ /etc/postfix/main.cf:
+ postscreen_cache_map =
+ proxy:btree:/var/lib/postfix/postscreen_cache
+ # See note 1 below.
+ # postscreen_cache_cleanup_interval = 0
+
+ # Example 4: proxied btree: allowlist with memcache: accelerator.
+ /etc/postfix/main.cf:
+ postscreen_cache_map = memcache:/etc/postfix/postscreen_cache
+ proxy_write_maps =
+ proxy:btree:/var/lib/postfix/postscreen_cache
+ ... other proxied tables ...
+ # See note 1 below.
+ # postscreen_cache_cleanup_interval = 0
+
+ /etc/postfix/postscreen_cache:
+ # Note: the $data_directory macro is not defined in this context.
+ memcache = inet:127.0.0.1:11211
+ backup = proxy:btree:/var/lib/postfix/postscreen_cache
+ key_format = postscreen:%s
+ </pre>
+
+ <p> Note 1: disable cache cleanup (postscreen_cache_cleanup_interval
+ = 0) in all postscreen(8) daemons except one that is responsible
+ for cache cleanup. </p>
+
+ <p> Note 2: postscreen(8) cache sharing via proxymap(8) requires Postfix
+ 2.9 or later; earlier proxymap(8) implementations don't support
+ cache cleanup. </p>
+
+</ul>
+
+<h2> <a name="historical"> Historical notes and credits </a> </h2>
+
+<p> Many ideas in postscreen(8) were explored in earlier work by
+Michael Tokarev, in OpenBSD spamd, and in MailChannels Traffic
+Control. </p>
+
+<p> Wietse threw together a crude prototype with pregreet and dnsbl
+support in June 2009, because he needed something new for a Mailserver
+conference presentation in July. Ralf Hildebrandt ran this code on
+several servers to collect real-world statistics. This version used
+the dnsblog(8) ad-hoc DNS client program. </p>
+
+<p> Wietse needed new material for a LISA conference presentation
+in November 2010, so he added support for DNSBL weights and filters
+in August, followed by a major code rewrite, deep protocol tests,
+helo/sender/recipient logging, and stress-adaptive behavior in
+September. Ralf Hildebrandt ran this code on several servers to
+collect real-world statistics. This version still used the embarrassing
+dnsblog(8) ad-hoc DNS client program. </p>
+
+<p> Wietse added STARTTLS support in December 2010. This makes
+postscreen(8) usable for sites that require TLS support. The
+implementation introduces the tlsproxy(8) event-driven TLS proxy
+that decrypts/encrypts the sessions for multiple SMTP clients. </p>
+
+<p> The tlsproxy(8) implementation led to the discovery of a "new"
+class of vulnerability (<a
+href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0411"
+>CVE-2011-0411</a>) that affected multiple implementations of SMTP,
+POP, IMAP, NNTP, and FTP over TLS. </p>
+
+<p> postscreen(8) was officially released as part of the Postfix
+2.8 stable release in January 2011.</p>
+
+</body>
+
+</html>
diff --git a/proto/POSTSCREEN_README.html b/proto/POSTSCREEN_README.html
new file mode 100644
index 0000000..8ab3235
--- /dev/null
+++ b/proto/POSTSCREEN_README.html
@@ -0,0 +1,1214 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<head>
+
+<title>Postfix Postscreen Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Postscreen Howto</h1>
+
+<hr>
+
+<h2> <a name="intro">Introduction</a> </h2>
+
+<p> This document describes features that are available in Postfix
+3.6 and later. See <a href="POSTSCREEN_3_5_README.html">
+POSTSCREEN_3_5_README.html</a> for Postfix versions 2.8 - 3.5. </p>
+
+<p> The Postfix postscreen(8) daemon provides additional protection
+against mail server overload. One postscreen(8) process handles
+multiple inbound SMTP connections, and decides which clients may
+talk to a Postfix SMTP server process. By keeping spambots away,
+postscreen(8) leaves more SMTP server processes available for
+legitimate clients, and delays the onset of <a
+href="STRESS_README.html">server overload</a> conditions. </p>
+
+<p> postscreen(8) should not be used on SMTP ports that receive
+mail from end-user clients (MUAs). In a typical deployment,
+postscreen(8) handles the MX service on TCP port 25, while MUA
+clients submit mail via the submission service on TCP port 587 which
+requires client authentication. Alternatively, a site could set up
+a dedicated, non-postscreen, "port 25" server that provides submission
+service and client authentication, but no MX service. </p>
+
+<p> postscreen(8) maintains a temporary allowlist for clients that
+pass its tests; by allowing allowlisted clients to skip tests,
+postscreen(8) minimizes its impact on legitimate email traffic.
+</p>
+
+<p> postscreen(8) is part of a multi-layer defense. <p>
+
+<ul>
+
+<li> <p> As the first layer, postscreen(8) blocks connections from
+zombies and other spambots that are responsible for about 90% of
+all spam. It is implemented as a single process to make this defense
+as inexpensive as possible. </p>
+
+<li> <p> The second layer implements more complex SMTP-level access
+checks with <a href="SMTPD_ACCESS_README.html">Postfix SMTP servers</a>,
+<a href="SMTPD_POLICY_README.html">policy daemons</a>, and
+<a href="MILTER_README.html">Milter applications</a>. </p>
+
+<li> <p> The third layer performs light-weight content inspection
+with the Postfix built-in header_checks and body_checks. This can
+block unacceptable attachments such as executable programs, and
+worms or viruses with easy-to-recognize signatures. </p>
+
+<li> <p> The fourth layer provides heavy-weight content inspection
+with external content filters. Typical examples are <a
+href="http://www.ijs.si/software/amavisd/">Amavisd-new</a>, <a
+href="http://spamassassin.apache.org/">SpamAssassin</a>, and <a
+href="MILTER_README.html">Milter applications</a>. </p>
+
+</ul>
+
+<p> Each layer reduces the spam volume. The general strategy is to
+use the less expensive defenses first, and to use the more expensive
+defenses only for the spam that remains. </p>
+
+<p> Topics in this document: </p>
+
+<ul>
+
+<li> <a href="#intro">Introduction</a>
+
+<li> <a href="#basic">The basic idea behind postscreen(8)</a>
+
+<li> <a href="#general"> General operation </a>
+
+<li> <a href="#quick">Quick tests before everything else</a>
+
+<li> <a href="#before_220"> Tests before the 220 SMTP server greeting </a>
+
+<li> <a href="#after_220">Tests after the 220 SMTP server greeting</a>
+
+<li> <a href="#other_error">Other errors</a>
+
+<li> <a href="#victory">When all tests succeed</a>
+
+<li> <a href="#config"> Configuring the postscreen(8) service</a>
+
+<li> <a href="#historical"> Historical notes and credits </a>
+
+</ul>
+
+<h2> <a name="basic">The basic idea behind postscreen(8)</a> </h2>
+
+<p> Most email is spam, and most spam is sent out by zombies (malware
+on compromised end-user computers). Wietse expects that the zombie
+problem will get worse before things improve, if ever. Without a
+tool like postscreen(8) that keeps the zombies away, Postfix would be
+spending most of its resources not receiving email. </p>
+
+<p> The main challenge for postscreen(8) is to make an is-a-zombie
+decision based on a single measurement. This is necessary because
+many zombies try to fly under the radar and avoid spamming the same
+site repeatedly. Once postscreen(8) decides that a client is
+not-a-zombie, it allowlists the client temporarily to avoid further
+delays for legitimate mail. </p>
+
+<p> Zombies have challenges too: they have only a limited amount
+of time to deliver spam before their IP address becomes denylisted.
+To speed up spam deliveries, zombies make compromises in their SMTP
+protocol implementation. For example, they speak before their turn,
+or they ignore responses from SMTP servers and continue sending
+mail even when the server tells them to go away. </p>
+
+<p> postscreen(8) uses a variety of measurements to recognize
+zombies. First, postscreen(8) determines if the remote SMTP client
+IP address is denylisted. Second, postscreen(8) looks for protocol
+compromises that are made to speed up delivery. These are good
+indicators for making is-a-zombie decisions based on single
+measurements. </p>
+
+<p> postscreen(8) does not inspect message content. Message content
+can vary from one delivery to the next, especially with clients
+that (also) send legitimate email. Content is not a good indicator
+for making is-a-zombie decisions based on single measurements,
+and that is the problem that postscreen(8) is focused on. </p>
+
+<h2> <a name="general"> General operation </a> </h2>
+
+<p> For each connection from an SMTP client, postscreen(8) performs
+a number of tests
+in the order as described below. Some tests introduce a delay of
+a few seconds. postscreen(8) maintains a temporary allowlist for
+clients that pass its tests; by allowing allowlisted clients to
+skip tests, postscreen(8) minimizes its impact on legitimate email
+traffic. </p>
+
+<p> By default, postscreen(8) hands off all connections to a Postfix
+SMTP server process after logging its findings. This mode is useful
+for non-destructive testing. </p>
+
+<p> In a typical production setting, postscreen(8) is configured
+to reject mail from clients that fail one or more tests, after
+logging the helo, sender and recipient information. </p>
+
+<p> Note: postscreen(8) is not an SMTP proxy; this is intentional.
+The purpose is to keep zombies away from Postfix, with minimal
+overhead for legitimate clients. </p>
+
+<h2> <a name="quick">Quick tests before everything else</a> </h2>
+
+<p> Before engaging in SMTP-level tests. postscreen(8) queries a
+number of local deny and allowlists. These tests speed up the
+handling of known clients. </p>
+
+<ul>
+
+<li> <a href="#perm_allow_deny"> Permanent allow/denylist test </a>
+
+<li> <a href="#temp_allow"> Temporary allowlist test </a>
+
+<li> <a href="#allow_veto"> MX Policy test </a>
+
+</ul>
+
+<h3> <a name="perm_allow_deny"> Permanent allow/denylist test </a> </h3>
+
+<p> The postscreen_access_list parameter (default: permit_mynetworks)
+specifies a permanent access list for SMTP client IP addresses. Typically
+one would specify something that allowlists local networks, followed
+by a CIDR table for selective allow- and denylisting. </p>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_access_list = permit_mynetworks,
+ cidr:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+ # Rules are evaluated in the order as specified.
+ # Denylist 192.168.* except 192.168.0.1.
+ 192.168.0.1 permit
+ 192.168.0.0/16 reject
+</pre>
+
+<p> See the postscreen_access_list manpage documentation for more
+details. </p>
+
+<p> When the SMTP client address matches a "permit" action,
+postscreen(8) logs this with the client address and port number as:
+</p>
+
+<blockquote>
+<pre>
+<b>ALLOWLISTED</b> <i>[address]:port</i>
+</pre>
+</blockquote>
+
+<blockquote> <p> Use the respectful_logging configuration parameter to
+select a deprecated form of this logging. </p> </blockquote>
+
+<p> The allowlist action is not configurable: immediately hand off the
+connection to a Postfix SMTP server process. </p>
+
+<p> When the SMTP client address matches a "reject" action,
+postscreen(8) logs this with the client address and port number as:
+</p>
+
+<blockquote>
+<pre>
+<b>DENYLISTED</b> <i>[address]:port</i>
+</pre>
+</blockquote>
+
+<blockquote> <p> Use the respectful_logging configuration parameter to
+select a deprecated form of this logging. </p> </blockquote>
+
+<p> The postscreen_denylist_action parameter specifies the action
+that is taken next. See "<a href="#fail_before_220">When tests
+fail before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="temp_allow"> Temporary allowlist test </a> </h3>
+
+<p> The postscreen(8) daemon maintains a <i>temporary</i>
+allowlist for SMTP client IP addresses that have passed all
+the tests described below. The postscreen_cache_map parameter
+specifies the location of the temporary allowlist. The
+temporary allowlist is not used for SMTP client addresses
+that appear on the <i>permanent</i> access list. </p>
+
+<p> By default the temporary allowlist is not shared with other
+postscreen(8) daemons. See
+<a href="#temp_allow_sharing"> Sharing
+the temporary allowlist </a> below for alternatives. </p>
+
+<p> When the SMTP client address appears on the temporary
+allowlist, postscreen(8) logs this with the client address and port
+number as: </p>
+
+<pre>
+ <b>PASS OLD</b> <i>[address]:port</i>
+</pre>
+
+<p> The action is not configurable: immediately hand off the
+connection to a Postfix SMTP server process. The client is
+excluded from further tests until its temporary allowlist
+entry expires, as controlled with the postscreen_*_ttl
+parameters. Expired entries are silently renewed if possible. </p>
+
+<h3> <a name="allow_veto"> MX Policy test </a> </h3>
+
+<p> When the remote SMTP client is not on the static access list
+or temporary allowlist, postscreen(8) can implement a number of
+allowlist tests, before it grants the client a temporary allowlist
+status that allows it to talk to a Postfix SMTP server process. </p>
+
+<p> When postscreen(8) is configured to monitor all primary and
+backup MX addresses, it can refuse to allowlist clients that connect
+to a backup MX address only (an old spammer trick to take advantage
+of backup MX hosts with weaker anti-spam policies than primary MX
+hosts). </p>
+
+<blockquote> <p> NOTE: The following solution is for small sites.
+Larger sites would have to share the postscreen(8) cache between
+primary and backup MTAs, which would introduce a common point of
+failure. </p> </blockquote>
+
+<ul>
+
+<li> <p> First, configure the host to listen on both primary and
+backup MX addresses. Use the appropriate <tt>ifconfig</tt> or <tt>ip</tt>
+command for the local operating system, or update the appropriate
+configuration files and "refresh" the network protocol stack. </p>
+
+<p> <p> Second, configure Postfix to listen on the new IP address
+(this step is needed when you have specified inet_interfaces in
+main.cf). </p>
+
+<li> <p> Then, configure postscreen(8) to deny the temporary allowlist
+status on the backup MX address(es). An example for Wietse's
+server is: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_allowlist_interfaces = !168.100.189.8 static:all
+</pre>
+
+<p> Translation: allow clients to obtain the temporary allowlist
+status on all server IP addresses except 168.100.189.8, which is a
+backup MX address. </p>
+
+</ul>
+
+<p> When a non-allowlisted client connects the backup MX address,
+postscreen(8) logs this with the client address and port number as:
+</p>
+
+<blockquote> <pre>
+<b>CONNECT from</b> <i>[address]:port</i> <b>to [168.100.189.8]:25</b>
+<b>ALLOWLIST VETO</b> <i>[address]:port</i>
+</pre> </blockquote>
+
+<blockquote> <p> Use the respectful_logging configuration parameter to
+select a deprecated form of this logging. </p> </blockquote>
+
+<p> Translation: the client at <i>[address]:port</i> connected to
+the backup MX address 168.100.189.8 while it was not allowlisted.
+The client will not be granted the temporary allowlist status, even
+if passes all the allowlist tests described below. </p>
+
+<h2> <a name="before_220"> Tests before the 220 SMTP server greeting </a> </h2>
+
+<p> The postscreen_greet_wait parameter specifies a short time
+interval before the "220 <i>text</i>..." server greeting, where
+postscreen(8) can run a number of tests in parallel. </p>
+
+<p> When a good client passes these tests, and no "<a
+href="#after_220">deep protocol tests</a>"
+are configured, postscreen(8)
+adds the client to the temporary allowlist and hands off the "live"
+connection to a Postfix SMTP server process. The client can then
+continue as if postscreen(8) never even existed (except of course
+for the short postscreen_greet_wait delay). </p>
+
+<ul>
+
+<li> <a href="#pregreet"> Pregreet test </a>
+
+<li> <a href="#dnsbl"> DNS Allow/denylist test </a>
+
+<li> <a href="#fail_before_220">When tests fail before the 220 SMTP server greeting</a>
+
+</ul>
+
+<h3> <a name="pregreet"> Pregreet test </a> </h3>
+
+<p> The SMTP protocol is a classic example of a protocol where the
+server speaks before the client. postscreen(8) detects zombies
+that are in a hurry and that speak before their turn. This test is
+enabled by default. </p>
+
+<p> The postscreen_greet_banner parameter specifies the <i>text</i>
+portion of a "220-<i>text</i>..." teaser banner (default: $smtpd_banner).
+Note that this becomes the first part of a multi-line server greeting.
+The postscreen(8) daemon sends this before the postscreen_greet_wait
+timer is started. The purpose of the teaser banner is to confuse
+zombies so that they speak before their turn. It has no effect on
+SMTP clients that correctly implement the protocol. </p>
+
+<p> To avoid problems with poorly-implemented SMTP engines in network
+appliances or network testing tools, either exclude them from all
+tests with the postscreen_access_list feature or else specify
+an empty teaser banner: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Exclude broken clients by allowlisting. Clients in mynetworks
+ # should always be allowlisted.
+ postscreen_access_list = permit_mynetworks,
+ cidr:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+ 192.168.254.0/24 permit
+</pre>
+
+<pre>
+/etc/postfix/main.cf:
+ # Disable the teaser banner (try allowlisting first if you can).
+ postscreen_greet_banner =
+</pre>
+
+<p> When an SMTP client sends a command before the
+postscreen_greet_wait time has elapsed, postscreen(8) logs this as:
+</p>
+
+<pre>
+ <b>PREGREET</b> <i>count</i> <b>after</b> <i>time</i> <b>from</b> <i>[address]:port text...</i>
+</pre>
+
+<p> Translation: the client at <i>[address]:port</i> sent <i>count</i>
+bytes before its turn to speak. This happened <i>time</i> seconds
+after the postscreen_greet_wait timer was started. The <i>text</i>
+is what the client sent (truncated to 100 bytes, and with non-printable
+characters replaced with C-style escapes such as \r for carriage-return
+and \n for newline). </p>
+
+<p> The postscreen_greet_action parameter specifies the action that
+is taken next. See "<a href="#fail_before_220">When tests fail
+before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="dnsbl"> DNS Allow/denylist test </a> </h3>
+
+<p> The postscreen_dnsbl_sites parameter (default: empty) specifies
+a list of DNS blocklist servers with optional filters and weight
+factors (positive weights for denylisting, negative for allowlisting).
+These servers will be queried in parallel with the reverse client
+IP address. This test is disabled by default. </p>
+
+<blockquote>
+<p>
+CAUTION: when postscreen rejects mail, its SMTP reply contains the
+DNSBL domain name. Use the postscreen_dnsbl_reply_map feature to
+hide "password" information in DNSBL domain names.
+</p>
+</blockquote>
+
+<p> When the postscreen_greet_wait time has elapsed, and the combined
+DNSBL score is equal to or greater than the postscreen_dnsbl_threshold
+parameter value, postscreen(8) logs this as: </p>
+
+<pre>
+ <b>DNSBL rank</b> <i>count</i> <b>for</b> <i>[address]:port</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> has a combined
+DNSBL score of <i>count</i>. </p>
+
+<p> The postscreen_dnsbl_action parameter specifies the action that
+is taken when the combined DNSBL score is equal to or greater than
+the threshold. See "<a href="#fail_before_220">When tests fail
+before the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="fail_before_220">When tests fail before the 220 SMTP server greeting</a> </h3>
+
+<p> When the client address matches the permanent denylist, or
+when the client fails the pregreet or DNSBL tests, the action is
+specified with postscreen_denylist_action, postscreen_greet_action,
+or postscreen_dnsbl_action, respectively. </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default) </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Repeat this test the next time the client connects. This option
+is useful for testing and collecting statistics without blocking
+mail. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. </dd>
+
+</dl>
+
+<h2> <a name="after_220">Tests after the 220 SMTP server greeting</a> </h2>
+
+<p> In this phase of the protocol, postscreen(8) implements a
+number of "deep protocol" tests. These tests use an SMTP protocol
+engine that is built into the postscreen(8) server. </p>
+
+<p> Important note: these protocol tests are disabled by default.
+They are more intrusive than the pregreet and DNSBL tests, and they
+have limitations as discussed next. </p>
+
+<ul>
+
+<li> <p> The main limitation of "after 220 greeting" tests is that
+a new client must disconnect after passing these tests (reason:
+postscreen is not a proxy). Then the client must reconnect from
+the same IP address before it can deliver mail. The following
+measures may help to avoid email delays: </p>
+
+<ul>
+
+<li> <p> Allow "good" clients to skip tests with the
+postscreen_dnsbl_allowlist_threshold feature. This is especially effective
+for large providers that usually don't retry from the same IP
+address. </p>
+
+<li> <p> Small sites: Configure postscreen(8) to listen on multiple
+IP addresses, published in DNS as different IP addresses for the
+same MX hostname or for different MX hostnames. This avoids mail
+delivery delays with clients that reconnect immediately from the
+same IP address. </p>
+
+<li> <p> Large sites: Share the postscreen(8) cache between different
+Postfix MTAs with a large-enough memcache_table(5). Again, this
+avoids mail delivery delays with clients that reconnect immediately
+from the same IP address. </p>
+
+</ul>
+
+<li> <p> postscreen(8)'s built-in SMTP engine does not implement the
+AUTH, XCLIENT, and XFORWARD features. If you need to make these
+services available on port 25, then do not enable the tests after
+the 220 server greeting. </p>
+
+<li> <p> End-user clients should connect directly to the submission
+service, so that they never have to deal with postscreen(8)'s tests.
+</p>
+
+</ul>
+
+<p> The following "after 220 greeting" tests are available: </p>
+
+<ul>
+
+<li> <a href="#pipelining">Command pipelining test</a>
+
+<li> <a href="#non_smtp">Non-SMTP command test</a>
+
+<li> <a href="#barelf">Bare newline test</a>
+
+<li> <a href="#fail_after_220">When tests fail after the 220 SMTP server greeting</a>
+
+</ul>
+
+<h3> <a name="pipelining">Command pipelining test</a> </h3>
+
+<p> By default, SMTP is a half-duplex protocol: the sender and
+receiver send one command and one response at a time. Unlike the
+Postfix SMTP server, postscreen(8) does not announce support
+for ESMTP command pipelining. Therefore, clients are not allowed
+to send multiple commands. postscreen(8)'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "postscreen_pipelining_enable = yes", postscreen(8) detects
+zombies that send multiple commands, instead of sending one command
+and waiting for the server to reply. </p>
+
+<p> This test is opportunistically enabled when postscreen(8) has
+to use the built-in SMTP engine anyway. This is to make postscreen(8)
+logging more informative. </p>
+
+<p> When a client sends multiple commands, postscreen(8) logs this
+as: </p>
+
+<pre>
+ <b>COMMAND PIPELINING from</b> <i>[address]:port</i> <b>after</b> <i>command</i>: <i>text</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent
+multiple SMTP commands, instead of sending one command and then
+waiting for the server to reply. This happened after the client
+sent <i>command</i>. The <i>text</i> shows part of the input that
+was sent too early; it is not logged with Postfix 2.8. </p>
+
+<p> The postscreen_pipelining_action parameter specifies the action
+that is taken next. See "<a href="#fail_after_220">When tests fail
+after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="non_smtp">Non-SMTP command test</a> </h3>
+
+<p> Some spambots send their mail through open proxies. A symptom
+of this is the usage of commands such as CONNECT and other non-SMTP
+commands. Just like the Postfix SMTP server's smtpd_forbidden_commands
+feature, postscreen(8) has an equivalent postscreen_forbidden_commands
+feature to block these clients. postscreen(8)'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "postscreen_non_smtp_command_enable = yes", postscreen(8)
+detects zombies that send commands specified with the
+postscreen_forbidden_commands parameter. This also detects commands
+with the syntax of a message header label. The latter is a symptom
+that the client is sending message content after ignoring all the
+responses from postscreen(8) that reject mail. </p>
+
+<p> This test is opportunistically enabled when postscreen(8) has
+to use the built-in SMTP engine anyway. This is to make postscreen(8)
+logging more informative. </p>
+
+<p> When a client sends non-SMTP commands, postscreen(8) logs this
+as: </p>
+
+<pre>
+ <b>NON-SMTP COMMAND from</b> <i>[address]:port</i> <b>after</b> <i>command: text</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a
+command that matches the postscreen_forbidden_commands
+parameter, or that has the syntax of a message header label (text
+followed by optional space and ":").
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> The postscreen_non_smtp_command_action parameter specifies
+the action that is taken next. See "<a href="#fail_after_220">When
+tests fail after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="barelf">Bare newline test</a> </h3>
+
+<p> SMTP is a line-oriented protocol: lines have a limited length,
+and are terminated with &lt;CR&gt;&lt;LF&gt;. Lines ending in a
+"bare" &lt;LF&gt;, that is newline not preceded by carriage return,
+are not allowed in SMTP. postscreen(8)'s
+<a href="#after_220">deep
+protocol test</a> for this is disabled by default. </p>
+
+<p> With "postscreen_bare_newline_enable = yes", postscreen(8)
+detects clients that send lines ending in bare newline characters.
+</p>
+
+<p> This test is opportunistically enabled when postscreen(8) has
+to use the built-in SMTP engine anyway. This is to make postscreen(8)
+logging more informative. </p>
+
+<p> When a client sends bare newline characters, postscreen(8) logs
+this as:
+</p>
+
+<pre>
+ <b>BARE NEWLINE from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> sent a bare
+newline character, that is newline not preceded by carriage
+return.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> The postscreen_bare_newline_action parameter specifies the
+action that is taken next. See "<a href="#fail_after_220">When
+tests fail after the 220 SMTP server greeting</a>" below. </p>
+
+<h3> <a name="fail_after_220">When tests fail after the 220 SMTP server greeting</a> </h3>
+
+<p> When the client fails the pipelining, non-SMTP command or bare
+newline tests, the action is specified with postscreen_pipelining_action,
+postscreen_non_smtp_command_action or postscreen_bare_newline_action,
+respectively. </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default for bare newline) </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Do NOT repeat this test before the result from some other test
+expires.
+
+This option is useful for testing and collecting statistics without
+blocking mail permanently. </dd>
+
+<dt> <b>enforce</b> (default for pipelining) </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver
+mail with a 550 SMTP reply, and log the helo/sender/recipient
+information. Repeat this test the next time the client connects.
+</dd>
+
+<dt> <b>drop</b> (default for non-SMTP commands) </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. This action is
+compatible with the Postfix SMTP server's smtpd_forbidden_commands
+feature. </dd>
+
+</dl>
+
+<h2> <a name="other_error">Other errors</a> </h2>
+
+<p> When an SMTP client hangs up unexpectedly, postscreen(8) logs
+this as: </p>
+
+<pre>
+ <b>HANGUP after</b> <i>time</i> <b>from</b> <i>[address]:port</i> <b>in</b> <i>test name</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> disconnected
+unexpectedly, <i>time</i> seconds after the start of the
+test named <i>test name</i>. </p>
+
+<p> There is no punishment for hanging up. A client that hangs up
+without sending the QUIT command can still pass all postscreen(8)
+tests. </p>
+
+<!--
+
+<p> While an unexpired penalty is in effect, an SMTP client is not
+allowed to pass any tests, and postscreen(8) logs each connection
+with the remaining amount of penalty time as: </p>
+
+<pre>
+ <b>PENALTY</b> <i>time</i> <b>for</b> <i>[address]:port</i>
+</pre>
+
+<p> During this time, all attempts by the client to deliver mail
+will be deferred with a 450 SMTP status. </p>
+
+-->
+
+<p> The following errors are reported by the built-in SMTP engine.
+This engine never accepts mail, therefore it has per-session limits
+on the number of commands and on the session length. </p>
+
+<pre>
+ <b>COMMAND TIME LIMIT</b> <b>from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-command time limit as specified with the postscreen_command_time_limit
+parameter. The session is terminated immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<pre>
+ <b>COMMAND COUNT LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-session command count limit as specified with the
+postscreen_command_count_limit parameter. The session is terminated
+immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<pre>
+ <b>COMMAND LENGTH LIMIT from</b> <i>[address]:port</i> <b>after</b> <i>command</i>
+</pre>
+
+<p> Translation: the SMTP client at <i>[address]:port</i> reached the
+per-command length limit, as specified with the line_length_limit
+parameter. The session is terminated immediately.
+The "<tt><b>after</b> <i>command</i></tt>" portion is logged with
+Postfix 2.10 and later. </p>
+
+<p> When an SMTP client makes too many connections at the same time,
+postscreen(8) rejects the connection with a 421 status code and logs: </p>
+
+<pre>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: too many connections</b>
+</pre>
+
+<p> The postscreen_client_connection_count_limit parameter controls this limit. </p>
+
+<p> When an SMTP client connects after postscreen(8) has reached a
+connection count limit, postscreen(8) rejects the connection with
+a 421 status code and logs: </p>
+
+<pre>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all screening ports busy</b>
+ <b>NOQUEUE: reject: CONNECT from</b> <i>[address]:port</i><b>: all server ports busy</b>
+</pre>
+
+<p> The postscreen_pre_queue_limit and postscreen_post_queue_limit
+parameters control these limits. </p>
+
+<h2> <a name="victory">When all tests succeed</a> </h2>
+
+<p> When a new SMTP client passes all tests (i.e. it is not allowlisted
+via some mechanism), postscreen(8) logs this as: </p>
+
+<pre>
+ <b>PASS NEW</b> <i>[address]:port</i>
+</pre>
+
+<p> Where <i>[address]:port</i> are the client IP address and port.
+Then, postscreen(8)
+creates a temporary allowlist entry that excludes the client IP
+address from further tests until the temporary allowlist entry
+expires, as controlled with the postscreen_*_ttl parameters. </p>
+
+<p> When no "<a href="#after_220">deep protocol tests</a>" are
+configured, postscreen(8) hands off the "live" connection to a Postfix
+SMTP server process. The client can then continue as if postscreen(8)
+never even existed (except for the short postscreen_greet_wait delay).
+</p>
+
+<p> When any "<a href="#after_220">deep protocol tests</a>" are
+configured, postscreen(8) cannot hand off the "live" connection to
+a Postfix SMTP server process in the middle of the session. Instead,
+postscreen(8) defers mail delivery attempts with a 4XX status, logs
+the helo/sender/recipient information, and waits for the client to
+disconnect. The next time the client connects it will be allowed
+to talk to a Postfix SMTP server process to deliver its mail.
+postscreen(8) mitigates the impact of this limitation by giving
+<a href="#after_220">deep protocol tests</a> a long expiration
+time. </p>
+
+<h2> <a name="config"> Configuring the postscreen(8) service</a>
+</h2>
+
+<p> postscreen(8) has been tested on FreeBSD [4-8], Linux 2.[4-6]
+and Solaris 9 systems. </p>
+
+<ul>
+
+<li> <a href="#enable"> Turning on postscreen(8) without blocking
+mail</a>
+
+<li> <a href="#starttls"> postscreen(8) TLS configuration </a>
+
+<li> <a href="#blocking"> Blocking mail with postscreen(8) </a>
+
+<li> <a href="#turnoff"> Turning off postscreen(8) </a>
+
+<li> <a href="#temp_allow_sharing"> Sharing the temporary allowlist
+</a>
+
+</ul>
+
+<h3> <a name="enable"> Turning on postscreen(8) without blocking mail</a> </h3>
+
+<p> To enable the postscreen(8) service and log client information
+without blocking mail: </p>
+
+<ol>
+
+<li> <p> Make sure that local clients and systems with non-standard
+SMTP implementations are excluded from any postscreen(8) tests. The
+default is to exclude all clients in mynetworks. To exclude additional
+clients, for example, third-party performance monitoring tools (these
+tend to have broken SMTP implementations): </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Exclude broken clients by allowlisting. Clients in mynetworks
+ # should always be allowlisted.
+ postscreen_access_list = permit_mynetworks,
+ cidr:/etc/postfix/postscreen_access.cidr
+
+/etc/postfix/postscreen_access.cidr:
+ 192.168.254.0/24 permit
+</pre>
+
+<li> <p> Comment out the "<tt>smtp inet ... smtpd</tt>" service
+in master.cf, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #smtp inet n - n - - smtpd
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the new "<tt>smtpd pass ... smtpd</tt>" service
+in master.cf, and duplicate any "<tt>-o parameter=value</tt>" entries
+from the smtpd service that was commented out in the previous step.
+</p>
+
+<pre>
+/etc/postfix/master.cf:
+ smtpd pass - - n - - smtpd
+ -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the new "<tt>smtp inet ... postscreen</tt>"
+service in master.cf. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - 1 postscreen
+</pre>
+
+<li> <p> Uncomment the new "<tt>tlsproxy unix ... tlsproxy</tt>"
+service in master.cf. This service implements STARTTLS support for
+postscreen(8). </p>
+
+<pre>
+/etc/postfix/master.cf:
+ tlsproxy unix - - n - 0 tlsproxy
+</pre>
+
+<li> <p> Uncomment the new "<tt>dnsblog unix ... dnsblog</tt>"
+service in master.cf. This service does DNSBL lookups for postscreen(8)
+and logs results. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ dnsblog unix - - n - 0 dnsblog
+</pre>
+
+<li> <p> To enable DNSBL lookups, list some DNS blocklist sites in
+main.cf, separated by whitespace. Different sites can have different
+weights. For example:
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_dnsbl_threshold = 2
+ postscreen_dnsbl_sites = zen.spamhaus.org*2
+ bl.spamcop.net*1 b.barracudacentral.org*1
+</pre>
+
+<p> Note: if your DNSBL queries have a "secret" in the domain name,
+you must censor this information from the postscreen(8) SMTP replies.
+For example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply
+</pre>
+
+<pre>
+/etc/postfix/dnsbl_reply:
+ # Secret DNSBL name Name in postscreen(8) replies
+ secret.zen.dq.spamhaus.net zen.spamhaus.org
+</pre>
+
+<p> The texthash: format is similar to hash: except that there is
+no need to run postmap(1) before the file can be used, and that it
+does not detect changes after the file is read. It is new with
+Postfix version 2.8. </p>
+
+<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
+</p>
+
+</ol>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Some postscreen(8) configuration parameters implement
+stress-dependent behavior. This is supported only when the default
+value is stress-dependent (that is, "postconf -d <i>parametername</i>"
+output shows
+"<i>parametername</i>&nbsp;=&nbsp;${stress?<i>something</i>}${stress:<i>something</i>}" or
+"<i>parametername</i>&nbsp;=&nbsp;${stress?{<i>something</i>}:{<i>something</i>}}").
+Other parameters always evaluate as if the stress value is the empty
+string. </p>
+
+<li> <p> See "<a href="#before_220">Tests before the 220 SMTP server
+greeting</a>" for details about the logging from these
+postscreen(8) tests. </p>
+
+<li> <p> If you run Postfix 2.6 or earlier you must stop and start
+the master daemon ("<tt>postfix stop; postfix start</tt>"). This
+is needed because the Postfix "pass" master service type did not
+work reliably on all systems. </p>
+
+</ul>
+
+<h3> <a name="starttls"> postscreen(8) TLS configuration </a> </h3>
+
+<p> postscreen(8) TLS support is available for remote SMTP clients
+that aren't allowlisted, including clients that need to renew their
+temporary allowlist status. When a remote SMTP client requests TLS
+service, postscreen(8) invisibly hands off the connection to a
+tlsproxy(8) process. Then, tlsproxy(8) encrypts and decrypts the
+traffic between postscreen(8) and the remote SMTP client. One
+tlsproxy(8) process can handle multiple SMTP sessions. The number
+of tlsproxy(8) processes slowly increases with server load, but it
+should always be much smaller than the number of postscreen(8) TLS
+sessions. </p>
+
+<p> TLS support for postscreen(8) and tlsproxy(8) uses the same
+parameters as with smtpd(8). We recommend that you keep the relevant
+configuration parameters in main.cf. If you must specify "-o
+smtpd_mumble=value" parameter overrides in master.cf for a
+postscreen-protected smtpd(8) service, then you should specify those
+same parameter overrides for the postscreen(8) and tlsproxy(8)
+services. </p>
+
+<h3> <a name="blocking"> Blocking mail with postscreen(8) </a> </h3>
+
+<p> For compatibility with smtpd(8), postscreen(8) implements the
+soft_bounce safety feature. This causes Postfix to reject mail with
+a "try again" reply code. </p>
+
+<ul>
+
+<li> <p> To turn this on for all of Postfix, specify "<tt>soft_bounce
+= yes</tt>" in main.cf. </p>
+
+<li> <p> To turn this on for postscreen(8) only, append "<tt>-o
+soft_bounce=yes</tt>" (note: NO SPACES around '=') to the postscreen
+entry in master.cf. <p>
+
+</ul>
+
+<p> Execute "<tt>postfix reload</tt>" to make the change effective. </p>
+
+<p> After testing, do not forget to remove the soft_bounce feature,
+otherwise senders won't receive their non-delivery notification
+until many days later. </p>
+
+<p> To use the postscreen(8) service to block mail, edit main.cf and
+specify one or more of: </p>
+
+<ul>
+
+<li> <p> "<tt>postscreen_dnsbl_action = enforce</tt>", to reject
+clients that are on DNS blocklists, and to log the helo/sender/recipient
+information. With good DNSBLs this reduces the amount of load on
+Postfix SMTP servers dramatically. </p>
+
+<li> <p> "<tt>postscreen_greet_action = enforce</tt>", to reject
+clients that talk before their turn, and to log the helo/sender/recipient
+information. This stops over half of all known-to-be illegitimate
+connections to Wietse's mail server. It is backup protection for
+zombies that haven't yet been denylisted. </p>
+
+<li> <p> You can also enable "<a href="#after_220">deep protocol
+tests</a>", but these are more intrusive than the pregreet or DNSBL
+tests. </p>
+
+<p> When a good client passes the "<a href="#after_220">deep
+protocol tests</a>",
+postscreen(8) adds the client to the temporary
+allowlist but it cannot hand off the "live" connection to a Postfix
+SMTP server process in the middle of the session. Instead, postscreen(8)
+defers mail delivery attempts with a 4XX status, logs the
+helo/sender/recipient information, and waits for the client to
+disconnect. </p>
+
+<p> When the good client comes back in a later session, it is allowed
+to talk directly to a Postfix SMTP server. See "<a href="#after_220">Tests
+after the 220 SMTP server greeting</a>" above for limitations with
+AUTH and other features that clients may need. </p>
+
+<p> An unexpected benefit from "<a href="#after_220">deep protocol
+tests</a>" is that some "good" clients don't return after the 4XX
+reply; these clients were not so good after all. </p>
+
+<p> Unfortunately, some senders will retry requests from different
+IP addresses, and may never get allowlisted. For this reason,
+Wietse stopped using "<a href="#after_220">deep protocol tests</a>"
+on his own internet-facing mail server. </p>
+
+<li> <p> There is also support for permanent denylisting and
+allowlisting; see the description of the postscreen_access_list
+parameter for details. </p>
+
+</ul>
+
+<h3> <a name="turnoff"> Turning off postscreen(8) </a> </h3>
+
+<p> To turn off postscreen(8) and handle mail directly with Postfix
+SMTP server processes: </p>
+
+<ol>
+
+<li> <p> Comment out the "<tt>smtp inet ... postscreen</tt>" service
+in master.cf, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #smtp inet n - n - 1 postscreen
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Comment out the "<tt>dnsblog unix ... dnsblog</tt>" service
+in master.cf. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #dnsblog unix - - n - 0 dnsblog
+</pre>
+
+<li> <p> Comment out the "<tt>smtpd pass ... smtpd</tt>" service
+in master.cf, including any "<tt>-o parameter=value</tt>" entries
+that follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #smtpd pass - - n - - smtpd
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Comment out the "<tt>tlsproxy unix ... tlsproxy</tt>"
+service in master.cf, including any "<tt>-o parameter=value</tt>"
+entries that follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ #tlsproxy unix - - n - 0 tlsproxy
+ # -o parameter=value ...
+</pre>
+
+<li> <p> Uncomment the "<tt>smtp inet ... smtpd</tt>" service in
+master.cf, including any "<tt>-o parameter=value</tt>" entries that
+may follow. </p>
+
+<pre>
+/etc/postfix/master.cf:
+ smtp inet n - n - - smtpd
+ -o parameter=value ...
+</pre>
+
+<li> <p> Read the new configuration with "<tt>postfix reload</tt>".
+</p>
+
+</ol>
+
+<h3> <a name="temp_allow_sharing"> Sharing the temporary allowlist </a> </h3>
+
+<p> By default, the temporary allowlist is not shared between
+multiple postscreen(8) daemons. To enable sharing, choose one
+of the following options: </p>
+
+<ul>
+
+<li> <p> A non-persistent memcache: temporary allowlist can be shared
+ between postscreen(8) daemons on the same host or different
+ hosts. Disable cache cleanup (postscreen_cache_cleanup_interval
+ = 0) in all postscreen(8) daemons because memcache: has no
+ first-next API (but see example 4 below for memcache: with
+ persistent backup). This requires Postfix 2.9 or later. </p>
+
+ <pre>
+ # Example 1: non-persistent memcache: allowlist.
+ /etc/postfix/main.cf:
+ postscreen_cache_map = memcache:/etc/postfix/postscreen_cache
+ postscreen_cache_cleanup_interval = 0
+
+ /etc/postfix/postscreen_cache:
+ memcache = inet:127.0.0.1:11211
+ key_format = postscreen:%s
+ </pre>
+
+<li> <p>
+ A persistent lmdb: temporary allowlist can be shared between
+ postscreen(8) daemons that run under the same master(8) daemon,
+ or under different master(8) daemons on the same host. Disable
+ cache cleanup (postscreen_cache_cleanup_interval = 0) in all
+ postscreen(8) daemons except one that is responsible for cache
+ cleanup. This requires Postfix 2.11 or later. </p>
+
+ <pre>
+ # Example 2: persistent lmdb: allowlist.
+ /etc/postfix/main.cf:
+ postscreen_cache_map = lmdb:$data_directory/postscreen_cache
+ # See note 1 below.
+ # postscreen_cache_cleanup_interval = 0
+ </pre>
+
+<li> <p> Other kinds of persistent temporary allowlist can be shared
+ only between postscreen(8) daemons that run under the same
+ master(8) daemon. In this case, temporary allowlist access must
+ be shared through the proxymap(8) daemon. This requires Postfix
+ 2.9 or later. </p>
+
+ <pre>
+ # Example 3: proxied btree: allowlist.
+ /etc/postfix/main.cf:
+ postscreen_cache_map =
+ proxy:btree:/var/lib/postfix/postscreen_cache
+ # See note 1 below.
+ # postscreen_cache_cleanup_interval = 0
+
+ # Example 4: proxied btree: allowlist with memcache: accelerator.
+ /etc/postfix/main.cf:
+ postscreen_cache_map = memcache:/etc/postfix/postscreen_cache
+ proxy_write_maps =
+ proxy:btree:/var/lib/postfix/postscreen_cache
+ ... other proxied tables ...
+ # See note 1 below.
+ # postscreen_cache_cleanup_interval = 0
+
+ /etc/postfix/postscreen_cache:
+ # Note: the $data_directory macro is not defined in this context.
+ memcache = inet:127.0.0.1:11211
+ backup = proxy:btree:/var/lib/postfix/postscreen_cache
+ key_format = postscreen:%s
+ </pre>
+
+ <p> Note 1: disable cache cleanup (postscreen_cache_cleanup_interval
+ = 0) in all postscreen(8) daemons except one that is responsible
+ for cache cleanup. </p>
+
+ <p> Note 2: postscreen(8) cache sharing via proxymap(8) requires Postfix
+ 2.9 or later; earlier proxymap(8) implementations don't support
+ cache cleanup. </p>
+
+</ul>
+
+<h2> <a name="historical"> Historical notes and credits </a> </h2>
+
+<p> Many ideas in postscreen(8) were explored in earlier work by
+Michael Tokarev, in OpenBSD spamd, and in MailChannels Traffic
+Control. </p>
+
+<p> Wietse threw together a crude prototype with pregreet and dnsbl
+support in June 2009, because he needed something new for a Mailserver
+conference presentation in July. Ralf Hildebrandt ran this code on
+several servers to collect real-world statistics. This version used
+the dnsblog(8) ad-hoc DNS client program. </p>
+
+<p> Wietse needed new material for a LISA conference presentation
+in November 2010, so he added support for DNSBL weights and filters
+in August, followed by a major code rewrite, deep protocol tests,
+helo/sender/recipient logging, and stress-adaptive behavior in
+September. Ralf Hildebrandt ran this code on several servers to
+collect real-world statistics. This version still used the embarrassing
+dnsblog(8) ad-hoc DNS client program. </p>
+
+<p> Wietse added STARTTLS support in December 2010. This makes
+postscreen(8) usable for sites that require TLS support. The
+implementation introduces the tlsproxy(8) event-driven TLS proxy
+that decrypts/encrypts the sessions for multiple SMTP clients. </p>
+
+<p> The tlsproxy(8) implementation led to the discovery of a "new"
+class of vulnerability (<a
+href="http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2011-0411"
+>CVE-2011-0411</a>) that affected multiple implementations of SMTP,
+POP, IMAP, NNTP, and FTP over TLS. </p>
+
+<p> postscreen(8) was officially released as part of the Postfix
+2.8 stable release in January 2011.</p>
+
+<p> Noel Jones helped with the Postfix 3.6 transition towards respectful
+documentation. </p>
+
+</body>
+</html>
diff --git a/proto/QSHAPE_README.html b/proto/QSHAPE_README.html
new file mode 100644
index 0000000..6956b46
--- /dev/null
+++ b/proto/QSHAPE_README.html
@@ -0,0 +1,938 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Bottleneck Analysis</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Bottleneck Analysis</h1>
+
+<hr>
+
+<h2>Purpose of this document </h2>
+
+<p> This document is an introduction to Postfix queue congestion analysis.
+It explains how the qshape(1) program can help to track down the
+reason for queue congestion. qshape(1) is bundled with Postfix
+2.1 and later source code, under the "auxiliary" directory. This
+document describes qshape(1) as bundled with Postfix 2.4. </p>
+
+<p> This document covers the following topics: </p>
+
+<ul>
+
+<li><a href="#qshape">Introducing the qshape tool</a>
+
+<li><a href="#trouble_shooting">Trouble shooting with qshape</a>
+
+<li><a href="#healthy">Example 1: Healthy queue</a>
+
+<li><a href="#dictionary_bounce">Example 2: Deferred queue full of
+dictionary attack bounces</a></li>
+
+<li><a href="#active_congestion">Example 3: Congestion in the active
+queue</a></li>
+
+<li><a href="#backlog">Example 4: High volume destination backlog</a>
+
+<li><a href="#queues">Postfix queue directories</a>
+
+<ul>
+
+<li> <a href="#maildrop_queue"> The "maildrop" queue </a>
+
+<li> <a href="#hold_queue"> The "hold" queue </a>
+
+<li> <a href="#incoming_queue"> The "incoming" queue </a>
+
+<li> <a href="#active_queue"> The "active" queue </a>
+
+<li> <a href="#deferred_queue"> The "deferred" queue </a>
+
+</ul>
+
+<li><a href="#credits">Credits</a>
+
+</ul>
+
+<h2><a name="qshape">Introducing the qshape tool</a></h2>
+
+<p> When mail is draining slowly or the queue is unexpectedly large,
+run qshape(1) as the super-user (root) to help zero in on the problem.
+The qshape(1) program displays a tabular view of the Postfix queue
+contents. </p>
+
+<ul>
+
+<li> <p> On the horizontal axis, it displays the queue age with
+fine granularity for recent messages and (geometrically) less fine
+granularity for older messages. </p>
+
+<li> <p> The vertical axis displays the destination (or with the
+"-s" switch the sender) domain. Domains with the most messages are
+listed first. </p>
+
+</ul>
+
+<p> For example, in the output below we see the top 10 lines of
+the (mostly forged) sender domain distribution for captured spam
+in the "hold" queue: </p>
+
+<blockquote>
+<pre>
+$ qshape -s hold | head
+ T 5 10 20 40 80 160 320 640 1280 1280+
+ TOTAL 486 0 0 1 0 0 2 4 20 40 419
+ yahoo.com 14 0 0 1 0 0 0 0 1 0 12
+ extremepricecuts.net 13 0 0 0 0 0 0 0 2 0 11
+ ms35.hinet.net 12 0 0 0 0 0 0 0 0 1 11
+ winnersdaily.net 12 0 0 0 0 0 0 0 2 0 10
+ hotmail.com 11 0 0 0 0 0 0 0 0 1 10
+ worldnet.fr 6 0 0 0 0 0 0 0 0 0 6
+ ms41.hinet.net 6 0 0 0 0 0 0 0 0 0 6
+ osn.de 5 0 0 0 0 0 1 0 0 0 4
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> The "T" column shows the total (in this case sender) count
+for each domain. The columns with numbers above them, show counts
+for messages aged fewer than that many minutes, but not younger
+than the age limit for the previous column. The row labeled "TOTAL"
+shows the total count for all domains. </p>
+
+<li> <p> In this example, there are 14 messages allegedly from
+yahoo.com, 1 between 10 and 20 minutes old, 1 between 320 and 640
+minutes old and 12 older than 1280 minutes (1440 minutes in a day).
+</p>
+
+</ul>
+
+<p> When the output is a terminal intermediate results showing the top 20
+domains (-n option) are displayed after every 1000 messages (-N option)
+and the final output also shows only the top 20 domains. This makes
+qshape useful even when the "deferred" queue is very large and it may
+otherwise take prohibitively long to read the entire "deferred" queue. </p>
+
+<p> By default, qshape shows statistics for the union of both the
+"incoming" and "active" queues which are the most relevant queues to
+look at when analyzing performance. </p>
+
+<p> One can request an alternate list of queues: </p>
+
+<blockquote>
+<pre>
+$ qshape deferred
+$ qshape incoming active deferred
+</pre>
+</blockquote>
+
+<p> this will show the age distribution of the "deferred" queue or
+the union of the "incoming", "active" and "deferred" queues. </p>
+
+<p> Command line options control the number of display "buckets",
+the age limit for the smallest bucket, display of parent domain
+counts and so on. The "-h" option outputs a summary of the available
+switches. </p>
+
+<h2><a name="trouble_shooting">Trouble shooting with qshape</a>
+</h2>
+
+<p> Large numbers in the qshape output represent a large number of
+messages that are destined to (or alleged to come from) a particular
+domain. It should be possible to tell at a glance which domains
+dominate the queue sender or recipient counts, approximately when
+a burst of mail started, and when it stopped. </p>
+
+<p> The problem destinations or sender domains appear near the top
+left corner of the output table. Remember that the "active" queue
+can accommodate up to 20000 ($qmgr_message_active_limit) messages.
+To check whether this limit has been reached, use: </p>
+
+<blockquote>
+<pre>
+$ qshape -s active <i>(show sender statistics)</i>
+</pre>
+</blockquote>
+
+<p> If the total sender count is below 20000 the "active" queue is
+not yet saturated, any high volume sender domains show near the
+top of the output.
+
+<p> With oqmgr(8) the "active" queue is also limited to at most 20000
+recipient addresses ($qmgr_message_recipient_limit). To check for
+exhaustion of this limit use: </p>
+
+<blockquote>
+<pre>
+$ qshape active <i>(show recipient statistics)</i>
+</pre>
+</blockquote>
+
+<p> Having found the high volume domains, it is often useful to
+search the logs for recent messages pertaining to the domains in
+question. </p>
+
+<blockquote>
+<pre>
+# Find deliveries to example.com
+#
+$ tail -10000 /var/log/maillog |
+ egrep -i ': to=&lt;.*@example\.com&gt;,' |
+ less
+
+# Find messages from example.com
+#
+$ tail -10000 /var/log/maillog |
+ egrep -i ': from=&lt;.*@example\.com&gt;,' |
+ less
+</pre>
+</blockquote>
+
+<p> You may want to drill in on some specific queue ids: </p>
+
+<blockquote>
+<pre>
+# Find all messages for a specific queue id.
+#
+$ tail -10000 /var/log/maillog | egrep ': 2B2173FF68: '
+</pre>
+</blockquote>
+
+<p> Also look for queue manager warning messages in the log. These
+warnings can suggest strategies to reduce congestion. </p>
+
+<blockquote>
+<pre>
+$ egrep 'qmgr.*(panic|fatal|error|warning):' /var/log/maillog
+</pre>
+</blockquote>
+
+<p> When all else fails try the Postfix mailing list for help, but
+please don't forget to include the top 10 or 20 lines of qshape(1)
+output. </p>
+
+<h2><a name="healthy">Example 1: Healthy queue</a></h2>
+
+<p> When looking at just the "incoming" and "active" queues, under
+normal conditions (no congestion) the "incoming" and "active" queues
+are nearly empty. Mail leaves the system almost as quickly as it
+comes in or is deferred without congestion in the "active" queue.
+</p>
+
+<blockquote>
+<pre>
+$ qshape <i>(show "incoming" and "active" queue status)</i>
+
+ T 5 10 20 40 80 160 320 640 1280 1280+
+ TOTAL 5 0 0 0 1 0 0 0 1 1 2
+ meri.uwasa.fi 5 0 0 0 1 0 0 0 1 1 2
+</pre>
+</blockquote>
+
+<p> If one looks at the two queues separately, the "incoming" queue
+is empty or perhaps briefly has one or two messages, while the
+"active" queue holds more messages and for a somewhat longer time:
+</p>
+
+<blockquote>
+<pre>
+$ qshape incoming
+
+ T 5 10 20 40 80 160 320 640 1280 1280+
+ TOTAL 0 0 0 0 0 0 0 0 0 0 0
+
+$ qshape active
+
+ T 5 10 20 40 80 160 320 640 1280 1280+
+ TOTAL 5 0 0 0 1 0 0 0 1 1 2
+ meri.uwasa.fi 5 0 0 0 1 0 0 0 1 1 2
+</pre>
+</blockquote>
+
+<h2><a name="dictionary_bounce">Example 2: Deferred queue full of
+dictionary attack bounces</a></h2>
+
+<p> This is from a server where recipient validation is not yet
+available for some of the hosted domains. Dictionary attacks on
+the unvalidated domains result in bounce backscatter. The bounces
+dominate the queue, but with proper tuning they do not saturate the
+"incoming" or "active" queues. The high volume of deferred mail is not
+a direct cause for alarm. </p>
+
+<blockquote>
+<pre>
+$ qshape deferred | head
+
+ T 5 10 20 40 80 160 320 640 1280 1280+
+ TOTAL 2234 4 2 5 9 31 57 108 201 464 1353
+ heyhihellothere.com 207 0 0 1 1 6 6 8 25 68 92
+ pleazerzoneprod.com 105 0 0 0 0 0 0 0 5 44 56
+ groups.msn.com 63 2 1 2 4 4 14 14 14 8 0
+ orion.toppoint.de 49 0 0 0 1 0 2 4 3 16 23
+ kali.com.cn 46 0 0 0 0 1 0 2 6 12 25
+ meri.uwasa.fi 44 0 0 0 0 1 0 2 8 11 22
+ gjr.paknet.com.pk 43 1 0 0 1 1 3 3 6 12 16
+ aristotle.algonet.se 41 0 0 0 0 0 1 2 11 12 15
+</pre>
+</blockquote>
+
+<p> The domains shown are mostly bulk-mailers and all the volume
+is the tail end of the time distribution, showing that short term
+arrival rates are moderate. Larger numbers and lower message ages
+are more indicative of current trouble. Old mail still going nowhere
+is largely harmless so long as the "active" and "incoming" queues are
+short. We can also see that the groups.msn.com undeliverables are
+low rate steady stream rather than a concentrated dictionary attack
+that is now over. </p>
+
+<blockquote>
+<pre>
+$ qshape -s deferred | head
+
+ T 5 10 20 40 80 160 320 640 1280 1280+
+ TOTAL 2193 4 4 5 8 33 56 104 205 465 1309
+ MAILER-DAEMON 1709 4 4 5 8 33 55 101 198 452 849
+ example.com 263 0 0 0 0 0 0 0 0 2 261
+ example.org 209 0 0 0 0 0 1 3 6 11 188
+ example.net 6 0 0 0 0 0 0 0 0 0 6
+ example.edu 3 0 0 0 0 0 0 0 0 0 3
+ example.gov 2 0 0 0 0 0 0 0 1 0 1
+ example.mil 1 0 0 0 0 0 0 0 0 0 1
+</pre>
+</blockquote>
+
+<p> Looking at the sender distribution, we see that as expected
+most of the messages are bounces. </p>
+
+<h2><a name="active_congestion">Example 3: Congestion in the active
+queue</a></h2>
+
+<p> This example is taken from a Feb 2004 discussion on the Postfix
+Users list. Congestion was reported with the
+"active" and "incoming" queues
+large and not shrinking despite very large delivery agent
+process limits. The thread is archived at:
+http://groups.google.com/groups?threadm=c0b7js$2r65$1@FreeBSD.csie.NCTU.edu.tw
+and
+http://archives.neohapsis.com/archives/postfix/2004-02/thread.html#1371
+</p>
+
+<p> Using an older version of qshape(1) it was quickly determined
+that all the messages were for just a few destinations: </p>
+
+<blockquote>
+<pre>
+$ qshape <i>(show "incoming" and "active" queue status)</i>
+
+ T A 5 10 20 40 80 160 320 320+
+ TOTAL 11775 9996 0 0 1 1 42 94 221 1420
+ user.sourceforge.net 7678 7678 0 0 0 0 0 0 0 0
+ lists.sourceforge.net 2313 2313 0 0 0 0 0 0 0 0
+ gzd.gotdns.com 102 0 0 0 0 0 0 0 2 100
+</pre>
+</blockquote>
+
+<p> The "A" column showed the count of messages in the "active" queue,
+and the numbered columns showed totals for the "deferred" queue. At
+10000 messages (Postfix 1.x "active" queue size limit) the "active" queue
+is full. The "incoming" queue was growing rapidly. </p>
+
+<p> With the trouble destinations clearly identified, the administrator
+quickly found and fixed the problem. It is substantially harder to
+glean the same information from the logs. While a careful reading
+of mailq(1) output should yield similar results, it is much harder
+to gauge the magnitude of the problem by looking at the queue
+one message at a time. </p>
+
+<h2><a name="backlog">Example 4: High volume destination backlog</a></h2>
+
+<p> When a site you send a lot of email to is down or slow, mail
+messages will rapidly build up in the "deferred" queue, or worse, in
+the "active" queue. The qshape output will show large numbers for
+the destination domain in all age buckets that overlap the starting
+time of the problem: </p>
+
+<blockquote>
+<pre>
+$ qshape deferred | head
+
+ T 5 10 20 40 80 160 320 640 1280 1280+
+ TOTAL 5000 200 200 400 800 1600 1000 200 200 200 200
+ highvolume.com 4000 160 160 320 640 1280 1440 0 0 0 0
+ ...
+</pre>
+</blockquote>
+
+<p> Here the "highvolume.com" destination is continuing to accumulate
+deferred mail. The "incoming" and "active" queues are fine, but the
+"deferred" queue started growing some time between 1 and 2 hours ago
+and continues to grow. </p>
+
+<p> If the high volume destination is not down, but is instead
+slow, one might see similar congestion in the "active" queue.
+"Active" queue congestion is a greater cause for alarm; one might need to
+take measures to ensure that the mail is deferred instead or even
+add an access(5) rule asking the sender to try again later. </p>
+
+<p> If a high volume destination exhibits frequent bursts of consecutive
+connections refused by all MX hosts or "421 Server busy errors", it
+is possible for the queue manager to mark the destination as "dead"
+despite the transient nature of the errors. The destination will be
+retried again after the expiration of a $minimal_backoff_time timer.
+If the error bursts are frequent enough it may be that only a small
+quantity of email is delivered before the destination is again marked
+"dead". In some cases enabling static (not on demand) connection
+caching by listing the appropriate nexthop domain in a table included in
+"smtp_connection_cache_destinations" may help to reduce the error rate,
+because most messages will re-use existing connections. </p>
+
+<p> The MTA that has been observed most frequently to exhibit such
+bursts of errors is Microsoft Exchange, which refuses connections
+under load. Some proxy virus scanners in front of the Exchange
+server propagate the refused connection to the client as a "421"
+error. </p>
+
+<p> Note that it is now possible to configure Postfix to exhibit similarly
+erratic behavior by misconfiguring the anvil(8) service. Do not use
+anvil(8) for steady-state rate limiting, its purpose is (unintentional)
+DoS prevention and the rate limits set should be very generous! </p>
+
+<p> If one finds oneself needing to deliver a high volume of mail to a
+destination that exhibits frequent brief bursts of errors and connection
+caching does not solve the problem, there is a subtle workaround. </p>
+
+<ul>
+
+<li> <p> Postfix version 2.5 and later: </p>
+
+<ul>
+
+<li> <p> In master.cf set up a dedicated clone of the "smtp" transport
+for the destination in question. In the example below we will call
+it "fragile". </p>
+
+<li> <p> In master.cf configure a reasonable process limit for the
+cloned smtp transport (a number in the 10-20 range is typical). </p>
+
+<li> <p> IMPORTANT!!! In main.cf configure a large per-destination
+pseudo-cohort failure limit for the cloned smtp transport. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+ fragile_destination_concurrency_failed_cohort_limit = 100
+ fragile_destination_concurrency_limit = 20
+
+/etc/postfix/transport:
+ example.com fragile:
+
+/etc/postfix/master.cf:
+ # service type private unpriv chroot wakeup maxproc command
+ fragile unix - - n - 20 smtp
+</pre>
+
+<p> See also the documentation for
+default_destination_concurrency_failed_cohort_limit and
+default_destination_concurrency_limit. </p>
+
+</ul>
+
+<li> <p> Earlier Postfix versions: </p>
+
+<ul>
+
+<li> <p> In master.cf set up a dedicated clone of the "smtp"
+transport for the destination in question. In the example below
+we will call it "fragile". </p>
+
+<li> <p> In master.cf configure a reasonable process limit for the
+transport (a number in the 10-20 range is typical). </p>
+
+<li> <p> IMPORTANT!!! In main.cf configure a very large initial
+and destination concurrency limit for this transport (say 2000). </p>
+
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+ initial_destination_concurrency = 2000
+ fragile_destination_concurrency_limit = 2000
+
+/etc/postfix/transport:
+ example.com fragile:
+
+/etc/postfix/master.cf:
+ # service type private unpriv chroot wakeup maxproc command
+ fragile unix - - n - 20 smtp
+</pre>
+
+<p> See also the documentation for default_destination_concurrency_limit.
+</p>
+
+</ul>
+
+</ul>
+
+<p> The effect of this configuration is that up to 2000
+consecutive errors are tolerated without marking the destination
+dead, while the total concurrency remains reasonable (10-20
+processes). This trick is only for a very specialized situation:
+high volume delivery into a channel with multi-error bursts
+that is capable of high throughput, but is repeatedly throttled by
+the bursts of errors. </p>
+
+<p> When a destination is unable to handle the load even after the
+Postfix process limit is reduced to 1, a desperate measure is to
+insert brief delays between delivery attempts. </p>
+
+<ul>
+
+<li> <p> Postfix version 2.5 and later: </p>
+
+<ul>
+
+<li> <p> In master.cf set up a dedicated clone of the "smtp" transport
+for the problem destination. In the example below we call it "slow".
+</p>
+
+<li> <p> In main.cf configure a short delay between deliveries to
+the same destination. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+ slow_destination_rate_delay = 1
+ slow_destination_concurrency_failed_cohort_limit = 100
+
+/etc/postfix/transport:
+ example.com slow:
+
+/etc/postfix/master.cf:
+ # service type private unpriv chroot wakeup maxproc command
+ slow unix - - n - - smtp
+</pre>
+
+</ul>
+
+<p> See also the documentation for default_destination_rate_delay. </p>
+
+<p> This solution forces the Postfix smtp(8) client to wait for
+$slow_destination_rate_delay seconds between deliveries to the same
+destination. </p>
+
+<p> IMPORTANT!! The large slow_destination_concurrency_failed_cohort_limit
+value is needed. This prevents Postfix from deferring all mail for
+the same destination after only one connection or handshake error
+(the reason for this is that non-zero slow_destination_rate_delay
+forces a per-destination concurrency of 1). </p>
+
+<li> <p> Earlier Postfix versions: </p>
+
+<ul>
+
+<li> <p> In the transport map entry for the problem destination,
+specify a dead host as the primary nexthop. </p>
+
+<li> <p> In the master.cf entry for the transport specify the
+problem destination as the fallback_relay and specify a small
+smtp_connect_timeout value. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+
+/etc/postfix/transport:
+ example.com slow:[dead.host]
+
+/etc/postfix/master.cf:
+ # service type private unpriv chroot wakeup maxproc command
+ slow unix - - n - 1 smtp
+ -o fallback_relay=problem.example.com
+ -o smtp_connect_timeout=1
+ -o smtp_connection_cache_on_demand=no
+</pre>
+
+</ul>
+
+<p> This solution forces the Postfix smtp(8) client to wait for
+$smtp_connect_timeout seconds between deliveries. The connection
+caching feature is disabled to prevent the client from skipping
+over the dead host. </p>
+
+</ul>
+
+<h2><a name="queues">Postfix queue directories</a></h2>
+
+<p> The following sections describe Postfix queues: their purpose,
+what normal behavior looks like, and how to diagnose abnormal
+behavior. </p>
+
+<h3> <a name="maildrop_queue"> The "maildrop" queue </a> </h3>
+
+<p> Messages that have been submitted via the Postfix sendmail(1)
+command, but not yet brought into the main Postfix queue by the
+pickup(8) service, await processing in the "maildrop" queue. Messages
+can be added to the "maildrop" queue even when the Postfix system
+is not running. They will begin to be processed once Postfix is
+started. </p>
+
+<p> The "maildrop" queue is drained by the single threaded pickup(8)
+service scanning the queue directory periodically or when notified
+of new message arrival by the postdrop(1) program. The postdrop(1)
+program is a setgid helper that allows the unprivileged Postfix
+sendmail(1) program to inject mail into the "maildrop" queue and
+to notify the pickup(8) service of its arrival. </p>
+
+<p> All mail that enters the main Postfix queue does so via the
+cleanup(8) service. The cleanup service is responsible for envelope
+and header rewriting, header and body regular expression checks,
+automatic bcc recipient processing, milter content processing, and
+reliable insertion of the message into the Postfix "incoming" queue. </p>
+
+<p> In the absence of excessive CPU consumption in cleanup(8) header
+or body regular expression checks or other software consuming all
+available CPU resources, Postfix performance is disk I/O bound.
+The rate at which the pickup(8) service can inject messages into
+the queue is largely determined by disk access times, since the
+cleanup(8) service must commit the message to stable storage before
+returning success. The same is true of the postdrop(1) program
+writing the message to the "maildrop" directory. </p>
+
+<p> As the pickup service is single threaded, it can only deliver
+one message at a time at a rate that does not exceed the reciprocal
+disk I/O latency (+ CPU if not negligible) of the cleanup service.
+</p>
+
+<p> Congestion in this queue is indicative of an excessive local message
+submission rate or perhaps excessive CPU consumption in the cleanup(8)
+service due to excessive body_checks, or (Postfix &ge; 2.3) high latency
+milters. </p>
+
+<p> Note, that once the "active" queue is full, the cleanup service
+will attempt to slow down message injection by pausing $in_flow_delay
+for each message. In this case "maildrop" queue congestion may be
+a consequence of congestion downstream, rather than a problem in
+its own right. </p>
+
+<p> Note, you should not attempt to deliver large volumes of mail via
+the pickup(8) service. High volume sites should avoid using "simple"
+content filters that re-inject scanned mail via Postfix sendmail(1)
+and postdrop(1). </p>
+
+<p> A high arrival rate of locally submitted mail may be an indication
+of an uncaught forwarding loop, or a run-away notification program.
+Try to keep the volume of local mail injection to a moderate level.
+</p>
+
+<p> The "postsuper -r" command can place selected messages into
+the "maildrop" queue for reprocessing. This is most useful for
+resetting any stale content_filter settings. Requeuing a large number
+of messages using "postsuper -r" can clearly cause a spike in the
+size of the "maildrop" queue. </p>
+
+<h3> <a name="hold_queue"> The "hold" queue </a> </h3>
+
+<p> The administrator can define "smtpd" access(5) policies, or
+cleanup(8) header/body checks that cause messages to be automatically
+diverted from normal processing and placed indefinitely in the
+"hold" queue. Messages placed in the "hold" queue stay there until
+the administrator intervenes. No periodic delivery attempts are
+made for messages in the "hold" queue. The postsuper(1) command
+can be used to manually release messages into the "deferred" queue.
+</p>
+
+<p> Messages can potentially stay in the "hold" queue longer than
+$maximal_queue_lifetime. If such "old" messages need to be released from
+the "hold" queue, they should typically be moved into the "maildrop" queue
+using "postsuper -r", so that the message gets a new timestamp and
+is given more than one opportunity to be delivered. Messages that are
+"young" can be moved directly into the "deferred" queue using
+"postsuper -H". </p>
+
+<p> The "hold" queue plays little role in Postfix performance, and
+monitoring of the "hold" queue is typically more closely motivated
+by tracking spam and malware, than by performance issues. </p>
+
+<h3> <a name="incoming_queue"> The "incoming" queue </a> </h3>
+
+<p> All new mail entering the Postfix queue is written by the
+cleanup(8) service into the "incoming" queue. New queue files are
+created owned by the "postfix" user with an access bitmask (or
+mode) of 0600. Once a queue file is ready for further processing
+the cleanup(8) service changes the queue file mode to 0700 and
+notifies the queue manager of new mail arrival. The queue manager
+ignores incomplete queue files whose mode is 0600, as these are
+still being written by cleanup. </p>
+
+<p> The queue manager scans the "incoming" queue bringing any new
+mail into the "active" queue if the "active" queue resource limits
+have not been exceeded. By default, the "active" queue accommodates
+at most 20000 messages. Once the "active" queue message limit is
+reached, the queue manager stops scanning the "incoming" queue
+(and the "deferred" queue, see below). </p>
+
+<p> Under normal conditions the "incoming" queue is nearly empty (has
+only mode 0600 files), with the queue manager able to import new
+messages into the "active" queue as soon as they become available.
+</p>
+
+<p> The "incoming" queue grows when the message input rate spikes
+above the rate at which the queue manager can import messages into
+the "active" queue. The main factors slowing down the queue manager
+are disk I/O and lookup queries to the trivial-rewrite service. If the queue
+manager is routinely not keeping up, consider not using "slow"
+lookup services (MySQL, LDAP, ...) for transport lookups or speeding
+up the hosts that provide the lookup service. If the problem is I/O
+starvation, consider striping the queue over more disks, faster controllers
+with a battery write cache, or other hardware improvements. At the very
+least, make sure that the queue directory is mounted with the "noatime"
+option if applicable to the underlying filesystem. </p>
+
+<p> The in_flow_delay parameter is used to clamp the input rate
+when the queue manager starts to fall behind. The cleanup(8) service
+will pause for $in_flow_delay seconds before creating a new queue
+file if it cannot obtain a "token" from the queue manager. </p>
+
+<p> Since the number of cleanup(8) processes is limited in most
+cases by the SMTP server concurrency, the input rate can exceed
+the output rate by at most "SMTP connection count" / $in_flow_delay
+messages per second. </p>
+
+<p> With a default process limit of 100, and an in_flow_delay of
+1s, the coupling is strong enough to limit a single run-away injector
+to 1 message per second, but is not strong enough to deflect an
+excessive input rate from many sources at the same time. </p>
+
+<p> If a server is being hammered from multiple directions, consider
+raising the in_flow_delay to 10 seconds, but only if the "incoming" queue
+is growing even while the "active" queue is not full and the
+trivial-rewrite service is using a fast transport lookup mechanism.
+</p>
+
+<h3> <a name="active_queue"> The "active" queue </a> </h3>
+
+<p> The queue manager is a delivery agent scheduler; it works to
+ensure fast and fair delivery of mail to all destinations within
+designated resource limits. </p>
+
+<p> The "active" queue is somewhat analogous to an operating system's
+process run queue. Messages in the "active" queue are ready to be
+sent (runnable), but are not necessarily in the process of being
+sent (running). </p>
+
+<p> While most Postfix administrators think of the "active" queue
+as a directory on disk, the real "active" queue is a set of data
+structures in the memory of the queue manager process. </p>
+
+<p> Messages in the "maildrop", "hold", "incoming" and "deferred" queues
+(see below) do not occupy memory; they are safely stored on
+disk waiting for their turn to be processed. The envelope information
+for messages in the "active" queue is managed in memory, allowing
+the queue manager to do global scheduling, allocating available
+delivery agent processes to an appropriate message in the "active" queue. </p>
+
+<p> Within the "active" queue, (multi-recipient) messages are broken
+up into groups of recipients that share the same transport/nexthop
+combination; the group size is capped by the transport's recipient
+concurrency limit. </p>
+
+<p> Multiple recipient groups (from one or more messages) are queued
+for delivery grouped by transport/nexthop combination. The
+<b>destination</b> concurrency limit for the transports caps the number
+of simultaneous delivery attempts for each nexthop. Transports with
+a <b>recipient</b> concurrency limit of 1 are special: these are grouped
+by the actual recipient address rather than the nexthop, yielding
+per-recipient concurrency limits rather than per-domain
+concurrency limits. Per-recipient limits are appropriate when
+performing final delivery to mailboxes rather than when relaying
+to a remote server. </p>
+
+<p> Congestion occurs in the "active" queue when one or more destinations
+drain slower than the corresponding message input rate. </p>
+
+<p> Input into the "active" queue comes both from new mail in the "incoming" queue,
+and retries of mail in the "deferred" queue. Should the "deferred" queue
+get really large, retries of old mail can dominate the arrival
+rate of new mail. Systems with more CPU, faster disks and more network
+bandwidth can deal with larger "deferred" queues, but as a rule of thumb
+the "deferred" queue scales to somewhere between 100,000 and 1,000,000
+messages with good performance unlikely above that "limit". Systems with
+queues this large should typically stop accepting new mail, or put the
+backlog "on hold" until the underlying issue is fixed (provided that
+there is enough capacity to handle just the new mail). </p>
+
+<p> When a destination is down for some time, the queue manager will
+mark it dead, and immediately defer all mail for the destination without
+trying to assign it to a delivery agent. In this case the messages
+will quickly leave the "active" queue and end up in the "deferred" queue
+(with Postfix &lt; 2.4, this is done directly by the queue manager,
+with Postfix &ge; 2.4 this is done via the "retry" delivery agent). </p>
+
+<p> When the destination is instead simply slow, or there is a problem
+causing an excessive arrival rate the "active" queue will grow and will
+become dominated by mail to the congested destination. </p>
+
+<p> The only way to reduce congestion is to either reduce the input
+rate or increase the throughput. Increasing the throughput requires
+either increasing the concurrency or reducing the latency of
+deliveries. </p>
+
+<p> For high volume sites a key tuning parameter is the number of
+"smtp" delivery agents allocated to the "smtp" and "relay" transports.
+High volume sites tend to send to many different destinations, many
+of which may be down or slow, so a good fraction of the available
+delivery agents will be blocked waiting for slow sites. Also mail
+destined across the globe will incur large SMTP command-response
+latencies, so high message throughput can only be achieved with
+more concurrent delivery agents. </p>
+
+<p> The default "smtp" process limit of 100 is good enough for most
+sites, and may even need to be lowered for sites with low bandwidth
+connections (no use increasing concurrency once the network pipe
+is full). When one finds that the queue is growing on an "idle"
+system (CPU, disk I/O and network not exhausted) the remaining
+reason for congestion is insufficient concurrency in the face of
+a high average latency. If the number of outbound SMTP connections
+(either ESTABLISHED or SYN_SENT) reaches the process limit, mail
+is draining slowly and the system and network are not loaded, raise
+the "smtp" and/or "relay" process limits! </p>
+
+<p> When a high volume destination is served by multiple MX hosts with
+typically low delivery latency, performance can suffer dramatically when
+one of the MX hosts is unresponsive and SMTP connections to that host
+timeout. For example, if there are 2 equal weight MX hosts, the SMTP
+connection timeout is 30 seconds and one of the MX hosts is down, the
+average SMTP connection will take approximately 15 seconds to complete.
+With a default per-destination concurrency limit of 20 connections,
+throughput falls to just over 1 message per second. </p>
+
+<p> The best way to avoid bottlenecks when one or more MX hosts is
+non-responsive is to use connection caching. Connection caching was
+introduced with Postfix 2.2 and is by default enabled on demand for
+destinations with a backlog of mail in the "active" queue. When connection
+caching is in effect for a particular destination, established connections
+are re-used to send additional messages, this reduces the number of
+connections made per message delivery and maintains good throughput even
+in the face of partial unavailability of the destination's MX hosts. </p>
+
+<p> If connection caching is not available (Postfix &lt; 2.2) or does
+not provide a sufficient latency reduction, especially for the "relay"
+transport used to forward mail to "your own" domains, consider setting
+lower than default SMTP connection timeouts (1-5 seconds) and higher
+than default destination concurrency limits. This will further reduce
+latency and provide more concurrency to maintain throughput should
+latency rise. </p>
+
+<p> Setting high concurrency limits to domains that are not your own may
+be viewed as hostile by the receiving system, and steps may be taken
+to prevent you from monopolizing the destination system's resources.
+The defensive measures may substantially reduce your throughput or block
+access entirely. Do not set aggressive concurrency limits to remote
+domains without coordinating with the administrators of the target
+domain. </p>
+
+<p> If necessary, dedicate and tune custom transports for selected high
+volume destinations. The "relay" transport is provided for forwarding mail
+to domains for which your server is a primary or backup MX host. These can
+make up a substantial fraction of your email traffic. Use the "relay" and
+not the "smtp" transport to send email to these domains. Using the "relay"
+transport allocates a separate delivery agent pool to these destinations
+and allows separate tuning of timeouts and concurrency limits. </p>
+
+<p> Another common cause of congestion is unwarranted flushing of the
+entire "deferred" queue. The "deferred" queue holds messages that are likely
+to fail to be delivered and are also likely to be slow to fail delivery
+(time out). As a result the most common reaction to a large "deferred" queue
+(flush it!) is more than likely counter-productive, and typically makes
+the congestion worse. Do not flush the "deferred" queue unless you expect
+that most of its content has recently become deliverable (e.g. relayhost
+back up after an outage)! </p>
+
+<p> Note that whenever the queue manager is restarted, there may
+already be messages in the "active" queue directory, but the "real"
+"active" queue in memory is empty. In order to recover the in-memory
+state, the queue manager moves all the "active" queue messages
+back into the "incoming" queue, and then uses its normal "incoming" queue
+scan to refill the "active" queue. The process of moving all
+the messages back and forth, redoing transport table (trivial-rewrite(8)
+resolve service) lookups, and re-importing the messages back into
+memory is expensive. At all costs, avoid frequent restarts of the
+queue manager (e.g. via frequent execution of "postfix reload"). </p>
+
+<h3> <a name="deferred_queue"> The "deferred" queue </a> </h3>
+
+<p> When all the deliverable recipients for a message are delivered,
+and for some recipients delivery failed for a transient reason (it
+might succeed later), the message is placed in the "deferred" queue.
+</p>
+
+<p> The queue manager scans the "deferred" queue periodically. The scan
+interval is controlled by the queue_run_delay parameter. While a "deferred" queue
+scan is in progress, if an "incoming" queue scan is also in progress
+(ideally these are brief since the "incoming" queue should be short), the
+queue manager alternates between looking for messages in the "incoming" queue
+and in the "deferred" queue. This "round-robin" strategy prevents
+starvation of either the "incoming" or the "deferred" queues. </p>
+
+<p> Each "deferred" queue scan only brings a fraction of the "deferred" queue
+back into the "active" queue for a retry. This is because each
+message in the "deferred" queue is assigned a "cool-off" time when
+it is deferred. This is done by time-warping the modification
+time of the queue file into the future. The queue file is not
+eligible for a retry if its modification time is not yet reached.
+</p>
+
+<p> The "cool-off" time is at least $minimal_backoff_time and at
+most $maximal_backoff_time. The next retry time is set by doubling
+the message's age in the queue, and adjusting up or down to lie
+within the limits. This means that young messages are initially
+retried more often than old messages. </p>
+
+<p> If a high volume site routinely has large "deferred" queues, it
+may be useful to adjust the queue_run_delay, minimal_backoff_time and
+maximal_backoff_time to provide short enough delays on first failure
+(Postfix &ge; 2.4 has a sensibly low minimal backoff time by default),
+with perhaps longer delays after multiple failures, to reduce the
+retransmission rate of old messages and thereby reduce the quantity
+of previously deferred mail in the "active" queue. If you want a really
+low minimal_backoff_time, you may also want to lower queue_run_delay,
+but understand that more frequent scans will increase the demand for
+disk I/O. </p>
+
+<p> One common cause of large "deferred" queues is failure to validate
+recipients at the SMTP input stage. Since spammers routinely launch
+dictionary attacks from unrepliable sender addresses, the bounces
+for invalid recipient addresses clog the "deferred" queue (and at high
+volumes proportionally clog the "active" queue). Recipient validation
+is strongly recommended through use of the local_recipient_maps and
+relay_recipient_maps parameters. Even when bounces drain quickly they
+inundate innocent victims of forgery with unwanted email. To avoid
+this, do not accept mail for invalid recipients. </p>
+
+<p> When a host with lots of deferred mail is down for some time,
+it is possible for the entire "deferred" queue to reach its retry
+time simultaneously. This can lead to a very full "active" queue once
+the host comes back up. The phenomenon can repeat approximately
+every maximal_backoff_time seconds if the messages are again deferred
+after a brief burst of congestion. Perhaps, a future Postfix release
+will add a random offset to the retry time (or use a combination
+of strategies) to reduce the odds of repeated complete "deferred" queue
+flushes. </p>
+
+<h2><a name="credits">Credits</a></h2>
+
+<p> The qshape(1) program was developed by Victor Duchovni of Morgan
+Stanley, who also wrote the initial version of this document. </p>
+
+</body>
+
+</html>
diff --git a/proto/README b/proto/README
new file mode 100644
index 0000000..b1db3e4
--- /dev/null
+++ b/proto/README
@@ -0,0 +1,34 @@
+This directory contains source for manual pages that aren't generated
+from C source code comments, and for README files.
+
+Tools for these conversions are found in the ../mantools subdirectory.
+The most important tool is postlink, which adds all the hyperlinks
+between manual pages, configuration parameters and README files.
+
+Manual pages are in the form of "shell" style comments. They are
+converted into nroff(1) input with the srctoman utility, converted
+to HTML with man2html, and hyperlinked with postlink.
+
+The README files are in the form of HTML. The are converted into
+hyperlinked HTML with postlink, and are converted into ASCII files
+with html2readme.
+
+The format of the README source files is a little tricky, because
+of the way postlink works.
+
+- postlink hyperlinks all the references to Postfix manual pages,
+configuration parameters, README file names, RFC documents, Postfix
+address class names, and URLs. Therefore you should not hyperlink
+those elements yourself.
+
+- URLs (such as "http://www.example.com") cannot contain quote, comma,
+or space characters.
+
+- An URL that appears at the end of a line must be followed by one
+other character.
+
+- Text must go between <p> and </p>, especially within lists, for
+consistency of vertical space.
+
+- Code fragments must go between <pre> and </pre>, again for
+consistency of vertical space.
diff --git a/proto/RESTRICTION_CLASS_README.html b/proto/RESTRICTION_CLASS_README.html
new file mode 100644
index 0000000..4988a33
--- /dev/null
+++ b/proto/RESTRICTION_CLASS_README.html
@@ -0,0 +1,239 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Per-Client/User/etc. Access Control</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Per-Client/User/etc. Access Control</h1>
+
+<hr>
+
+<h2>Postfix restriction classes</h2>
+
+<p> The Postfix SMTP server supports access restrictions such as
+reject_rbl_client or reject_unknown_client_hostname on the right-hand side
+of SMTP server access(5) tables. This allows you to implement
+different junk mail restrictions for different clients or users.
+</p>
+
+<p> Having to specify lists of access restrictions for every
+recipient becomes tedious quickly. Postfix restriction classes
+allow you to give easy-to-remember names to groups of UCE restrictions
+(such as "permissive", "restrictive", and so on). </p>
+
+<p> The real reason for the existence of Postfix restriction classes
+is more mundane: you can't specify a lookup table on the right-hand
+side of a Postfix access table. This is because Postfix needs to
+open lookup tables ahead of time, but the reader probably does not
+care about these low-level details. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_restriction_classes = restrictive, permissive
+ # With Postfix &lt; 2.3 specify reject_unknown_client.
+ restrictive = reject_unknown_sender_domain reject_unknown_client_hostname ...
+ permissive = permit
+
+ smtpd_recipient_restrictions =
+ permit_mynetworks
+ # reject_unauth_destination is not needed here if the mail
+ # relay policy is specified with smtpd_relay_restrictions
+ # (available with Postfix 2.10 and later).
+ reject_unauth_destination
+ check_recipient_access hash:/etc/postfix/recipient_access
+ ...
+
+/etc/postfix/recipient_access:
+ joe@my.domain permissive
+ jane@my.domain restrictive
+</pre>
+</blockquote>
+
+<p> With this in place, you can use "restrictive" or "permissive"
+on the right-hand side of your per-client, helo, sender, or recipient
+SMTPD access tables. </p>
+
+<p> The remainder of this document gives examples of how Postfix
+access restriction classes can be used to: </p>
+
+<ul>
+
+<li> <a href="#internal"> Shield an internal mailing list from
+outside posters</a>,
+
+<li> <a href="#external"> Prevent external access by internal
+senders</a>.
+
+</ul>
+
+<p> These questions come up frequently, and the examples hopefully
+make clear that Postfix restriction classes aren't really the right
+solution. They should be used for what they were designed to do,
+different junk mail restrictions for different clients or users.
+</p>
+
+<h2><a name="internal">Protecting internal email distribution
+lists</a></h2>
+
+<blockquote>
+
+<p> We want to implement an internal email distribution list.
+Something like all@our.domain.com, which aliases to all employees.
+My first thought was to use the aliases map, but that would lead
+to "all" being accessible from the "outside", and this is not
+desired... :-) </p>
+
+</blockquote>
+
+<p> Postfix can implement per-address access controls. What follows
+is based on the SMTP client IP address, and therefore is subject
+to IP spoofing. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ ...
+ check_recipient_access hash:/etc/postfix/access
+ <i>...the usual stuff...</i>
+
+/etc/postfix/access:
+ all@my.domain permit_mynetworks,reject
+ all@my.hostname permit_mynetworks,reject
+</pre>
+</blockquote>
+
+<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what map
+types Postfix supports, use the command <b>postconf -m</b>. </p>
+
+<p> Now, that would be sufficient when your machine receives all
+Internet mail directly from the Internet. That's unlikely if your
+network is a bit larger than an office. For example, your backup
+MX hosts would "launder" the client IP address of mail from the
+outside so it would appear to come from a trusted machine. </p>
+
+<p> In the general case you need two lookup tables: one table that
+lists destinations that need to be protected, and one table that
+lists domains that are allowed to send to the protected destinations.
+</p>
+
+<p> What follows is based on the sender SMTP envelope address, and
+therefore is subject to SMTP sender spoofing. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ ...
+ check_recipient_access hash:/etc/postfix/protected_destinations
+ <i>...the usual stuff...</i>
+
+ smtpd_restriction_classes = insiders_only
+ insiders_only = check_sender_access hash:/etc/postfix/insiders, reject
+
+/etc/postfix/protected_destinations:
+ all@my.domain insiders_only
+ all@my.hostname insiders_only
+
+/etc/postfix/insiders:
+ my.domain OK <i>matches my.domain and subdomains</i>
+ another.domain OK <i>matches another.domain and subdomains</i>
+</pre>
+</blockquote>
+
+<p> Getting past this scheme is relatively easy, because all one
+has to do is to spoof the SMTP sender address. </p>
+
+<p> If the internal list is a low-volume one, perhaps it makes more
+sense to make it moderated. </p>
+
+<h2><a name="external">Restricting what users can send mail to
+off-site destinations</a></h2>
+
+<blockquote>
+
+<p> How can I configure Postfix in a way that some users can send
+mail to the internet and other users not. The users with no access
+should receive a generic bounce message. Please don't discuss
+whether such access restrictions are necessary, it was not my
+decision. </p>
+
+</blockquote>
+
+<p> Postfix has support for per-user restrictions. The restrictions
+are implemented by the SMTP server. Thus, users that violate the
+policy have their mail rejected by the SMTP server. Like this:
+</p>
+
+<blockquote>
+<pre>
+554 &lt;user@remote&gt;: Access denied
+</pre>
+</blockquote>
+
+<p> The implementation uses two lookup tables. One table defines
+what users are restricted in where they can send mail, and the
+other table defines what destinations are local. It is left as an
+exercise for the reader to change this into a scheme where only
+some users have permission to send mail to off-site destinations,
+and where most users are restricted. </p>
+
+<p> The example assumes DB/DBM files, but this could also be done
+with LDAP or SQL. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ ...
+ check_sender_access hash:/etc/postfix/restricted_senders
+ <i>...other stuff...</i>
+
+ smtpd_restriction_classes = local_only
+ local_only =
+ check_recipient_access hash:/etc/postfix/local_domains, reject
+
+/etc/postfix/restricted_senders:
+ foo@domain local_only
+ bar@domain local_only
+
+/etc/postfix/local_domains:
+ this.domain OK <i>matches this.domain and subdomains</i>
+ that.domain OK <i>matches that.domain and subdomains</i>
+</pre>
+</blockquote>
+
+<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what map
+types Postfix supports, use the command <b>postconf -m</b>. </p>
+
+<p> Note: this scheme does not authenticate the user, and therefore it can be
+bypassed in several ways: </p>
+
+<ul>
+
+<li> <p> By sending mail via a less restrictive mail
+relay host. </p>
+
+<li> <p> By sending mail as someone else who does have permission
+to send mail to off-site destinations. </p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/SASL_README.html b/proto/SASL_README.html
new file mode 100644
index 0000000..c70d242
--- /dev/null
+++ b/proto/SASL_README.html
@@ -0,0 +1,2261 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<head>
+
+<title>Postfix SASL Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix SASL Howto</h1>
+
+<hr>
+
+<h2><a name="intro">How Postfix uses SASL authentication</a></h2>
+
+<p> SMTP servers need to decide whether an SMTP client is authorized
+to send mail to remote destinations, or only to destinations that
+the server itself is responsible for. Usually, SMTP servers accept
+mail to remote destinations when the client's IP address is in the
+"same network" as the server's IP address. </p>
+
+<p> SMTP clients outside the SMTP server's network need a different
+way to get "same network" privileges. To address this need, Postfix
+supports SASL authentication (RFC 4954, formerly RFC 2554). With
+this a remote SMTP client can authenticate to the Postfix SMTP
+server, and the Postfix SMTP client can authenticate to a remote
+SMTP server. Once a client is authenticated, a server can give it
+"same network" privileges. </p>
+
+<p> Postfix does not implement SASL itself, but instead uses existing
+implementations as building blocks. This means that some SASL-related
+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>
+
+<p> NOTE: People who go to the trouble of installing Postfix may
+have the expectation that Postfix is more secure than some other
+mailers. The Cyrus SASL library contains a lot of code. With this,
+Postfix becomes as secure as other mail systems that use the Cyrus
+SASL library. Dovecot provides an alternative that may be worth
+considering. </p>
+
+<p> You can read more about the following topics: </p>
+
+<ul>
+
+<li><a href="#server_sasl">Configuring SASL authentication in the
+Postfix SMTP server</a></li>
+
+<li><a href="#client_sasl">Configuring SASL authentication in the Postfix SMTP/LMTP client</a></li>
+
+<li><a href="#postfix_build">Building Postfix with SASL support</a></li>
+
+<li><a href="#cyrus_legacy">Using Cyrus SASL version 1.5.x</a></li>
+
+<li><a href="#credits">Credits</a></li>
+
+</ul>
+
+<h2><a name="server_sasl">Configuring SASL authentication in the
+Postfix SMTP server</a></h2>
+
+<p> As mentioned earlier, SASL is implemented separately from
+Postfix. For this reason, configuring SASL authentication in the
+Postfix SMTP server involves two different steps: </p>
+
+<ul>
+
+<li> <p> Configuring the SASL implementation to offer a list of
+mechanisms that are suitable for SASL authentication and, depending
+on the SASL implementation used, configuring authentication backends
+that verify the remote SMTP client's authentication data against
+the system password file or some other database. </p> </li>
+
+<li> <p> Configuring the Postfix SMTP server to enable SASL
+authentication, and to authorize clients to relay mail or to control
+what envelope sender addresses the client may use. </p> </li>
+
+</ul>
+
+<p> Successful authentication in the Postfix SMTP server requires
+a functional SASL framework. Configuring SASL should therefore
+always be the first step, before configuring Postfix. </p>
+
+<p> You can read more about the following topics: </p>
+
+<ul>
+
+<li><a href="#server_which">Which SASL Implementations are
+supported?</a></li>
+
+<li><a href="#server_dovecot">Configuring Dovecot SASL</a>
+
+<ul>
+
+<li><a href="#server_dovecot_comm">Postfix to Dovecot SASL
+communication</a></li>
+
+</ul> </li>
+
+<li><a href="#server_cyrus">Configuring Cyrus SASL</a>
+
+<ul>
+
+<li><a href="#server_cyrus_name">Cyrus SASL configuration file
+name</a></li>
+
+<li><a href="#server_cyrus_location">Cyrus SASL configuration
+file location</a></li>
+
+<li><a href="#server_cyrus_comm">Postfix to Cyrus SASL
+communication</a></li>
+
+</ul> </li>
+
+<li><a href="#server_sasl_enable">Enabling SASL authentication and
+authorization in the Postfix SMTP server</a>
+
+<ul>
+
+<li><a href="#server_sasl_authc">Enabling SASL authentication in
+the Postfix SMTP server</a></li>
+
+<li><a href="#smtpd_sasl_security_options">Postfix SMTP Server
+policy - SASL mechanism properties</a></li>
+
+<li><a href="#server_sasl_authz">Enabling SASL authorization in the
+Postfix SMTP server</a></li>
+
+<li><a href="#server_sasl_other">Additional SMTP Server SASL
+options</a></li>
+
+</ul></li>
+
+<li><a href="#server_test">Testing SASL authentication in the Postfix
+SMTP server</a></li>
+
+</ul>
+
+
+<h3><a name="server_which">Which SASL Implementations are
+supported?</a></h3>
+
+<p> Currently the Postfix SMTP server supports the Cyrus SASL and
+Dovecot SASL implementations. </p>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Current Postfix versions have a plug-in architecture that can
+support multiple SASL implementations. Before Postfix version 2.3,
+Postfix had support only for Cyrus SASL. </p>
+
+</blockquote>
+
+<p> To find out what SASL implementations are compiled into Postfix,
+use the following commands: </p>
+
+<blockquote>
+<pre>
+% <strong><code>postconf -a</code></strong> (SASL support in the SMTP server)
+% <strong><code>postconf -A</code></strong> (SASL support in the SMTP+LMTP client)
+</pre>
+</blockquote>
+
+<p> These commands are available only with Postfix version 2.3 and
+later. </p>
+
+<h3><a name="server_dovecot">Configuring Dovecot SASL</a></h3>
+
+<p> Dovecot is a POP/IMAP server that has its own configuration to
+authenticate POP/IMAP clients. When the Postfix SMTP server uses
+Dovecot SASL, it reuses parts of this configuration. Consult the
+<a href="http://wiki.dovecot.org">Dovecot documentation</a> for how
+to configure and operate the Dovecot authentication server. </p>
+
+<h4><a name="server_dovecot_comm">Postfix to Dovecot SASL communication</a></h4>
+
+<p> Communication between the Postfix SMTP server and Dovecot SASL
+happens over a UNIX-domain socket or over a TCP socket. We will
+be using a UNIX-domain socket for better privacy. </p>
+
+<p> The following fragment for Dovecot version 2 assumes that the
+Postfix queue is under <code>/var/spool/postfix/</code>. </p>
+
+<blockquote>
+<pre>
+ 1 conf.d/10-master.conf:
+ 2 service auth {
+ 3 ...
+ 4 unix_listener /var/spool/postfix/private/auth {
+ 5 mode = 0660
+ 6 # Assuming the default Postfix user and group
+ 7 user = postfix
+ 8 group = postfix
+ 9 }
+10 ...
+11 }
+12
+13 conf.d/10-auth.conf
+14 auth_mechanisms = plain login
+</pre>
+</blockquote>
+
+<p> Line 4 places the Dovecot SASL socket in
+<code>/var/spool/postfix/private/auth</code>, lines 5-8 limit
+read+write permissions to user and group <code>postfix</code> only,
+and line 14 provides <code>plain</code> and <code>login</code> as
+mechanisms for the Postfix SMTP server. </p>
+
+<p> Proceed with the section "<a href="#server_sasl_enable">Enabling
+SASL authentication and authorization in the Postfix SMTP server</a>"
+to turn on and use SASL in the Postfix SMTP server. </p>
+
+<h3><a name="server_cyrus">Configuring Cyrus SASL</a></h3>
+
+<p> The Cyrus SASL framework supports a wide variety of applications
+(POP, IMAP, SMTP, etc.). Different applications may require different
+configurations. As a consequence each application may have its own
+configuration file. </p>
+
+<p> The first step configuring Cyrus SASL is to determine name and
+location of a configuration file that describes how the Postfix
+SMTP server will use the SASL framework. </p>
+
+<h4><a name="server_cyrus_name">Cyrus SASL configuration file name</a></h4>
+
+<p> The name of the configuration file (default: <code>smtpd.conf</code>)
+is configurable. It is a concatenation from a value that the Postfix
+SMTP server sends to the Cyrus SASL library, and the suffix
+<code>.conf</code>, added by Cyrus SASL. </p>
+
+<p> The value sent by Postfix is the name of the server component
+that will use Cyrus SASL. It defaults to <code>smtpd</code> and
+is configured with one of the following variables: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Postfix 2.3 and later
+ smtpd_sasl_path = smtpd
+
+ # Postfix &lt; 2.3
+ smtpd_sasl_application_name = smtpd
+</pre>
+</blockquote>
+
+<h4><a name="server_cyrus_location">Cyrus SASL configuration file
+location</a></h4>
+
+<p> The location where Cyrus SASL searches for the named file depends
+on the Cyrus SASL version and the OS/distribution used. </p>
+
+<p> You can read more about the following topics: </p>
+
+<ul>
+
+<li> <p> Cyrus SASL version 2.x searches for the configuration file
+in <code>/usr/lib/sasl2/</code>. </p> </li>
+
+<li> <p> Cyrus SASL version 2.1.22 and newer additionally search
+in <code>/etc/sasl2/</code>. </p> </li>
+
+<li> <p> Some Postfix distributions are modified and look for the
+Cyrus SASL configuration file in <code>/etc/postfix/sasl/</code>,
+<code>/var/lib/sasl2/</code> etc. See the distribution-specific
+documentation to determine the expected location. </p> </li>
+
+</ul>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Cyrus SASL searches <code>/usr/lib/sasl2/</code> first. If it
+finds the specified configuration file there, it will not examine
+other locations. </p>
+
+</blockquote>
+
+<h4><a name="server_cyrus_comm">Postfix to Cyrus SASL communication</a></h4>
+
+<p> As the Postfix SMTP server is linked with the Cyrus SASL library
+<code>libsasl</code>, communication between Postfix and Cyrus SASL
+takes place by calling functions in the SASL library. </p>
+
+<p> The SASL library may use an external password verification
+service, or an internal plugin to connect to authentication backends
+and verify the SMTP client's authentication data against the system
+password file or other databases. </p>
+
+<p> The following table shows typical combinations discussed in
+this document: </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr>
+
+<th align="center">authentication backend</th>
+
+<th align="center">password verification service / plugin</th>
+
+</tr>
+
+<tr>
+
+<td>/etc/shadow</td>
+
+<td><a href="#saslauthd">saslauthd</a></td>
+
+</tr>
+
+<tr>
+
+<td>PAM</td>
+
+<td><a href="#saslauthd">saslauthd</a></td>
+
+</tr>
+
+<tr>
+
+<td>IMAP server</td>
+
+<td><a href="#saslauthd">saslauthd</a></td>
+
+</tr>
+
+<tr>
+
+<td>sasldb</td>
+
+<td><a href="#auxprop_sasldb">sasldb</a></td>
+
+</tr>
+
+<tr>
+
+<td>MySQL, PostgreSQL, SQLite</td>
+
+<td><a href="#auxprop_sql">sql</a></td>
+
+</tr>
+
+<tr>
+
+<td>LDAP</td>
+
+<td><a href="#auxprop_ldapdb">ldapdb</a></td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Read the Cyrus SASL documentation for other backends it can
+use. </p>
+
+</blockquote>
+
+<h4><a name="saslauthd">saslauthd - Cyrus SASL password verification service</a></h4>
+
+<p> Communication between the Postfix SMTP server (read: Cyrus SASL's
+<code>libsasl</code>) and the <code>saslauthd</code> server takes
+place over a UNIX-domain socket. </p>
+
+<p> <code>saslauthd</code> usually establishes the UNIX domain
+socket in <code>/var/run/saslauthd/</code> and waits for authentication
+requests. The Postfix SMTP server must have read+execute permission
+to this directory or authentication attempts will fail. </p>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> Some distributions require the user <code>postfix</code> to be
+member of a special group e.g. <code>sasl</code>, otherwise it
+will not be able to access the <code>saslauthd</code> socket
+directory. </p>
+
+</blockquote>
+
+<p> The following example configures the Cyrus SASL library to
+contact <code>saslauthd</code> as its password verification service:
+</p>
+
+<blockquote>
+<pre>
+/etc/sasl2/smtpd.conf:
+ pwcheck_method: saslauthd
+ mech_list: PLAIN LOGIN
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> Do not specify any other mechanisms in <code>mech_list</code>
+than <code>PLAIN</code> or <code>LOGIN</code> when using
+<code>saslauthd</code>! It can only handle these two mechanisms,
+and authentication will fail if clients are allowed to choose other
+mechanisms. </p>
+
+</blockquote>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> Plaintext mechanisms (<code>PLAIN</code>, <code>LOGIN</code>)
+send credentials unencrypted. This information should be protected
+by an additional security layer such as a TLS-encrypted SMTP session
+(see: TLS_README). </p>
+
+</blockquote>
+
+<p> Additionally the <code>saslauthd</code> server itself must be
+configured. It must be told which authentication backend to turn
+to for password verification. The backend is selected with a
+<code>saslauthd</code> command-line option and will be shown in the
+following examples. </p>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Some distributions use a configuration file to provide saslauthd
+command line options to set e.g. the authentication backend. Typical
+locations are <code>/etc/sysconfig/saslauthd</code> or
+<code>/etc/default/saslauthd</code>. </p>
+
+</blockquote>
+
+<h4><a name="saslauthd_shadow">Using saslauthd with /etc/shadow</a></h4>
+
+<p> Access to the <code>/etc/shadow</code> system password file
+requires <code>root</code> privileges. The Postfix SMTP server
+(and in consequence <code>libsasl</code> linked to the server) runs
+with the least privilege possible. Direct access to
+<code>/etc/shadow</code> would not be possible without breaking the
+Postfix security architecture. </p>
+
+<p> The <code>saslauthd</code> socket builds a safe bridge. Postfix,
+running as limited user <code>postfix</code>, can access the
+UNIX-domain socket that <code>saslauthd</code> receives commands
+on; <code>saslauthd</code>, running as privileged user <code>root</code>,
+has the privileges required to access the shadow file. </p>
+
+<p> The <code>saslauthd</code> server verifies passwords against the
+authentication backend <code>/etc/shadow</code> if started like this: </p>
+
+<blockquote>
+<pre>
+% <strong><code>saslauthd -a shadow</code></strong>
+</pre>
+</blockquote>
+
+<p> See section "<a href="#testing_saslauthd">Testing saslauthd
+authentication</a>" for test instructions. </p>
+
+<h4><a name="saslauthd_pam">Using saslauthd with PAM</a></h4>
+
+<p> Cyrus SASL can use the PAM framework to authenticate credentials.
+<code>saslauthd</code> uses the PAM framework when started like
+this: </p>
+
+<blockquote>
+<pre>
+% <strong><code>saslauthd -a pam</code></strong>
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> PAM configuration for the Postfix SMTP server is usually given
+in <code>/etc/pam.d/smtp</code> and is beyond the scope of this
+document. </p>
+
+</blockquote>
+
+<p> See section "<a href="#testing_saslauthd">Testing saslauthd
+authentication</a>" for test instructions. </p>
+
+<h4><a name="saslauthd_imap">Using saslauthd with an IMAP server</a></h4>
+
+<p> <code>saslauthd</code> can verify the SMTP client credentials
+by using them to log into an IMAP server. If the login succeeds,
+SASL authentication also succeeds. <code>saslauthd</code> contacts
+an IMAP server when started like this: </p>
+
+<blockquote>
+<pre>
+% <strong><code>saslauthd -a rimap -O imap.example.com</code></strong>
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> The option "<code>-O imap.example.com</code>" specifies the
+IMAP server <code>saslauthd</code> should contact when it verifies
+credentials. </p>
+
+</blockquote>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> <code>saslauthd</code> sends IMAP login information unencrypted.
+Any IMAP session leaving the local host should be protected by an
+additional security layer such as an SSL tunnel. </p>
+
+</blockquote>
+
+<p> See section "<a href="#testing_saslauthd">Testing saslauthd
+authentication</a>" for test instructions. </p>
+
+<h4><a name="testing_saslauthd">Testing saslauthd authentication</a></h4>
+
+<p> Cyrus SASL provides the <code>testsaslauthd</code> utility to
+test <code>saslauthd</code> authentication. The username and password
+are given as command line arguments. The example shows the response
+when authentication is successful: </p>
+
+<blockquote>
+<pre>
+% <strong><code>testsaslauthd -u <em>username</em> -p <em>password</em></code></strong>
+0: OK "Success."
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Sometimes the <code>testsaslauthd</code> program is not distributed
+with a the Cyrus SASL main package. In that case, it may be
+distributed with <code>-devel</code>, <code>-dev</code> or
+<code>-debug</code> packages. </p>
+
+</blockquote>
+
+<p> Specify an additional "<code>-s smtp</code>" if <code>saslauthd</code>
+was configured to contact the PAM authentication framework, and
+specify an additional "<code>-f <em>/path/to/socketdir/mux</em></code>"
+if <code>saslauthd</code> establishes the UNIX-domain socket in a
+non-default location. </p>
+
+<p> If authentication succeeds, proceed with the section "<a
+href="#server_sasl_enable">Enabling SASL authentication and authorization
+in the Postfix SMTP server</a>". </p>
+
+<h4><a name="auxprop">Cyrus SASL Plugins - auxiliary property
+plugins</a></h4>
+
+<p> Cyrus SASL uses a plugin infrastructure (called <code>auxprop</code>)
+to expand <code>libsasl</code>'s capabilities. Currently Cyrus
+SASL sources provide three authentication plugins. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th>Plugin </th> <th>Description </th> </tr>
+
+<tr> <td><a href="#auxprop_sasldb">sasldb</a></td> <td> Accounts
+are stored stored in a Cyrus SASL Berkeley DB database </td> </tr>
+
+<tr> <td><a href="#auxprop_sql">sql</a></td> <td> Accounts are
+stored in a SQL database </td> </tr>
+
+<tr> <td><a href="#auxprop_ldapdb">ldapdb</a></td> <td> Accounts
+are stored stored in an LDAP database </td> </tr>
+
+</table>
+
+</blockquote>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> These three plugins support shared-secret mechanisms i.e.
+CRAM-MD5, DIGEST-MD5 and NTLM. These mechanisms send credentials
+encrypted but their verification process requires the password to
+be available in plaintext. Consequently passwords cannot (!) be
+stored in encrypted form. </p>
+
+</blockquote>
+
+<h4><a name="auxprop_sasldb">The sasldb plugin</a></h4>
+
+<p> The sasldb auxprop plugin authenticates SASL clients against
+credentials that are stored in a Berkeley DB database. The database
+schema is specific to Cyrus SASL. The database is usually located
+at <code>/etc/sasldb2</code>. </p>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> The <code>sasldb2</code> file contains passwords in
+plaintext, and should have read+write access only to user
+<code>postfix</code> or a group that <code>postfix</code> is member
+of. </p>
+
+</blockquote>
+
+<p> The <code>saslpasswd2</code> command-line utility creates
+and maintains the database: </p>
+
+<blockquote>
+<pre>
+% <strong>saslpasswd2 -c -u <em>example.com</em> <em>username</em></strong>
+Password:
+Again (for verification):
+</pre>
+</blockquote>
+
+<p> This command creates an account
+<code><em>username@example.com</em></code>. </p>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> users must specify <code><em>username@example.com</em></code>
+as login name, not <code><em>username</em></code>. </p>
+
+</blockquote>
+
+<p> Run the following command to reuse the Postfix <code>mydomain</code>
+parameter value as the login domain: </p>
+
+<blockquote>
+<pre>
+% <strong>saslpasswd2 -c -u `postconf -h mydomain` <em>username</em></strong>
+Password:
+Again (for verification):
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Run <code>saslpasswd2</code> without any options for further
+help on how to use the command. </p>
+
+</blockquote>
+
+<p> The <code>sasldblistusers2</code> command lists all existing
+users in the sasldb database: </p>
+
+<blockquote>
+<pre>
+% <strong>sasldblistusers2</strong>
+username1@example.com: password1
+username2@example.com: password2
+</pre>
+</blockquote>
+
+<p> Configure libsasl to use sasldb with the following instructions: </p>
+
+<blockquote>
+<pre>
+/etc/sasl2/smtpd.conf:
+ pwcheck_method: auxprop
+ auxprop_plugin: sasldb
+ mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> In the above example adjust <code>mech_list</code> to the
+mechanisms that are applicable for your environment. </p>
+
+</blockquote>
+
+<h4><a name="auxprop_sql">The sql plugin</a></h4>
+
+<p> The sql auxprop plugin is a generic SQL plugin. It provides
+access to credentials stored in a MySQL, PostgreSQL or SQLite
+database. This plugin requires that SASL client passwords are
+stored as plaintext. </p>
+
+<blockquote>
+
+<strong>Tip</strong>
+
+<p> If you must store encrypted passwords, you cannot use the sql
+auxprop plugin. Instead, see section "<a href="#saslauthd_pam">Using
+saslauthd with PAM</a>", and configure PAM to look up the encrypted
+passwords with, for example, the <code>pam_mysql</code> module.
+You will not be able to use any of the methods that require access
+to plaintext passwords, such as the shared-secret methods CRAM-MD5
+and DIGEST-MD5. </p>
+
+</blockquote>
+
+<p> The following example configures libsasl to use the sql plugin
+and connects it to a PostgreSQL server: </p>
+
+<blockquote>
+<pre>
+/etc/sasl2/smtpd.conf:
+ pwcheck_method: auxprop
+ auxprop_plugin: sql
+ mech_list: PLAIN LOGIN CRAM-MD5 DIGEST-MD5 NTLM
+ sql_engine: pgsql
+ sql_hostnames: 127.0.0.1, 192.0.2.1
+ sql_user: username
+ sql_passwd: secret
+ sql_database: dbname
+ sql_select: SELECT password FROM users WHERE user = '%u@%r'
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Set appropriate permissions if <code>smtpd.conf</code> contains
+a password. The file should be readable by the <code>postfix</code>
+user. </p>
+
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> In the above example, adjust <code>mech_list</code> to the
+mechanisms that are applicable for your environment. </p>
+
+</blockquote>
+
+<p> The sql plugin has the following configuration options: </p>
+
+<blockquote>
+
+<dl>
+
+<dt>sql_engine</dt>
+
+<dd>
+
+<p> Specify <code>mysql</code> to connect to a MySQL server,
+<code>pgsql</code> for a PostgreSQL server or <code>sqlite</code>
+for an SQLite database </p>
+
+</dd>
+
+<dt>sql_hostnames</dt>
+
+<dd>
+
+<p> Specify one or more servers (hostname or hostname:port) separated
+by commas. </p>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> With MySQL servers, specify <code>localhost</code> to connect
+over a UNIX-domain socket, and specify <code>127.0.0.1</code> to
+connect over a TCP socket. </p>
+
+</blockquote>
+
+</dd>
+
+<dt>sql_user</dt>
+
+<dd>
+
+<p> The login name to gain access to the database. </p>
+
+</dd>
+
+<dt>sql_passwd</dt>
+
+<dd>
+
+<p> The password to gain access to the database. </p>
+
+</dd>
+
+<dt>sql_database</dt>
+
+<dd>
+
+<p> The name of the database to connect to. </p>
+
+</dd>
+
+<dt>sql_select</dt>
+
+<dd>
+
+<p> The SELECT statement that should retrieve the plaintext password
+from a database table. </p>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> Do not enclose the statement in quotes! Use single quotes to
+escape macros! </p>
+
+</blockquote>
+
+</dd>
+
+</dl>
+
+</blockquote>
+
+<p> The sql plugin provides macros to build <code>sql_select</code>
+statements. They will be replaced with arguments sent from the client. The
+following macros are available: </p>
+
+<blockquote>
+
+<dl>
+
+<dt>%u</dt>
+
+<dd>
+
+<p> The name of the user whose properties are being selected. </p>
+
+</dd>
+
+<dt>%p</dt>
+
+<dd>
+
+<p> The name of the property being selected. While this could technically be
+anything, Cyrus SASL will try userPassword and cmusaslsecretMECHNAME (where
+MECHNAME is the name of a SASL mechanism). </p>
+
+</dd>
+
+<dt>%r</dt>
+
+<dd>
+
+<p> The name of the realm to which the user belongs. This could be
+the KERBEROS realm, the fully-qualified domain name of the computer
+the SASL application is running on, or the domain after the "@" in a
+username. </p>
+
+</dd>
+
+</dl>
+
+</blockquote>
+
+<h4><a name="auxprop_ldapdb">The ldapdb plugin</a></h4>
+
+<p> The ldapdb auxprop plugin provides access to credentials stored
+in an LDAP server. This plugin requires that SASL client passwords are
+stored as plaintext. </p>
+
+<blockquote>
+
+<strong>Tip</strong>
+
+<p> If you must store encrypted passwords, you cannot use the ldapdb
+auxprop plugin. Instead, you can use "<code>saslauthd -a ldap</code>"
+to query the LDAP database directly, with appropriate configuration
+in <code>saslauthd.conf</code>, <a
+href="http://git.cyrusimap.org/cyrus-sasl/tree/saslauthd/LDAP_SASLAUTHD">as
+described here</a>. You will not be able to use any of the
+methods that require access to plaintext passwords, such as the
+shared-secret methods CRAM-MD5 and DIGEST-MD5. </p>
+
+</blockquote>
+
+<p> The ldapdb plugin implements proxy authorization. This means
+that the ldapdb plugin uses its own username and password to
+authenticate with the LDAP server, before it asks the LDAP server
+for the remote SMTP client's password. The LDAP server then decides
+if the ldapdb plugin is authorized to read the remote SMTP client's
+password. </p>
+
+<p> In a nutshell: Configuring ldapdb means authentication and
+authorization must be configured twice - once in the Postfix SMTP
+server to authenticate and authorize the remote SMTP client, and
+once in the LDAP server to authenticate and authorize the ldapdb
+plugin. </p>
+
+<p> This example configures libsasl to use the ldapdb plugin and
+the plugin to connect to an LDAP server: </p>
+
+<blockquote>
+<pre>
+/etc/sasl2/smtpd.conf:
+ pwcheck_method: auxprop
+ auxprop_plugin: ldapdb
+ mech_list: PLAIN LOGIN NTLM CRAM-MD5 DIGEST-MD5
+ ldapdb_uri: ldap://localhost
+ ldapdb_id: proxyuser
+ ldapdb_pw: password
+ ldapdb_mech: DIGEST-MD5
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> Set appropriate permissions if <code>smtpd.conf</code> contains a
+password. The file should be readable by the <code>postfix</code>
+user. </p>
+
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> The shared-secret mechanisms (CRAM-MD5, etc.) require that the
+SASL client passwords are stored as plaintext. </p>
+
+</blockquote>
+
+<p> The following is a summary of applicable <code>smtpd.conf</code>
+file entries: </p>
+
+<blockquote>
+
+<dl>
+
+<dt>auxprop_plugin</dt>
+
+<dd> <p> Specify <code>ldapdb</code> to enable the plugin. </p> </dd>
+
+<dt>ldapdb_uri</dt>
+
+<dd> <p> Specify either <code>ldapi://</code> to connect over
+a UNIX-domain socket, <code>ldap://</code> for an unencrypted TCP
+connection, or <code>ldaps://</code> for an encrypted TCP connection.
+</p> </dd>
+
+<dt>ldapdb_id</dt>
+
+<dd> <p> The login name to authenticate the ldapdb plugin to the
+LDAP server (proxy authorization). </p> </dd>
+
+<dt>ldapdb_pw</dt>
+
+<dd> <p> The password (in plaintext) to authenticate the ldapdb
+plugin to the LDAP server (proxy authorization). </p> </dd>
+
+<dt>ldapdb_mech</dt>
+
+<dd> <p> The mechanism to authenticate the ldapdb plugin to the
+LDAP server. </p>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Specify a mechanism here that is supported by the LDAP server.
+</p>
+
+</blockquote>
+
+</dd>
+
+<dt>ldapdb_rc (optional)</dt>
+
+<dd> <p> The path to a file containing individual configuration
+options for the ldapdb LDAP client (libldap). This allows to specify
+a TLS client certificate which in turn can be used to use the SASL
+EXTERNAL mechanism. </p>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> This mechanism supports authentication over an encrypted transport
+layer, which is recommended if the plugin must connect to an OpenLDAP
+server on a remote machine. </p>
+
+</blockquote>
+
+</dd>
+
+<dt>ldapdb_starttls (optional)</dt>
+
+<dd> <p> The TLS policy for connecting to the LDAP server. Specify
+either <code>try</code> or <code>demand</code>. If the option is
+<code>try</code> the plugin will attempt to establish a TLS-encrypted
+connection with the LDAP server, and will fallback to an unencrypted
+connection if TLS fails. If the policy is <code>demand</code> and
+a TLS-encrypted connection cannot be established, the connection
+fails immediately. </p> </dd>
+
+</dl>
+
+</blockquote>
+
+<p> When the ldapdb plugin connects to the OpenLDAP server and
+successfully authenticates, the OpenLDAP server decides if the
+plugin user is authorized to read SASL account information. </p>
+
+<p> The following configuration gives an example of authorization configuration
+in the OpenLDAP slapd server: </p>
+
+<blockquote>
+<pre>
+/etc/openldap/slapd.conf:
+ authz-regexp
+ uid=(.*),cn=.*,cn=auth
+ ldap:///dc=example,dc=com??sub?cn=$1
+ authz-policy to
+</pre>
+</blockquote>
+
+<p> Here, the <code>authz-regexp</code> option serves for authentication
+of the ldapdb user. It maps its login name to a DN in the LDAP
+directory tree where <code>slapd</code> can look up the SASL account
+information. The <code>authz-policy</code> options defines the
+authentication policy. In this case it grants authentication
+privileges "<code>to</code>" the ldapdb plugin. </p>
+
+<p> The last configuration step is to tell the OpenLDAP <code>slapd</code>
+server where ldapdb may search for usernames matching the one given
+by the mail client. The example below adds an additional attribute
+ldapdb user object (here: <code>authzTo</code> because the authz-policy
+is "<code>to</code>") and configures the scope where the login name
+"proxyuser" may search: </p>
+
+<blockquote>
+<pre>
+dn: cn=proxyuser,dc=example,dc=com
+changetype: modify
+add: authzTo
+authzTo: dn.regex:uniqueIdentifier=(.*),ou=people,dc=example,dc=com
+</pre>
+</blockquote>
+
+<p> Use the <code>ldapmodify</code> or <code>ldapadd</code> command
+to add the above attribute. </p>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Read the chapter "Using SASL" in the <a
+href="http://www.openldap.org/doc/admin">OpenLDAP Admin Guide</a>
+for more detailed instructions to set up SASL authentication in
+OpenLDAP. </p>
+
+</blockquote>
+
+<h3><a name="server_sasl_enable">Enabling SASL authentication and
+authorization in the Postfix SMTP server</a></h3>
+
+<p> By default the Postfix SMTP server uses the Cyrus SASL
+implementation. If the Dovecot SASL implementation should be used,
+specify an <code>smtpd_sasl_type</code> value of <code>dovecot</code>
+instead of <code>cyrus</code>: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_type = dovecot
+</pre>
+</blockquote>
+
+<p> Additionally specify how Postfix SMTP server can find the Dovecot
+authentication server. This depends on the settings that you have
+selected in the section "<a href="#server_dovecot_comm">Postfix to
+Dovecot SASL communication</a>". </p>
+
+<ul>
+
+<li> <p> If you configured Dovecot for UNIX-domain socket communication,
+configure Postfix as follows: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_path = private/auth
+</pre>
+
+<strong>Note</strong>
+
+<p> This example uses a pathname relative to the Postfix queue
+directory, so that it will work whether or not the Postfix SMTP
+server runs chrooted. </p>
+
+<li> <p> If you configured Dovecot for TCP socket communication,
+configure Postfix as follows. If Dovecot runs on a different machine,
+replace 127.0.0.1 by that machine's IP address. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_path = inet:127.0.0.1:12345
+</pre>
+
+<strong>Note</strong>
+
+<p> If you specify a remote IP address, information
+will be sent as plaintext over the network. </p>
+
+</ul>
+
+<h4><a name="server_sasl_authc">Enabling SASL authentication
+in the Postfix SMTP server</a></h4>
+
+<p> Regardless of the SASL implementation type, enabling SMTP
+authentication in the Postfix SMTP server always requires setting
+the <code>smtpd_sasl_auth_enable</code> option: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_auth_enable = yes
+</pre>
+</blockquote>
+
+<p> After a "postfix reload", SMTP clients will see the additional
+capability AUTH in an SMTP session, followed by a list of
+authentication mechanisms the server supports: </p>
+
+<blockquote>
+<pre>
+% <strong>telnet server.example.com 25</strong>
+...
+220 server.example.com ESMTP Postfix
+<strong>EHLO client.example.com</strong>
+250-server.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-AUTH DIGEST-MD5 PLAIN CRAM-MD5
+...
+</pre>
+</blockquote>
+
+<p> However not all clients recognize the AUTH capability as defined
+by the SASL authentication RFC. Some historical implementations expect the
+server to send an "<code>=</code>" as separator between the AUTH
+verb and the list of mechanisms that follows it. </p>
+
+<p> The <code>broken_sasl_auth_clients</code> configuration option
+lets Postfix repeat the AUTH statement in a form that these broken
+clients understand: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ broken_sasl_auth_clients = yes
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> Enable this option for Outlook up to and including version 2003
+and Outlook Express up to version 6. This option does not hurt other
+clients. </p>
+
+</blockquote>
+
+<p> After "postfix reload", the Postfix SMTP server will propagate
+the AUTH capability twice - once for compliant and once for broken
+clients: </p>
+
+<blockquote>
+<pre>
+% <strong>telnet server.example.com 25</strong>
+...
+220 server.example.com ESMTP Postfix
+<strong>EHLO client.example.com</strong>
+250-server.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-AUTH DIGEST-MD5 PLAIN CRAM-MD5
+250-AUTH=DIGEST-MD5 PLAIN CRAM-MD5
+...
+</pre>
+</blockquote>
+
+<h4><a name="smtpd_sasl_security_options">Postfix SMTP Server policy
+- SASL mechanism properties</a></h4>
+
+<p> The Postfix SMTP server supports policies that limit the SASL
+mechanisms that it makes available to clients, based on the properties
+of those mechanisms. The next two sections give examples of how
+these policies are used. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th>Property</th> <th>Description</th> </tr>
+
+<tr> <td>noanonymous</td> <td> Don't use mechanisms that permit
+anonymous authentication. </td> </tr>
+
+<tr> <td>noplaintext</td> <td> Don't use mechanisms that transmit
+unencrypted username and password information. </td> </tr>
+
+<tr> <td>nodictionary</td> <td> Don't use mechanisms that are
+vulnerable to dictionary attacks. </td> </tr>
+
+<tr> <td>forward_secrecy</td> <td> Require forward secrecy between
+sessions (breaking one session does not break earlier sessions).
+</td> </tr>
+
+<tr> <td>mutual_auth</td> <td> Use only mechanisms that authenticate
+both the client and the server to each other. </td> </tr>
+
+</table>
+
+</blockquote>
+
+<h4><a name="id396877">Unencrypted SMTP session</a></h4>
+
+<p> The default policy is to allow any mechanism in the Postfix SMTP server
+except for those based on anonymous authentication: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Specify a list of properties separated by comma or whitespace
+ smtpd_sasl_security_options = noanonymous
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> Always set at least the <code>noanonymous</code> option.
+Otherwise, the Postfix SMTP server can give strangers the same
+authorization as a properly-authenticated client. </p>
+
+</blockquote>
+
+<h4><a name="id396969">Encrypted SMTP session (TLS)</a></h4>
+
+<p> A separate parameter controls Postfix SASL mechanism policy
+during a TLS-encrypted SMTP session. The default is to copy the
+settings from the unencrypted session: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_tls_security_options = $smtpd_sasl_security_options
+</pre>
+</blockquote>
+
+<p> A more sophisticated policy allows plaintext mechanisms, but
+only over a TLS-encrypted connection: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_security_options = noanonymous, noplaintext
+ smtpd_sasl_tls_security_options = noanonymous
+</pre>
+</blockquote>
+
+<p> To offer SASL authentication only after a TLS-encrypted session has been
+established specify this: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_auth_only = yes
+</pre>
+</blockquote>
+
+<h4><a name="server_sasl_authz">Enabling SASL authorization in the Postfix
+SMTP server</a></h4>
+
+<p> After the client has authenticated with SASL, the Postfix SMTP
+server decides what the remote SMTP client will be authorized
+for. Examples of possible SMTP clients authorizations are: </p>
+
+<ul>
+
+<li> <p> Send a message to a remote recipient. </p> </li>
+
+<li> <p> Use a specific envelope sender in the MAIL FROM command. </p> </li>
+
+</ul>
+
+<p> These permissions are not enabled by default. </p>
+
+<h4><a name="server_sasl_authz_relay">Mail relay authorization</a></h4>
+
+<p> With <code>permit_sasl_authenticated</code> the Postfix SMTP
+server can allow
+SASL-authenticated SMTP clients to send mail to remote destinations.
+Examples:
+</p>
+
+<blockquote>
+<pre>
+# With Postfix 2.10 and later, the mail relay policy is
+# preferably specified under smtpd_relay_restrictions.
+/etc/postfix/main.cf:
+ smtpd_relay_restrictions =
+ permit_mynetworks
+ <strong>permit_sasl_authenticated</strong>
+ reject_unauth_destination
+</pre>
+
+<pre>
+# Older configurations combine relay control and spam control under
+# smtpd_recipient_restrictions. To use this example with Postfix &ge;
+# 2.10 specify "smtpd_relay_restrictions=".
+/etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ permit_mynetworks
+ <strong>permit_sasl_authenticated</strong>
+ reject_unauth_destination
+ ...other rules...
+</pre>
+</blockquote>
+
+<h4><a name="server_sasl_authz_envelope">Envelope sender address
+authorization</a></h4>
+
+<p> By default an SMTP client may specify any envelope sender address
+in the MAIL FROM command. That is because the Postfix SMTP server
+only knows the remote SMTP client hostname and IP address, but not
+the user who controls the remote SMTP client. </p>
+
+<p> This changes the moment an SMTP client uses SASL authentication.
+Now, the Postfix SMTP server knows who the sender is. Given a table
+of envelope sender addresses and SASL login names, the Postfix SMTP
+server can decide if the SASL authenticated client is allowed to
+use a particular envelope sender address: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ <strong>smtpd_sender_login_maps = hash:/etc/postfix/controlled_envelope_senders</strong>
+
+ smtpd_recipient_restrictions =
+ ...
+ <strong>reject_sender_login_mismatch</strong>
+ permit_sasl_authenticated
+ ...
+</pre>
+</blockquote>
+
+<p> The <code>controlled_envelope_senders</code> table specifies
+the binding between a sender envelope address and the SASL login
+names that own that address: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/controlled_envelope_senders
+ # envelope sender owners (SASL login names)
+ john@example.com john@example.com
+ helpdesk@example.com john@example.com, mary@example.com
+ postmaster admin@example.com
+ @example.net barney, fred, john@example.com, mary@example.com
+</pre>
+</blockquote>
+
+<p> With this, the <code>reject_sender_login_mismatch</code>
+restriction above will reject the sender address in the MAIL FROM
+command if <code>smtpd_sender_login_maps</code> does not specify
+the SMTP client's login name as an owner of that address. </p>
+
+<p> See also <code>reject_authenticated_sender_login_mismatch</code>,
+<code>reject_known_sender_login_mismatch</code>, and
+<code>reject_unauthenticated_sender_login_mismatch</code> for additional
+control over the SASL login name and the envelope sender. </p>
+
+<h4><a name="server_sasl_other">Additional SMTP Server SASL options</a></h4>
+
+<p> Postfix provides a wide range of SASL authentication configuration
+options. The next section lists a few that are discussed frequently.
+See postconf(5) for a complete list. </p>
+
+<h4><a name="sasl_access">Per-account access control</a></h4>
+
+<p> Postfix can implement policies that depend on the SASL login
+name (Postfix 2.11 and later). Typically this is used to HOLD or
+REJECT mail from accounts whose credentials have been compromised.
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ permit_mynetworks
+ check_sasl_access hash:/etc/postfix/sasl_access
+ permit_sasl_authenticated
+ ...
+
+/etc/postfix/sasl_access:
+ # Use this when smtpd_sasl_local_domain is empty.
+ username HOLD
+ # Use this when smtpd_sasl_local_domain=example.com.
+ username@example.com HOLD
+</pre>
+</blockquote>
+
+<h4><a name="id397172">Default authentication domain</a></h4>
+
+<p> Postfix can append a domain name (or any other string) to a
+SASL login name that does not have a domain part, e.g. "<code>john</code>"
+instead of "<code>john@example.com</code>": </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_local_domain = example.com
+</pre>
+</blockquote>
+
+<p> This is useful as a default setting and safety net for misconfigured
+clients, or during a migration to an authentication method/backend
+that requires an authentication REALM or domain name, before all
+SMTP clients are configured to send such information. </p>
+
+<h4><a name="id397205">Hiding SASL authentication from clients or
+networks</a></h4>
+
+<p> Some clients insist on using SASL authentication if it is offered, even
+when they are not configured to send credentials - and therefore
+they will always fail and disconnect. </p>
+
+<p> Postfix can hide the AUTH capability from these clients/networks: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_exceptions_networks = !192.0.2.171/32, 192.0.2.0/24
+</pre>
+</blockquote>
+
+<h4><a name="id397226">Adding the SASL login name to mail headers</a></h4>
+
+<p> To report SASL login names in Received: message headers (Postfix
+version 2.3 and later): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_sasl_authenticated_header = yes
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> The SASL login names will be shared with the entire world. </p>
+
+</blockquote>
+
+<h3><a name="server_test">Testing SASL authentication in the Postfix SMTP Server</a></h3>
+
+<p> To test the server side, connect (for example, with
+<code>telnet</code>) to the Postfix SMTP server port and you should
+be able to have a conversation as shown below. Information sent by
+the client (that is, you) is shown in <strong>bold</strong> font.
+</p>
+
+<blockquote>
+<pre>
+% <strong>telnet server.example.com 25</strong>
+...
+220 server.example.com ESMTP Postfix
+<strong>EHLO client.example.com</strong>
+250-server.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-ETRN
+250-AUTH DIGEST-MD5 PLAIN CRAM-MD5
+250 8BITMIME
+<strong>AUTH PLAIN AHRlc3QAdGVzdHBhc3M=</strong>
+235 Authentication successful
+</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>'
+with password `<code>testpass</code>'. </p>
+<blockquote>
+
+<strong>Caution</strong>
+
+<p> When posting logs of the SASL negotiations to public lists,
+please keep in mind that username/password information is trivial
+to recover from the base64-encoded form. </p>
+
+</blockquote>
+
+<p> You can use one of the following commands to generate base64
+encoded authentication information: </p>
+
+<ul>
+
+<li> <p> Using a recent version of the <b>bash</b> shell: </p>
+
+<blockquote>
+<pre>
+% <strong>echo -ne '\000username\000password' | openssl base64</strong>
+</pre>
+</blockquote>
+
+<p> Some other shells support similar syntax. </p>
+
+<li> <p> Using the <b>printf</b> command: </p>
+
+<blockquote>
+<pre>
+% <strong>printf '\0%s\0%s' '<em>username</em>' '<em>password</em>' | openssl base64</strong>
+% <strong>printf '\0%s\0%s' '<em>username</em>' '<em>password</em>' | mmencode</strong>
+</pre>
+</blockquote>
+
+<p> The <strong>mmencode</strong> command is part of the metamail
+software. </p>
+
+<li> <p> Using Perl <b>MIME::Base64</b> (from http://www.cpan.org/): </p>
+
+<blockquote>
+<pre>
+% <strong>perl -MMIME::Base64 -e \
+ 'print encode_base64("\0<em>username</em>\0<em>password</em>");'</strong>
+</pre>
+</blockquote>
+
+<p> If the username or password contain "@", you must specify "\@". </p>
+
+<li> <p> Using the <b>gen-auth</b> script: </p>
+
+<blockquote>
+<pre>
+% <strong>gen-auth plain</strong>
+username: <strong><em>username</em></strong>
+password:
+</pre>
+</blockquote>
+
+<p> The <strong>gen-auth</strong> Perl script was written by John
+Jetmore and can be found at http://jetmore.org/john/code/gen-auth. </p>
+
+</ul>
+
+<h2><a name="client_sasl">Configuring SASL authentication in the Postfix SMTP/LMTP client</a></h2>
+
+<p> The Postfix SMTP and the LMTP client can authenticate with a
+remote SMTP server via the Cyrus SASL framework. At this time, the
+Dovecot SASL implementation does not provide client functionality.
+</p>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> The examples in this section discuss only the SMTP client.
+Replace <code>smtp_</code> with <code>lmtp_</code> to get the
+corresponding LMTP client configuration. </p>
+
+</blockquote>
+
+<p> You can read more about the following topics: </p>
+
+<ul>
+
+<li><a href="#client_sasl_enable">Enabling SASL authentication in
+the Postfix SMTP/LMTP client</a></li>
+
+<li><a href="#client_sasl_sender">Configuring sender-dependent SASL
+authentication</a></li>
+
+<li><a href="#client_sasl_policy">Postfix SMTP/LMTP client policy
+- SASL mechanism <em>properties</em></a></li>
+
+<li><a href="#client_sasl_filter">Postfix SMTP/LMTP client policy
+- SASL mechanism <em>names</em></a></li>
+
+</ul>
+
+<h3><a name="client_sasl_enable">Enabling SASL authentication in the
+Postfix SMTP/LMTP client</a></h3>
+
+<p> This section shows a typical scenario where the Postfix SMTP
+client sends all messages via a mail gateway server that requires
+SASL authentication. </p>
+
+<blockquote>
+
+<strong> Trouble solving tips: </strong>
+
+<ul>
+
+<li> <p> If your SASL logins fail with "SASL authentication failure:
+No worthy mechs found" in the mail logfile, then see the section
+"<a href="SASL_README.html#client_sasl_policy">Postfix SMTP/LMTP
+client policy - SASL mechanism <em>properties</em></a>".
+
+<li> <p> For a solution to a more obscure class of SASL authentication
+failures, see "<a href="SASL_README.html#client_sasl_filter">Postfix
+SMTP/LMTP client policy - SASL mechanism <em>names</em></a>".
+
+</ul>
+
+</blockquote>
+
+<p> To make the example more readable we introduce it in two parts.
+The first part takes care of the basic configuration, while the
+second part sets up the username/password information. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_sasl_auth_enable = yes
+ smtp_tls_security_level = encrypt
+ smtp_sasl_tls_security_options = noanonymous
+ relayhost = [mail.isp.example]
+ # Alternative form:
+ # relayhost = [mail.isp.example]:submission
+ smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> The <code>smtp_sasl_auth_enable</code> setting enables
+client-side authentication. We will configure the client's username
+and password information in the second part of the example. </p>
+</li>
+
+<li> <p> The <code>smtp_tls_security_level</code> setting ensures
+that the connection to the remote smtp server will be encrypted, and
+<code>smtp_sasl_tls_security_options</code> removes the prohibition on
+plaintext passwords. </p>
+
+<li> <p> The <code>relayhost</code> setting forces the Postfix SMTP
+to send all remote messages to the specified mail server instead
+of trying to deliver them directly to their destination. </p> </li>
+
+<li> <p> In the <code>relayhost</code> setting, the "<code>[</code>"
+and "<code>]</code>" prevent the Postfix SMTP client from looking
+up MX (mail exchanger) records for the enclosed name. </p> </li>
+
+<li> <p> The <code>relayhost</code> destination may also specify a
+non-default TCP port. For example, the alternative form
+<code>[mail.isp.example]:submission</code> tells Postfix to connect
+to TCP network port 587, which is reserved for email client
+applications. </p> </li>
+
+<li> <p> The Postfix SMTP client is compatible with SMTP servers
+that use the non-standard "<code>AUTH=<em>method.</em>...</code>"
+syntax in response to the EHLO command; this requires no additional
+Postfix client configuration. </p> </li>
+
+<li> <p> With the setting "smtp_tls_wrappermode = yes", the Postfix
+SMTP client supports the "wrappermode" protocol, which uses TCP
+port 465 on the SMTP server (Postfix 3.0 and later). </p> </li>
+
+<li> <p> With the <code>smtp_sasl_password_maps</code> parameter,
+we configure the Postfix SMTP client to send username and password
+information to the mail gateway server. As discussed in the next
+section, the Postfix SMTP client supports multiple ISP accounts.
+For this reason the username and password are stored in a table
+that contains one username/password combination for each mail gateway
+server. </p>
+
+</ul>
+
+<blockquote>
+<pre>
+/etc/postfix/sasl_passwd:
+ # destination credentials
+ [mail.isp.example] username:password
+ # Alternative form:
+ # [mail.isp.example]:submission username:password
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> Keep the SASL client password file in <code>/etc/postfix</code>,
+and make the file read+write only for <code>root</code> to protect
+the username/password combinations against other users. The Postfix
+SMTP client will still be able to read the SASL client passwords.
+It opens the file as user <code>root</code> before it drops privileges,
+and before entering an optional chroot jail. </p>
+
+</blockquote>
+
+<ul>
+
+<li> <p> Use the <code>postmap</code> command whenever you
+change the <code>/etc/postfix/sasl_passwd</code> file. </p> </li>
+
+<li> <p> If you specify the "<code>[</code>" and "<code>]</code>"
+in the <code>relayhost</code> destination, then you must use the
+same form in the <code>smtp_sasl_password_maps</code> file. </p>
+</li>
+
+<li> <p> If you specify a non-default TCP Port (such as
+"<code>:submission</code>" or "<code>:587</code>") in the
+<code>relayhost</code> destination, then you must use the same form
+in the <code>smtp_sasl_password_maps</code> file. </p> </li>
+
+</ul>
+
+<h3><a name="client_sasl_sender">Configuring Sender-Dependent SASL
+authentication</a></h3>
+
+<p> Postfix supports different ISP accounts for different sender
+addresses (version 2.3 and later). This can be useful when one
+person uses the same machine for work and for personal use, or when
+people with different ISP accounts share the same Postfix server.
+</p>
+
+<p> To make this possible, Postfix supports per-sender SASL passwords
+and per-sender relay hosts. In the example below, the Postfix SMTP
+client will search the SASL password file by sender address before
+it searches that same file by destination. Likewise, the Postfix
+trivial-rewrite(8) daemon will search the per-sender relayhost file,
+and use the default <code>relayhost</code> setting only as a final
+resort. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_sender_dependent_authentication = yes
+ sender_dependent_relayhost_maps = hash:/etc/postfix/sender_relay
+ smtp_sasl_auth_enable = yes
+ smtp_sasl_password_maps = hash:/etc/postfix/sasl_passwd
+ relayhost = [mail.isp.example]
+ # Alternative form:
+ # relayhost = [mail.isp.example]:submission
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/sasl_passwd:
+ # Per-sender authentication; see also /etc/postfix/sender_relay.
+ user1@example.com username1:password1
+ user2@example.net username2:password2
+ # Login information for the default relayhost.
+ [mail.isp.example] username:password
+ # Alternative form:
+ # [mail.isp.example]:submission username:password
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/sender_relay:
+ # Per-sender provider; see also /etc/postfix/sasl_passwd.
+ user1@example.com [mail.example.com]:submission
+ user2@example.net [mail.example.net]
+</pre>
+</blockquote>
+
+<ul>
+
+<li> <p> If you are creative, then you can try to combine the two
+tables into one single MySQL database, and configure different
+Postfix queries to extract the appropriate information. </p>
+
+<li> <p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
+tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+
+<li> <p> Execute the command "<b>postmap /etc/postfix/sasl_passwd</b>"
+whenever you change the sasl_passwd table. </p>
+
+<li> <p> Execute the command "<b>postmap /etc/postfix/sender_relay</b>"
+whenever you change the sender_relay table. </p>
+
+</ul>
+
+<h3><a name="client_sasl_policy">Postfix SMTP/LMTP client policy -
+SASL mechanism <em>properties</em></a></h3>
+
+<p> Just like the Postfix SMTP server, the SMTP client has a policy
+that determines which SASL mechanisms are acceptable, based on their
+properties. The next two sections give examples of how these policies
+are used. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th>Property</th> <th>Description</th> </tr>
+
+<tr> <td>noanonymous</td> <td> Don't use mechanisms that permit
+anonymous authentication. </td> </tr>
+
+<tr> <td>noplaintext</td> <td> Don't use mechanisms that transmit
+unencrypted username and password information. </td> </tr>
+
+<tr> <td>nodictionary</td> <td> Don't use mechanisms that are
+vulnerable to dictionary attacks. </td> </tr>
+
+<tr> <td>mutual_auth</td> <td> Use only mechanisms that authenticate
+both the client and the server to each other. </td> </tr>
+
+</table>
+
+</blockquote>
+
+<h4>Unencrypted SMTP session</h4>
+
+<p> The default policy is stricter than that of the Postfix SMTP
+server - plaintext mechanisms are not allowed (nor is any anonymous
+mechanism): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_sasl_security_options = noplaintext, noanonymous
+</pre>
+</blockquote>
+
+<p> This default policy, which allows no plaintext passwords, leads
+to authentication failures if the remote server only offers plaintext
+authentication mechanisms (the SMTP server announces "<code>AUTH
+PLAIN LOGIN</code>"). In such cases the SMTP client will log the
+following error message: </p>
+
+<blockquote>
+<pre>
+SASL authentication failure: No worthy mechs found
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> This same error message will also be logged when the
+<code>libplain.so</code> or <code>liblogin.so</code> modules are
+not installed in the <code>/usr/lib/sasl2</code> directory. </p>
+
+</blockquote>
+
+<p> The insecure approach is to lower the security standards and
+permit plaintext authentication mechanisms: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_sasl_security_options = noanonymous
+</pre>
+</blockquote>
+
+<p> The more secure approach is to protect the plaintext username
+and password with TLS session encryption. To find out if the remote
+SMTP server supports TLS, connect to the server and see if it
+announces STARTTLS support as shown in the example. Information
+sent by the client (that is, you) is shown in <strong>bold</strong>
+font. </p>
+
+<blockquote>
+<pre>
+% <strong>telnet server.example.com 25</strong>
+...
+220 server.example.com ESMTP Postfix
+<strong>EHLO client.example.com</strong>
+250-server.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-STARTTLS
+...
+</pre>
+</blockquote>
+
+<p> Instead of port 25 (smtp), specify port 587 (submission) where
+appropriate. </p>
+
+<h4>Encrypted SMTP session (TLS)</h4>
+
+<p> To turn on TLS in the Postfix SMTP client, see TLS_README for
+configuration details. </p>
+
+<p> The smtp_sasl_tls_security_options parameter controls Postfix
+SASL mechanism policy during a TLS-encrypted SMTP session. The
+default is to copy the settings from the unencrypted session: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_sasl_tls_security_options = $smtp_sasl_security_options
+</pre>
+</blockquote>
+
+<p> A more sophisticated policy allows plaintext mechanisms, but
+only over a TLS-encrypted connection: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_sasl_security_options = noanonymous, noplaintext
+ smtp_sasl_tls_security_options = noanonymous
+</pre>
+</blockquote>
+
+<h3><a name="client_sasl_filter">Postfix SMTP/LMTP client policy -
+SASL mechanism <em>names</em></a></h3>
+
+<p> Given the SASL security options of the previous section, the
+Cyrus SASL library will choose the most secure authentication
+mechanism that both the SMTP client and server implement. Unfortunately,
+that authentication mechanism may fail because the client or server
+is not configured to use that mechanism.</p>
+
+<p> To prevent this, the Postfix SMTP client can filter the names
+of the authentication mechanisms from the remote SMTP server. Used
+correctly, the filter hides unwanted mechanisms from the Cyrus SASL
+library, forcing the library to choose from the mechanisms the
+Postfix SMTP client filter passes through. </p>
+
+<p> The following example filters out everything but the mechanisms
+<code>PLAIN</code> and <code>LOGIN</code>: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_sasl_mechanism_filter = plain, login
+</pre>
+</blockquote>
+
+<blockquote>
+
+<strong>Note</strong>
+
+<p> If the remote server does not offer any of the mechanisms on
+the filter list, authentication will fail. </p>
+
+</blockquote>
+
+<p> We close this section with an example that passes every mechanism
+except for <code>GSSAPI</code> and <code>LOGIN</code>: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_sasl_mechanism_filter = !gssapi, !login, static:all
+</pre>
+</blockquote>
+
+<h2><a name="postfix_build">Building Postfix with SASL support</a></h2>
+
+<p> As mentioned elsewhere, Postfix supports two SASL implementations:
+Cyrus SASL (SMTP client and server) and Dovecot SASL (SMTP server
+only). Both implementations can be built into Postfix simultaneously.
+</p>
+
+<ul>
+
+<li><a href="#build_dovecot">Building Dovecot SASL support</a></li>
+
+<li><a href="#sasl_support">Building Cyrus SASL support</a></li>
+
+</ul>
+
+<h3><a name="build_dovecot">Building Dovecot SASL support</a></h3>
+
+<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 use it to authenticate the
+Postfix SMTP client to your network provider's server. </p>
+
+<p> Dovecot uses its own daemon process for authentication. This
+keeps the Postfix build process simple, because there is no need
+to link extra libraries into Postfix. </p>
+
+<p> To generate the necessary Makefiles, execute the following in
+the Postfix top-level directory: </p>
+
+<blockquote>
+<pre>
+% <strong>make tidy</strong> # if you have left-over files from a previous build
+% <strong>make makefiles CCARGS='-DUSE_SASL_AUTH \
+ -DDEF_SERVER_SASL_TYPE=\"dovecot\"'</strong>
+</pre>
+</blockquote>
+
+<p> After this, proceed with "<code>make</code>" as described in
+the INSTALL document. </p>
+
+<strong>Note</strong>
+
+<ul>
+
+<li>
+
+<p> The <code>-DDEF_SERVER_SASL_TYPE=\"dovecot\"</code> is not
+necessary; it just makes Postfix configuration a little more
+convenient because you don't have to specify the SASL plug-in type
+in the Postfix main.cf file (but this may cause surprises when you
+switch to a later Postfix version that is built with the default
+SASL type of <code>cyrus</code>). </p>
+
+</li>
+
+<li>
+
+<p> If you also want support for LDAP or TLS (or for Cyrus SASL),
+you need to merge their <code>CCARGS</code> and <code>AUXLIBS</code>
+options into the above command line; see the LDAP_README and
+TLS_README for details. </p>
+
+<blockquote>
+<pre>
+% <strong>make tidy</strong> # if you have left-over files from a previous build
+% <strong>make makefiles CCARGS='-DUSE_SASL_AUTH \
+ -DDEF_SERVER_SASL_TYPE=\"dovecot\" \
+ ...<i>CCARGS options for LDAP or TLS etc.</i>...' \
+ AUXLIBS='...<i>AUXLIBS options for LDAP or TLS etc.</i>...'</strong>
+</pre>
+</blockquote>
+
+</li>
+
+</ul>
+
+<h3><a name="sasl_support">Building Cyrus SASL support</a></h3>
+
+<h4><a name="build_sasl">Building the Cyrus SASL library</a></h4>
+
+<p> Postfix works with cyrus-sasl-1.5.x or cyrus-sasl-2.1.x, which are
+available from https://github.com/cyrusimap/cyrus-sasl/releases. </p>
+
+<blockquote>
+
+<strong>Important</strong>
+
+<p> If you install the Cyrus SASL libraries as per the default, you will have
+to create a symlink <code>/usr/lib/sasl</code> -&gt;
+<code>/usr/local/lib/sasl</code> for version 1.5.x or
+<code>/usr/lib/sasl2</code> -&gt; <code>/usr/local/lib/sasl2</code>
+for version 2.1.x. </p>
+
+</blockquote>
+
+<p> Reportedly, Microsoft Outlook (Express) requires the non-standard LOGIN
+and/or NTLM authentication mechanism. To enable these authentication
+mechanisms, build the Cyrus SASL libraries with: </p>
+
+<blockquote>
+<pre>
+% <strong>./configure --enable-login --enable-ntlm</strong>
+</pre>
+</blockquote>
+
+<h4><a name="build_postfix">Building Postfix with Cyrus SASL support</a></h4>
+
+<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
+<code>/usr/local/include</code>, and that the Cyrus SASL libraries are in
+<code>/usr/local/lib</code>. </p>
+
+<p> On some systems this generates the necessary <code>Makefile</code>
+definitions: </p>
+
+<dl>
+
+<dt>Cyrus SASL version 2.1.x</dt>
+
+<dd>
+
+<pre>
+% <strong>make tidy</strong> # if you have left-over files from a previous build
+% <strong>make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+ -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib -lsasl2"</strong>
+</pre>
+
+<p> If your Cyrus SASL shared library is in a directory that the RUN-TIME
+linker does not know about, add a "-Wl,-R,/path/to/directory" option after
+"-lsasl2". </p>
+
+</dd>
+
+<dt>Cyrus SASL version 1.5.x</dt>
+
+<dd>
+
+<pre>
+% <strong>make tidy</strong> # if you have left-over files from a previous build
+% <strong>make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+ -I/usr/local/include" AUXLIBS="-L/usr/local/lib -lsasl"</strong>
+</pre>
+
+</dd>
+
+</dl>
+
+<p> On Solaris 2.x you need to specify run-time link information,
+otherwise the ld.so run-time linker will not find the SASL shared
+library: </p>
+
+<dl>
+
+<dt>Cyrus SASL version 2.1.x</dt>
+
+<dd>
+
+<pre>
+% <strong>make tidy</strong> # remove left-over files from a previous build
+% <strong>make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+ -I/usr/local/include/sasl" AUXLIBS="-L/usr/local/lib \
+ -R/usr/local/lib -lsasl2"</strong>
+</pre>
+
+</dd>
+
+<dt>Cyrus SASL version 1.5.x</dt>
+
+<dd>
+
+<pre>
+% <strong>make tidy</strong> # if you have left-over files from a previous build
+% <strong>make makefiles CCARGS="-DUSE_SASL_AUTH -DUSE_CYRUS_SASL \
+ -I/usr/local/include" AUXLIBS="-L/usr/local/lib \
+ -R/usr/local/lib -lsasl"</strong>
+</pre>
+
+</dd>
+
+</dl>
+
+<h2><a name="cyrus_legacy">Using Cyrus SASL version 1.5.x</a></h2>
+
+<p> Postfix supports Cyrus SASL version 1.x, but you shouldn't use
+it unless you are forced to. The makers of Cyrus SASL write: </p>
+
+<blockquote> <i> This library is being deprecated and applications
+should transition to using the SASLv2 library</i> (source: <a
+href="http://www.cyrusimap.org/download.html">Project Cyrus:
+Downloads</a>). </blockquote>
+
+<p> If you still need to set it up, here's a quick rundown: </p>
+
+<p> Read the regular section on SMTP server configurations for the
+Cyrus SASL framework. The differences are: </p>
+
+<ul>
+
+<li> <p> Cyrus SASL version 1.5.x searches for configuration
+(<code>smtpd.conf</code>) in <code>/usr/lib/sasl/</code> only. You
+must place the configuration in that directory. Some systems may
+have modified Cyrus SASL and put the files into e.g.
+<code>/var/lib/sasl/</code>. </p> </li>
+
+<li> <p> Use the <code>saslpasswd</code> command instead of
+<code>saslpasswd2</code> to create users in <code>sasldb</code>.
+</p> </li>
+
+<li> <p> Use the <code>sasldblistusers</code> command instead of
+<code>sasldblistusers2</code> to find users in <code>sasldb</code>.
+</p> </li>
+
+<li> <p> In the <code>smtpd.conf</code> file you can't use
+<code>mech_list</code> to limit the range of mechanisms offered.
+Instead, remove their libraries from <code>/usr/lib/sasl/</code>
+(and remember remove those files again when a system update
+re-installs new versions). </p> </li>
+
+</ul>
+
+<h2><a name="credits">Credits</a></h2>
+
+<ul>
+
+<li> Postfix SASL support was originally implemented by Till Franke
+of SuSE Rhein/Main AG. </li>
+
+<li> Wietse trimmed down the code to only the bare necessities.
+ </li>
+
+<li> Support for Cyrus SASL version 2 was contributed by Jason Hoos.
+</li>
+
+<li> Liviu Daia added smtpd_sasl_application_name, separated
+reject_sender_login_mismatch into
+reject_authenticated_sender_login_mismatch and
+reject_unauthenticated_sender_login_mismatch, and revised the docs.
+ </li>
+
+<li> Wietse made another iteration through the code to add plug-in
+support for multiple SASL implementations, and for reasons that
+have been lost, also changed smtpd_sasl_application_name into
+smtpd_sasl_path. </li>
+
+<li> The Dovecot SMTP server-only plug-in was originally implemented
+by Timo Sirainen of Procontrol, Finland. </li>
+
+<li> Patrick Ben Koetter revised this document for Postfix 2.4 and
+made much needed updates. </li>
+
+<li> Patrick Ben Koetter revised this document again for Postfix
+2.7 and made much needed updates. </li>
+
+</ul>
+
+</body>
+
+</html>
+
diff --git a/proto/SCHEDULER_README.html b/proto/SCHEDULER_README.html
new file mode 100644
index 0000000..d80b8f4
--- /dev/null
+++ b/proto/SCHEDULER_README.html
@@ -0,0 +1,1839 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Queue Scheduler</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Queue Scheduler</h1>
+
+<hr>
+
+<h2> Disclaimer </h2>
+
+<p> Many of the <i>transport</i>-specific configuration parameters
+discussed in this document will not show up in "postconf" command
+output before Postfix version 2.9. This limitation applies to many
+parameters whose name is a combination of a master.cf service name
+such as "relay" and a built-in suffix such as
+"_destination_concurrency_limit". </p>
+
+<h2> Overview </h2>
+
+<p> The queue manager is by far the most complex part of the Postfix
+mail system. It schedules delivery of new mail, retries failed
+deliveries at specific times, and removes mail from the queue after
+the last delivery attempt. There are two major classes of mechanisms
+that control the operation of the queue manager. </p>
+
+<p> Topics covered by this document: </p>
+
+<ul>
+
+<li> <a href="#concurrency"> Concurrency scheduling</a>, concerned
+with the number of concurrent deliveries to a specific destination,
+including decisions on when to suspend deliveries after persistent
+failures.
+
+<li> <a href="#jobs"> Preemptive scheduling</a>, concerned with
+the selection of email messages and recipients for a given destination.
+
+<li> <a href="#credits"> Credits</a>, something this document would not be
+complete without.
+
+</ul>
+
+<!--
+
+<p> Once started, the qmgr(8) process runs until "postfix reload"
+or "postfix stop". As a persistent process, the queue manager has
+to meet strict requirements with respect to code correctness and
+robustness. Unlike non-persistent daemon processes, the queue manager
+cannot benefit from Postfix's process rejuvenation mechanism that
+limit the impact from resource leaks and other coding errors
+(translation: replacing a process after a short time covers up bugs
+before they can become a problem). </p>
+
+-->
+
+<h2> <a name="concurrency"> Concurrency scheduling </a> </h2>
+
+<p> The following sections document the Postfix 2.5 concurrency
+scheduler, after a discussion of the limitations of the earlier
+concurrency scheduler. This is followed by results of medium-concurrency
+experiments, and a discussion of trade-offs between performance and
+robustness. </p>
+
+<p> The material is organized as follows: </p>
+
+<ul>
+
+<li> <a href="#concurrency_drawbacks"> Drawbacks of the existing
+concurrency scheduler </a>
+
+<li> <a href="#concurrency_summary_2_5"> Summary of the Postfix 2.5
+concurrency feedback algorithm </a>
+
+<li> <a href="#dead_summary_2_5"> Summary of the Postfix 2.5 "dead
+destination" detection algorithm </a>
+
+<li> <a href="#pseudo_code_2_5"> Pseudocode for the Postfix 2.5
+concurrency scheduler </a>
+
+<li> <a href="#concurrency_results"> Results for delivery to
+concurrency limited servers </a>
+
+<li> <a href="#concurrency_discussion"> Discussion of concurrency
+limited server results </a>
+
+<li> <a href="#concurrency_limitations"> Limitations of less-than-1
+per delivery feedback </a>
+
+<li> <a href="#concurrency_config"> Concurrency configuration
+parameters </a>
+
+</ul>
+
+<h3> <a name="concurrency_drawbacks"> Drawbacks of the existing
+concurrency scheduler </a> </h3>
+
+<p> From the start, Postfix has used a simple but robust algorithm
+where the per-destination delivery concurrency is decremented by 1
+after delivery failed due to connection or handshake failure, and
+incremented by 1 otherwise. Of course the concurrency is never
+allowed to exceed the maximum per-destination concurrency limit.
+And when a destination's concurrency level drops to zero, the
+destination is declared "dead" and delivery is suspended. </p>
+
+<p> Drawbacks of +/-1 concurrency feedback per delivery are: <p>
+
+<ul>
+
+<li> <p> Overshoot due to exponential delivery concurrency growth
+with each pseudo-cohort(*). This can be an issue with high-concurrency
+channels. For example, with the default initial concurrency of 5,
+concurrency would proceed over time as (5-10-20). </p>
+
+<li> <p> Throttling down to zero concurrency after a single
+pseudo-cohort(*) failure. This was especially an issue with
+low-concurrency channels where a single failure could be sufficient
+to mark a destination as "dead", causing the suspension of further
+deliveries to the affected destination. </p>
+
+</ul>
+
+<p> (*) A pseudo-cohort is a number of delivery requests equal to
+a destination's delivery concurrency. </p>
+
+<p> The revised concurrency scheduler has a highly modular structure.
+It uses separate mechanisms for per-destination concurrency control
+and for "dead destination" detection. The concurrency control in
+turn is built from two separate mechanisms: it supports less-than-1
+feedback per delivery to allow for more gradual concurrency
+adjustments, and it uses feedback hysteresis to suppress concurrency
+oscillations. And instead of waiting for delivery concurrency to
+throttle down to zero, a destination is declared "dead" after a
+configurable number of pseudo-cohorts reports connection or handshake
+failure. </p>
+
+<h3> <a name="concurrency_summary_2_5"> Summary of the Postfix 2.5
+concurrency feedback algorithm </a> </h3>
+
+<p> We want to increment a destination's delivery concurrency when
+some (not necessarily consecutive) number of deliveries complete
+without connection or handshake failure. This is implemented with
+positive feedback g(N) where N is the destination's delivery
+concurrency. With g(N)=1 feedback per delivery, concurrency increases
+by 1 after each positive feedback event; this gives us the old
+scheduler's exponential growth in time. With g(N)=1/N feedback per
+delivery, concurrency increases by 1 after an entire pseudo-cohort
+N of positive feedback reports; this gives us linear growth in time.
+Less-than-1 feedback per delivery and integer truncation naturally
+give us hysteresis, so that transitions to larger concurrency happen
+every 1/g(N) positive feedback events. </p>
+
+<p> We want to decrement a destination's delivery concurrency when
+some (not necessarily consecutive) number of deliveries complete
+after connection or handshake failure. This is implemented with
+negative feedback f(N) where N is the destination's delivery
+concurrency. With f(N)=1 feedback per delivery, concurrency decreases
+by 1 after each negative feedback event; this gives us the old
+scheduler's behavior where concurrency is throttled down dramatically
+after a single pseudo-cohort failure. With f(N)=1/N feedback per
+delivery, concurrency backs off more gently. Again, less-than-1
+feedback per delivery and integer truncation naturally give us
+hysteresis, so that transitions to lower concurrency happen every
+1/f(N) negative feedback events. </p>
+
+<p> However, with negative feedback we introduce a subtle twist.
+We "reverse" the negative hysteresis cycle so that the transition
+to lower concurrency happens at the <b>beginning</b> of a sequence
+of 1/f(N) negative feedback events. Otherwise, a correction for
+overload would be made too late. This makes the choice of f(N)
+relatively unimportant, as borne out by measurements later in this
+document. </p>
+
+<p> In summary, the main ingredients for the Postfix 2.5 concurrency
+feedback algorithm are a) the option of less-than-1 positive feedback
+per delivery to avoid overwhelming servers, b) the option of
+less-than-1 negative feedback per delivery to avoid giving up too
+fast, c) feedback hysteresis to avoid rapid oscillation, and d) a
+"reverse" hysteresis cycle for negative feedback, so that it can
+correct for overload quickly. </p>
+
+<h3> <a name="dead_summary_2_5"> Summary of the Postfix 2.5 "dead destination" detection algorithm </a> </h3>
+
+<p> We want to suspend deliveries to a specific destination after
+some number of deliveries suffers connection or handshake failure.
+The old scheduler declares a destination "dead" when negative (-1)
+feedback throttles the delivery concurrency down to zero. With
+less-than-1 feedback per delivery, this throttling down would
+obviously take too long. We therefore have to separate "dead
+destination" detection from concurrency feedback. This is implemented
+by introducing the concept of pseudo-cohort failure. The Postfix
+2.5 concurrency scheduler declares a destination "dead" after a
+configurable number of pseudo-cohorts suffers from connection or
+handshake failures. The old scheduler corresponds to the special
+case where the pseudo-cohort failure limit is equal to 1. </p>
+
+<h3> <a name="pseudo_code_2_5"> Pseudocode for the Postfix 2.5 concurrency scheduler </a> </h3>
+
+<p> The pseudo code shows how the ideas behind new concurrency
+scheduler are implemented as of November 2007. The actual code can
+be found in the module qmgr/qmgr_queue.c. </p>
+
+<pre>
+Types:
+ Each destination has one set of the following variables
+ int concurrency
+ double success
+ double failure
+ double fail_cohorts
+
+Feedback functions:
+ N is concurrency; x, y are arbitrary numbers in [0..1] inclusive
+ positive feedback: g(N) = x/N | x/sqrt(N) | x
+ negative feedback: f(N) = y/N | y/sqrt(N) | y
+
+Initialization:
+ concurrency = initial_concurrency
+ success = 0
+ failure = 0
+ fail_cohorts = 0
+
+After success:
+ fail_cohorts = 0
+ Be prepared for feedback &gt; hysteresis, or rounding error
+ success += g(concurrency)
+ while (success >= 1) Hysteresis 1
+ concurrency += 1 Hysteresis 1
+ failure = 0
+ success -= 1 Hysteresis 1
+ Be prepared for overshoot
+ if (concurrency &gt; concurrency limit)
+ concurrency = concurrency limit
+
+Safety:
+ Don't apply positive feedback unless
+ concurrency &lt; busy_refcount + init_dest_concurrency
+ otherwise negative feedback effect could be delayed
+
+After failure:
+ if (concurrency &gt; 0)
+ fail_cohorts += 1.0 / concurrency
+ if (fail_cohorts &gt; cohort_failure_limit)
+ concurrency = 0
+ if (concurrency &gt; 0)
+ Be prepared for feedback &gt; hysteresis, rounding errors
+ failure -= f(concurrency)
+ while (failure &lt; 0)
+ concurrency -= 1 Hysteresis 1
+ failure += 1 Hysteresis 1
+ success = 0
+ Be prepared for overshoot
+ if (concurrency &lt; 1)
+ concurrency = 1
+</pre>
+
+<h3> <a name="concurrency_results"> Results for delivery to concurrency-limited servers </a> </h3>
+
+<p> Discussions about the concurrency scheduler redesign started
+early 2004, when the primary goal was to find alternatives that did
+not exhibit exponential growth or rapid concurrency throttling. No
+code was implemented until late 2007, when the primary concern had
+shifted towards better handling of server concurrency limits. For
+this reason we measure how well the new scheduler does this
+job. The table below compares mail delivery performance of the old
++/-1 feedback per delivery with several less-than-1 feedback
+functions, for different limited-concurrency server scenarios.
+Measurements were done with a FreeBSD 6.2 client and with FreeBSD
+6.2 and various Linux servers. </p>
+
+<p> Server configuration: </p>
+
+<ul> <li> The mail flow was slowed down with 1 second latency per
+recipient ("smtpd_client_restrictions = sleep 1"). The purpose was
+to make results less dependent on hardware details, by avoiding
+slow-downs by queue file I/O, logging I/O, and network I/O.
+
+<li> Concurrency was limited by the server process limit
+("default_process_limit = 5" and "smtpd_client_event_limit_exceptions
+= static:all"). Postfix was stopped and started after changing the
+process limit, because the same number is also used as the backlog
+argument to the listen(2) system call, and "postfix reload" does
+not re-issue this call.
+
+<li> Mail was discarded with "local_recipient_maps = static:all" and
+"local_transport = discard". The discard action in access maps or
+header/body checks
+could not be used as it fails to update the in_flow_delay counters.
+
+</ul>
+
+<p> Client configuration: </p>
+
+<ul>
+
+<li> Queue file overhead was minimized by sending one message to a
+virtual alias that expanded into 2000 different remote recipients.
+All recipients were accounted for according to the maillog file.
+The virtual_alias_expansion_limit setting was increased to avoid
+complaints from the cleanup(8) server.
+
+<li> The number of deliveries was maximized with
+"smtp_destination_recipient_limit = 2". A smaller limit would cause
+Postfix to schedule the concurrency per recipient instead of domain,
+which is not what we want.
+
+<li> Maximum concurrency was limited with
+"smtp_destination_concurrency_limit = 20", and
+initial_destination_concurrency was set to the same value.
+
+<li> The positive and negative concurrency feedback hysteresis was
+1. Concurrency was incremented by 1 at the END of 1/feedback steps
+of positive feedback, and was decremented by 1 at the START of
+1/feedback steps of negative feedback.
+
+<li> The SMTP client used the default 30s SMTP connect timeout and
+300s SMTP greeting timeout.
+
+</ul>
+
+<h4> Impact of the 30s SMTP connect timeout </h4>
+
+<p> The first results are for a FreeBSD 6.2 server, where our
+artificially low listen(2) backlog results in a very short kernel
+queue for established connections. The table shows that all deferred
+deliveries failed due to a 30s connection timeout, and none failed
+due to a server greeting timeout. This measurement simulates what
+happens when the server's connection queue is completely full under
+load, and the TCP engine drops new connections. </p>
+
+<blockquote>
+
+<table>
+
+<tr> <th>client<br> limit</th> <th>server<br> limit</th> <th>feedback<br>
+style</th> <th>connection<br> caching</th> <th>percentage<br>
+deferred</th> <th colspan="2">client concurrency<br> average/stddev</th>
+<th colspan=2>timed-out in<br> connect/greeting </th> </tr>
+
+<tr> <td align="center" colspan="9"> <hr> </td> </tr>
+
+<tr><td align="center">20</td> <td align="center">5</td> <td
+align="center">1/N</td> <td align="center">no</td> <td
+align="center">9.9</td> <td align="center">19.4</td> <td
+align="center">0.49</td> <td align="center">198</td> <td
+align="center">-</td> </tr>
+
+<tr><td align="center">20</td> <td align="center">5</td> <td
+align="center">1/N</td> <td align="center">yes</td> <td
+align="center">10.3</td> <td align="center">19.4</td> <td
+align="center">0.49</td> <td align="center">206</td> <td
+align="center">-</td> </tr>
+
+<tr><td align="center">20</td> <td align="center">5</td> <td
+align="center">1/sqrt(N)</td> <td align="center">no</td>
+<td align="center">10.4</td> <td align="center">19.6</td> <td
+align="center">0.59</td> <td align="center">208</td> <td
+align="center">-</td> </tr>
+
+<tr><td align="center">20</td> <td align="center">5</td> <td
+align="center">1/sqrt(N)</td> <td align="center">yes</td>
+<td align="center">10.6</td> <td align="center">19.6</td> <td
+align="center">0.61</td> <td align="center">212</td> <td
+align="center">-</td> </tr>
+
+<tr><td align="center">20</td> <td align="center">5</td> <td
+align="center">1</td> <td align="center">no</td> <td
+align="center">10.1</td> <td align="center">19.5</td> <td
+align="center">1.29</td> <td align="center">202</td> <td
+align="center">-</td> </tr>
+
+<tr><td align="center">20</td> <td align="center">5</td> <td
+align="center">1</td> <td align="center">yes</td> <td
+align="center">10.8</td> <td align="center">19.3</td> <td
+align="center">1.57</td> <td align="center">216</td> <td
+align="center">-</td> </tr>
+
+<tr> <td align="center" colspan="9"> <hr> </td> </tr>
+
+</table>
+
+<p> A busy server with a completely full connection queue. N is
+the client delivery concurrency. Failed deliveries time out after
+30s without completing the TCP handshake. See text for a discussion
+of results. </p>
+
+</blockquote>
+
+<h4> Impact of the 300s SMTP greeting timeout </h4>
+
+<p> The next table shows results for a Fedora Core 8 server (results
+for RedHat 7.3 are identical). In this case, the artificially small
+listen(2) backlog argument does not impact our measurement. The
+table shows that practically all deferred deliveries fail after the
+300s SMTP greeting timeout. As these timeouts were 10x longer than
+with the first measurement, we increased the recipient count (and
+thus the running time) by a factor of 10 to keep the results
+comparable. The deferred mail percentages are a factor 10 lower
+than with the first measurement, because the 1s per-recipient delay
+was 1/300th of the greeting timeout instead of 1/30th of the
+connection timeout. </p>
+
+<blockquote>
+
+<table>
+
+<tr> <th>client<br> limit</th> <th>server<br> limit</th> <th>feedback<br>
+style</th> <th>connection<br> caching</th> <th>percentage<br>
+deferred</th> <th colspan="2">client concurrency<br> average/stddev</th>
+<th colspan=2>timed-out in<br> connect/greeting </th> </tr>
+
+<tr> <td align="center" colspan="9"> <hr> </td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1/N</td> <td align="center">no</td> <td
+align="center">1.16</td> <td align="center">19.8</td> <td
+align="center">0.37</td> <td align="center">-</td> <td
+align="center">230</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1/N</td> <td align="center">yes</td> <td
+align="center">1.36</td> <td align="center">19.8</td> <td
+align="center">0.36</td> <td align="center">-</td> <td
+align="center">272</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1/sqrt(N)</td> <td align="center">no</td>
+<td align="center">1.21</td> <td align="center">19.9</td> <td
+align="center">0.23</td> <td align="center">4</td> <td
+align="center">238</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1/sqrt(N)</td> <td align="center">yes</td>
+<td align="center">1.36</td> <td align="center">20.0</td> <td
+align="center">0.23</td> <td align="center">-</td> <td
+align="center">272</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1</td> <td align="center">no</td> <td
+align="center">1.18</td> <td align="center">20.0</td> <td
+align="center">0.16</td> <td align="center">-</td> <td
+align="center">236</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1</td> <td align="center">yes</td> <td
+align="center">1.39</td> <td align="center">20.0</td> <td
+align="center">0.16</td> <td align="center">-</td> <td
+align="center">278</td> </tr>
+
+<tr> <td align="center" colspan="9"> <hr> </td> </tr>
+
+</table>
+
+<p> A busy server with a non-full connection queue. N is the client
+delivery concurrency. Failed deliveries complete at the TCP level,
+but time out after 300s while waiting for the SMTP greeting. See
+text for a discussion of results. </p>
+
+</blockquote>
+
+<h4> Impact of active server concurrency limiter </h4>
+
+<p> The final concurrency-limited result shows what happens when
+SMTP connections don't time out, but are rejected immediately with
+the Postfix server's smtpd_client_connection_count_limit feature
+(the server replies with a 421 status and disconnects immediately).
+Similar results can be expected with concurrency limiting features
+built into other MTAs or firewalls. For this measurement we specified
+a server concurrency limit and a client initial destination concurrency
+of 5, and a server process limit of 10; all other conditions were
+the same as with the first measurement. The same result would be
+obtained with a FreeBSD or Linux server, because the "pushing back"
+is done entirely by the receiving side. </p>
+
+<blockquote>
+
+<table>
+
+<tr> <th>client<br> limit</th> <th>server<br> limit</th> <th>feedback<br>
+style</th> <th>connection<br> caching</th> <th>percentage<br>
+deferred</th> <th colspan="2">client concurrency<br> average/stddev</th>
+<th>theoretical<br>defer rate</th> </tr>
+
+<tr> <td align="center" colspan="9"> <hr> </td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1/N</td> <td align="center">no</td> <td
+align="center">16.5</td> <td align="center">5.17</td> <td
+align="center">0.38</td> <td align="center">1/6</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1/N</td> <td align="center">yes</td> <td
+align="center">16.5</td> <td align="center">5.17</td> <td
+align="center">0.38</td> <td align="center">1/6</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1/sqrt(N)</td> <td align="center">no</td>
+<td align="center">24.5</td> <td align="center">5.28</td> <td
+align="center">0.45</td> <td align="center">1/4</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1/sqrt(N)</td> <td align="center">yes</td>
+<td align="center">24.3</td> <td align="center">5.28</td> <td
+align="center">0.46</td> <td align="center">1/4</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1</td> <td align="center">no</td> <td
+align="center">49.7</td> <td align="center">5.63</td> <td
+align="center">0.67</td> <td align="center">1/2</td> </tr>
+
+<tr> <td align="center">20</td> <td align="center">5</td> <td
+align="center">1</td> <td align="center">yes</td> <td
+align="center">49.7</td> <td align="center">5.68</td> <td
+align="center">0.70</td> <td align="center">1/2</td> </tr>
+
+<tr> <td align="center" colspan="9"> <hr> </td> </tr>
+
+</table>
+
+<p> A server with active per-client concurrency limiter that replies
+with 421 and disconnects. N is the client delivery concurrency.
+The theoretical defer rate is 1/(1+roundup(1/feedback)). This is
+always 1/2 with the fixed +/-1 feedback per delivery; with the
+concurrency-dependent feedback variants, the defer rate decreases
+with increasing concurrency. See text for a discussion of results.
+</p>
+
+</blockquote>
+
+<h3> <a name="concurrency_discussion"> Discussion of concurrency-limited server results </a> </h3>
+
+<p> All results in the previous sections are based on the first
+delivery runs only; they do not include any second etc. delivery
+attempts. It's also worth noting that the measurements look at
+steady-state behavior only. They don't show what happens when the
+client starts sending at a much higher or lower concurrency.
+</p>
+
+<p> The first two examples show that the effect of feedback
+is negligible when concurrency is limited due to congestion. This
+is because the initial concurrency is already at the client's
+concurrency maximum, and because there is 10-100 times more positive
+than negative feedback. Under these conditions, it is no surprise
+that the contribution from SMTP connection caching is also negligible.
+</p>
+
+<p> In the last example, the old +/-1 feedback per delivery will
+defer 50% of the mail when confronted with an active (anvil-style)
+server concurrency limit, where the server hangs up immediately
+with a 421 status (a TCP-level RST would have the same result).
+Less aggressive feedback mechanisms fare better than more aggressive
+ones. Concurrency-dependent feedback fares even better at higher
+concurrencies than shown here, but has limitations as discussed in
+the next section. </p>
+
+<h3> <a name="concurrency_limitations"> Limitations of less-than-1 per delivery feedback </a> </h3>
+
+<p> Less-than-1 feedback is of interest primarily when sending large
+amounts of mail to destinations with active concurrency limiters
+(servers that reply with 421, or firewalls that send RST). When
+sending small amounts of mail per destination, less-than-1 per-delivery
+feedback won't have a noticeable effect on the per-destination
+concurrency, because the number of deliveries to the same destination
+is too small. You might just as well use zero per-delivery feedback
+and stay with the initial per-destination concurrency. And when
+mail deliveries fail due to congestion instead of active concurrency
+limiters, the measurements above show that per-delivery feedback
+has no effect. With large amounts of mail you might just as well
+use zero per-delivery feedback and start with the maximal per-destination
+concurrency. </p>
+
+<p> The scheduler with less-than-1 concurrency
+feedback per delivery solves a problem with servers that have active
+concurrency limiters. This works only because feedback is handled
+in a peculiar manner: positive feedback will increment the concurrency
+by 1 at the <b>end</b> of a sequence of events of length 1/feedback,
+while negative feedback will decrement concurrency by 1 at the
+<b>beginning</b> of such a sequence. This is how Postfix adjusts
+quickly for overshoot without causing lots of mail to be deferred.
+Without this difference in feedback treatment, less-than-1 feedback
+per delivery would defer 50% of the mail, and would be no better
+in this respect than the old +/-1 feedback per delivery. </p>
+
+<p> Unfortunately, the same feature that corrects quickly for
+concurrency overshoot also makes the scheduler more sensitive for
+noisy negative feedback. The reason is that one lonely negative
+feedback event has the same effect as a complete sequence of length
+1/feedback: in both cases delivery concurrency is dropped by 1
+immediately. As a worst-case scenario, consider multiple servers
+behind a load balancer on a single IP address, and no backup MX
+address. When 1 out of K servers fails to complete the SMTP handshake
+or drops the connection, a scheduler with 1/N (N = concurrency)
+feedback stops increasing its concurrency once it reaches a concurrency
+level of about K, even though the good servers behind the load
+balancer are perfectly capable of handling more traffic. </p>
+
+<p> This noise problem gets worse as the amount of positive feedback
+per delivery gets smaller. A compromise is to use fixed less-than-1
+positive feedback values instead of concurrency-dependent positive
+feedback. For example, to tolerate 1 of 4 bad servers in the above
+load balancer scenario, use positive feedback of 1/4 per "good"
+delivery (no connect or handshake error), and use an equal or smaller
+amount of negative feedback per "bad" delivery. The downside of
+using concurrency-independent feedback is that some of the old +/-1
+feedback problems will return at large concurrencies. Sites that
+must deliver mail at non-trivial per-destination concurrencies will
+require special configuration. </p>
+
+<h3> <a name="concurrency_config"> Concurrency configuration parameters </a> </h3>
+
+<p> The Postfix 2.5 concurrency scheduler is controlled with the
+following configuration parameters, where "<i>transport</i>_foo"
+provides a transport-specific parameter override. All parameter
+default settings are compatible with earlier Postfix versions. </p>
+
+<blockquote>
+
+<table border="0">
+
+<tr> <th> Parameter name </th> <th> Postfix version </th> <th>
+Description </th> </tr>
+
+<tr> <td colspan="3"> <hr> </td> </tr>
+
+<tr> <td> initial_destination_concurrency<br>
+<i>transport</i>_initial_destination_concurrency </td> <td
+align="center"> all<br> 2.5 </td> <td> Initial per-destination
+delivery concurrency </td> </tr>
+
+<tr> <td> default_destination_concurrency_limit<br>
+<i>transport</i>_destination_concurrency_limit </td> <td align="center">
+all<br> all </td> <td> Maximum per-destination delivery concurrency
+</td> </tr>
+
+<tr> <td> default_destination_concurrency_positive_feedback<br>
+<i>transport</i>_destination_concurrency_positive_feedback </td>
+<td align="center"> 2.5<br> 2.5 </td> <td> Per-destination positive
+feedback amount, per delivery that does not fail with connection
+or handshake failure </td> </tr>
+
+<tr> <td> default_destination_concurrency_negative_feedback<br>
+<i>transport</i>_destination_concurrency_negative_feedback </td>
+<td align="center"> 2.5<br> 2.5 </td> <td> Per-destination negative
+feedback amount, per delivery that fails with connection or handshake
+failure </td> </tr>
+
+<tr> <td> default_destination_concurrency_failed_cohort_limit<br>
+<i>transport</i>_destination_concurrency_failed_cohort_limit </td>
+<td align="center"> 2.5<br> 2.5 </td> <td> Number of failed
+pseudo-cohorts after which a destination is declared "dead" and
+delivery is suspended </td> </tr>
+
+<tr> <td> destination_concurrency_feedback_debug</td> <td align="center">
+2.5 </td> <td> Enable verbose logging of concurrency scheduler
+activity </td> </tr>
+
+<tr> <td colspan="3"> <hr> </td> </tr>
+
+</table>
+
+</blockquote>
+
+<h2> <a name="jobs"> Preemptive scheduling </a> </h2>
+
+<p>
+
+The following sections describe the new queue manager and its
+preemptive scheduler algorithm. Note that the document was originally
+written to describe the changes between the new queue manager (in
+this text referred to as <tt>nqmgr</tt>, the name it was known by
+before it became the default queue manager) and the old queue manager
+(referred to as <tt>oqmgr</tt>). This is why it refers to <tt>oqmgr</tt>
+every so often.
+
+</p>
+
+<p>
+
+This document is divided into sections as follows:
+
+</p>
+
+<ul>
+
+<li> <a href="#<tt>nqmgr</tt>_structures"> The structures used by
+nqmgr </a>
+
+<li> <a href="#<tt>nqmgr</tt>_pickup"> What happens when nqmgr picks
+up the message </a> - how it is assigned to transports, jobs, peers,
+entries
+
+<li> <a href="#<tt>nqmgr</tt>_selection"> How the entry selection
+works </a>
+
+<li> <a href="#<tt>nqmgr</tt>_preemption"> How the preemption
+works </a> - what messages may be preempted and how and what messages
+are chosen to preempt them
+
+<li> <a href="#<tt>nqmgr</tt>_concurrency"> How destination concurrency
+limits affect the scheduling algorithm </a>
+
+<li> <a href="#<tt>nqmgr</tt>_memory"> Dealing with memory resource
+limits </a>
+
+</ul>
+
+<h3> <a name="<tt>nqmgr</tt>_structures"> The structures used by
+nqmgr </a> </h3>
+
+<p>
+
+Let's start by recapitulating the structures and terms used when
+referring to the queue manager and how it operates. Many of these are
+partially described elsewhere, but it is nice to have a coherent
+overview in one place:
+
+</p>
+
+<ul>
+
+<li> <p> Each message structure represents one mail message which
+Postfix is to deliver. The message recipients specify to what
+destinations is the message to be delivered and what transports are
+going to be used for the delivery. </p>
+
+<li> <p> Each recipient entry groups a batch of recipients of one
+message which are all going to be delivered to the same destination
+(and over the same transport).
+</p>
+
+<li> <p> Each transport structure groups everything what is going
+to be delivered by delivery agents dedicated for that transport.
+Each transport maintains a set of queues (describing the destinations
+it shall talk to) and jobs (referencing the messages it shall
+deliver). </p>
+
+<li> <p> Each transport queue (not to be confused with the on-disk
+"active" queue or "incoming" queue) groups everything what is going be
+delivered to given destination (aka nexthop) by its transport. Each
+queue belongs to one transport, so each destination may be referred
+to by several queues, one for each transport. Each queue maintains
+a list of all recipient entries (batches of message recipients)
+which shall be delivered to given destination (the todo list), and
+a list of recipient entries already being delivered by the delivery
+agents (the busy list). </p>
+
+<li> <p> Each queue corresponds to multiple peer structures. Each
+peer structure is like the queue structure, belonging to one transport
+and referencing one destination. The difference is that it lists
+only the recipient entries which all originate from the same message,
+unlike the queue structure, whose entries may originate from various
+messages. For messages with few recipients, there is usually just
+one recipient entry for each destination, resulting in one recipient
+entry per peer. But for large mailing list messages the recipients
+may need to be split to multiple recipient entries, in which case
+the peer structure may list many entries for single destination.
+</p>
+
+<li> <p> Each transport job groups everything it takes to deliver
+one message via its transport. Each job represents one message
+within the context of the transport. The job belongs to one transport
+and message, so each message may have multiple jobs, one for each
+transport. The job groups all the peer structures, which describe
+the destinations the job's message has to be delivered to. </p>
+
+</ul>
+
+<p>
+
+The first four structures are common to both <tt>nqmgr</tt> and
+<tt>oqmgr</tt>, the latter two were introduced by <tt>nqmgr</tt>.
+
+</p>
+
+<p>
+
+These terms are used extensively in the text below, feel free to
+look up the description above anytime you'll feel you have lost a
+sense what is what.
+
+</p>
+
+<h3> <a name="<tt>nqmgr</tt>_pickup"> What happens when nqmgr picks
+up the message </a> </h3>
+
+<p>
+
+Whenever <tt>nqmgr</tt> moves a queue file into the "active" queue,
+the following happens: It reads all necessary information from the
+queue file as <tt>oqmgr</tt> does, and also reads as many recipients
+as possible - more on that later, for now let's just pretend it
+always reads all recipients.
+
+</p>
+
+<p>
+
+Then it resolves the recipients as <tt>oqmgr</tt> does, which
+means obtaining (address, nexthop, transport) triple for each
+recipient. For each triple, it finds the transport; if it does not
+exist yet, it instantiates it (unless it's dead). Within the
+transport, it finds the destination queue for the given nexthop; if it
+does not exist yet, it instantiates it (unless it's dead). The
+triple is then bound to given destination queue. This happens in
+qmgr_resolve() and is basically the same as in <tt>oqmgr</tt>.
+
+</p>
+
+<p>
+
+Then for each triple which was bound to some queue (and thus
+transport), the program finds the job which represents the message
+within that transport's context; if it does not exist yet, it
+instantiates it. Within the job, it finds the peer which represents
+the bound destination queue within this jobs context; if it does
+not exist yet, it instantiates it. Finally, it stores the address
+from the resolved triple to the recipient entry which is appended
+to both the queue entry list and the peer entry list. The addresses
+for the same nexthop are batched in the entries up to the
+<i>transport</i>_destination_recipient_limit for that transport.
+This happens in qmgr_message_assign(), and apart
+from that it operates with job and peer structures, it is basically the
+same as in <tt>oqmgr</tt>.
+
+</p>
+
+<p>
+
+When the job is instantiated, it is enqueued on the transport's job
+list based on the time its message was picked up by <tt>nqmgr</tt>.
+For first batch of recipients this means it is appended to the end
+of the job list, but the ordering of the job list by the enqueue
+time is important as we will see shortly.
+
+</p>
+
+<p>
+
+[Now you should have a pretty good idea what the state of the
+<tt>nqmgr</tt> is after a couple of messages were picked up, and what the
+relation is between all those job, peer, queue and entry structures.]
+
+</p>
+
+<h3> <a name="<tt>nqmgr</tt>_selection"> How the entry selection
+works </a> </h3>
+
+<p>
+
+Having prepared all those above mentioned structures, the task of
+the <tt>nqmgr</tt>'s scheduler is to choose the recipient entries
+one at a time and pass them to the delivery agent for corresponding
+transport. Now how does this work?
+
+</p>
+
+<p>
+
+The first approximation of the new scheduling algorithm is like this:
+
+</p>
+
+<blockquote>
+<pre>
+foreach transport (round-robin-by-transport)
+do
+ if transport busy continue
+ if transport process limit reached continue
+ foreach transport's job (in the order of the transport's job list)
+ do
+ foreach job's peer (round-robin-by-destination)
+ if peer-&gt;queue-&gt;concurrency &lt; peer-&gt;queue-&gt;window
+ return next peer entry.
+ done
+ done
+done
+</pre>
+</blockquote>
+
+<p>
+
+Now what is the "order of the transport's job list"? As we know
+already, the job list is by default kept in the order the message
+was picked up by the <tt>nqmgr</tt>. So by default we get the
+top-level round-robin transport, and within each transport we get
+the FIFO message delivery. The round-robin of the peers by the
+destination is perhaps of little importance in most real-life cases
+(unless the <i>transport</i>_destination_recipient_limit is reached,
+in one job there
+is only one peer structure for each destination), but theoretically
+it makes sure that even within single jobs, destinations are treated
+fairly.
+
+</p>
+
+<p>
+
+[By now you should have a feeling you really know how the scheduler
+works, except for the preemption, under ideal conditions - that is,
+no recipient resource limits and no destination concurrency problems.]
+
+</p>
+
+<h3> <a name="<tt>nqmgr</tt>_preemption"> How the preemption
+works </a> </h3>
+
+<p>
+
+As you might perhaps expect by now, the transport's job list does
+not remain sorted by the job's message enqueue time all the time.
+The most cool thing about <tt>nqmgr</tt> is not the simple FIFO
+delivery, but that it is able to slip mail with little recipients
+past the mailing-list bulk mail. This is what the job preemption
+is about - shuffling the jobs on the transport's job list to get
+the best message delivery rates. Now how is it achieved?
+
+</p>
+
+<p>
+
+First I have to tell you that there are in fact two job lists in
+each transport. One is the scheduler's job list, which the scheduler
+is free to play with, while the other one keeps the jobs always
+listed in the order of the enqueue time and is used for recipient
+pool management we will discuss later. For now, we will deal with
+the scheduler's job list only.
+
+</p>
+
+<p>
+
+So, we have the job list, which is first ordered by the time the
+jobs' messages were enqueued, oldest messages first, the most recently
+picked one at the end. For now, let's assume that there are no
+destination concurrency problems. Without preemption, we pick some
+entry of the first (oldest) job on the queue, assign it to delivery
+agent, pick another one from the same job, assign it again, and so
+on, until all the entries are used and the job is delivered. We
+would then move onto the next job and so on and on. Now how do we
+manage to sneak in some entries from the recently added jobs when
+the first job on the job list belongs to a message going to the
+mailing-list and has thousands of recipient entries?
+
+</p>
+
+<p>
+
+The <tt>nqmgr</tt>'s answer is that we can artificially "inflate"
+the delivery time of that first job by some constant for free - it
+is basically the same trick you might remember as "accumulation of
+potential" from the amortized complexity lessons. For example,
+instead of delivering the entries of the first job on the job list
+every time a delivery agent becomes available, we can do it only
+every second time. If you view the moments the delivery agent becomes
+available on a timeline as "delivery slots", then instead of using
+every delivery slot for the first job, we can use only every other
+slot, and still the overall delivery efficiency of the first job
+remains the same. So the delivery <tt>11112222</tt> becomes
+<tt>1.1.1.1.2.2.2.2</tt> (1 and 2 are the imaginary job numbers, .
+denotes the free slot). Now what do we do with free slots?
+
+</p>
+
+<p>
+
+As you might have guessed, we will use them for sneaking the mail
+with little recipients in. For example, if we have one four-recipient
+mail followed by four one recipients mail, the delivery sequence
+(that is, the sequence in which the jobs are assigned to the
+delivery slots) might look like this: <tt>12131415</tt>. Hmm, fine
+for sneaking in the single recipient mail, but how do we sneak in
+the mail with more than one recipient? Say if we have one four-recipient
+mail followed by two two-recipient mails?
+
+</p>
+
+<p>
+
+The simple answer would be to use delivery sequence <tt>12121313</tt>.
+But the problem is that this does not scale well. Imagine you have
+mail with a thousand recipients followed by mail with a hundred recipients.
+It is tempting to suggest the delivery sequence like <tt>121212....</tt>,
+but alas! Imagine there arrives another mail with say ten recipients.
+But there are no free slots anymore, so it can't slip by, not even
+if it had only one recipient. It will be stuck until the
+hundred-recipient mail is delivered, which really sucks.
+
+</p>
+
+<p>
+
+So, it becomes obvious that while inflating the message to get
+free slots is a great idea, one has to be really careful of how the
+free slots are assigned, otherwise one might corner himself. So,
+how does <tt>nqmgr</tt> really use the free slots?
+
+</p>
+
+<p>
+
+The key idea is that one does not have to generate the free slots
+in a uniform way. The delivery sequence <tt>111...1</tt> is no
+worse than <tt>1.1.1.1</tt>, in fact, it is even better as some
+entries are in the first case selected earlier than in the second
+case, and none is selected later! So it is possible to first
+"accumulate" the free delivery slots and then use them all at once.
+It is even possible to accumulate some, then use them, then accumulate
+some more and use them again, as in <tt>11..1.1</tt> .
+
+</p>
+
+<p>
+
+Let's get back to the one hundred recipient example. We now know
+that we could first accumulate one hundred free slots, and only
+after then to preempt the first job and sneak the one hundred
+recipient mail in. Applying the algorithm recursively, we see the
+hundred recipient job can accumulate ten free delivery slots, and
+then we could preempt it and sneak in the ten-recipient mail...
+Wait wait wait! Could we? Aren't we overinflating the original one
+thousand recipient mail?
+
+</p>
+
+<p>
+
+Well, despite the fact that it looks so at the first glance, another trick will
+allow us to answer "no, we are not!". If we had said that we will
+inflate the delivery time twice at maximum, and then we consider
+every other slot as a free slot, then we would overinflate in case
+of the recursive preemption. BUT! The trick is that if we use only
+every n-th slot as a free slot for n&gt;2, there is always some worst
+inflation factor which we can guarantee not to be breached, even
+if we apply the algorithm recursively. To be precise, if for every
+k&gt;1 normally used slots we accumulate one free delivery slot, than
+the inflation factor is not worse than k/(k-1) no matter how many
+recursive preemptions happen. And it's not worse than (k+1)/k if
+only non-recursive preemption happens. Now, having got through the
+theory and the related math, let's see how <tt>nqmgr</tt> implements
+this.
+
+</p>
+
+<p>
+
+Each job has so called "available delivery slot" counter. Each
+transport has a <i>transport</i>_delivery_slot_cost parameter, which
+defaults to default_delivery_slot_cost parameter which is set to 5
+by default. This is the k from the paragraph above. Each time k
+entries of the job are selected for delivery, this counter is
+incremented by one. Once there are some slots accumulated, a job which
+requires no more than that number of slots to be fully delivered
+can preempt this job.
+
+</p>
+
+<p>
+
+[Well, the truth is, the counter is incremented every time an entry
+is selected and it is divided by k when it is used.
+But to understand, it's good enough to use
+the above approximation of the truth.]
+
+</p>
+
+<p>
+
+OK, so now we know the conditions which must be satisfied so one
+job can preempt another one. But what job gets preempted, how do
+we choose what job preempts it if there are several valid candidates,
+and when does all this exactly happen?
+
+</p>
+
+<p>
+
+The answer for the first part is simple. The job whose entry was
+selected the last time is the so called current job. Normally, it is
+the first job on the scheduler's job list, but destination concurrency
+limits may change this as we will see later. It is always only the
+current job which may get preempted.
+
+</p>
+
+<p>
+
+Now for the second part. The current job has a certain amount of
+recipient entries, and as such may accumulate at maximum some amount
+of available delivery slots. It might have already accumulated some,
+and perhaps even already used some when it was preempted before
+(remember a job can be preempted several times). In either case,
+we know how many are accumulated and how many are left to deliver,
+so we know how many it may yet accumulate at maximum. Every other
+job which may be delivered by less than that number of slots is a
+valid candidate for preemption. How do we choose among them?
+
+</p>
+
+<p>
+
+The answer is - the one with maximum enqueue_time/recipient_entry_count.
+That is, the older the job is, the more we should try to deliver
+it in order to get best message delivery rates. These rates are of
+course subject to how many recipients the message has, therefore
+the division by the recipient (entry) count. No one shall be surprised
+that a message with n recipients takes n times longer to deliver than
+a message with one recipient.
+
+</p>
+
+<p>
+
+Now let's recap the previous two paragraphs. Isn't it too complicated?
+Why don't the candidates come only among the jobs which can be
+delivered within the number of slots the current job already
+accumulated? Why do we need to estimate how much it has yet to
+accumulate? If you found out the answer, congratulate yourself. If
+we did it this simple way, we would always choose the candidate
+with the fewest recipient entries. If there were enough single recipient
+mails coming in, they would always slip by the bulk mail as soon
+as possible, and the two or more recipients mail would never get
+a chance, no matter how long they have been sitting around in the
+job list.
+
+</p>
+
+<p>
+
+This candidate selection has an interesting implication - that when
+we choose the best candidate for preemption (this is done in
+qmgr_choose_candidate()), it may happen that we may not use it for
+preemption immediately. This leads to an answer to the last part
+of the original question - when does the preemption happen?
+
+</p>
+
+<p>
+
+The preemption attempt happens every time next transport's recipient
+entry is to be chosen for delivery. To avoid needless overhead, the
+preemption is not attempted if the current job could never accumulate
+more than <i>transport</i>_minimum_delivery_slots (defaults to
+default_minimum_delivery_slots which defaults to 3). If there are
+already enough accumulated slots to preempt the current job by the
+chosen best candidate, it is done immediately. This basically means
+that the candidate is moved in front of the current job on the
+scheduler's job list and decreasing the accumulated slot counter
+by the amount used by the candidate. If there are not enough slots...
+well, I could say that nothing happens and the another preemption
+is attempted the next time. But that's not the complete truth.
+
+</p>
+
+<p>
+
+The truth is that it turns out that it is not really necessary to
+wait until the jobs counter accumulates all the delivery slots in
+advance. Say we have ten-recipient mail followed by two two-recipient
+mails. If the preemption happened when enough delivery slots accumulate
+(assuming slot cost 2), the delivery sequence becomes
+<tt>11112211113311</tt>. Now what would we get if we would wait
+only for 50% of the necessary slots to accumulate and we promise
+we would wait for the remaining 50% later, after we get back
+to the preempted job? If we use such a slot loan, the delivery sequence
+becomes <tt>11221111331111</tt>. As we can see, it makes it not
+considerably worse for the delivery of the ten-recipient mail, but
+it allows the small messages to be delivered sooner.
+
+</p>
+
+<p>
+
+The concept of these slot loans is where the
+<i>transport</i>_delivery_slot_discount and
+<i>transport</i>_delivery_slot_loan come from (they default to
+default_delivery_slot_discount and default_delivery_slot_loan, whose
+values are by default 50 and 3, respectively). The discount (resp.
+loan) specifies how many percent (resp. how many slots) one "gets
+in advance", when the number of slots required to deliver the best
+candidate is compared with the number of slots the current slot had
+accumulated so far.
+
+</p>
+
+<p>
+
+And that pretty much concludes this chapter.
+
+</p>
+
+<p>
+
+[Now you should have a feeling that you pretty much understand the
+scheduler and the preemption, or at least that you will have
+after you read the last chapter a couple more times. You shall clearly
+see the job list and the preemption happening at its head, in ideal
+delivery conditions. The feeling of understanding shall last until
+you start wondering what happens if some of the jobs are blocked,
+which you might eventually figure out correctly from what had been
+said already. But I would be surprised if your mental image of the
+scheduler's functionality is not completely shattered once you
+start wondering how it works when not all recipients may be read
+in-core. More on that later.]
+
+</p>
+
+<h3> <a name="<tt>nqmgr</tt>_concurrency"> How destination concurrency
+limits affect the scheduling algorithm </a> </h3>
+
+<p>
+
+The <tt>nqmgr</tt> uses the same algorithm for destination concurrency
+control as <tt>oqmgr</tt>. Now what happens when the destination
+limits are reached and no more entries for that destination may be
+selected by the scheduler?
+
+</p>
+
+<p>
+
+From the user's point of view it is all simple. If some of the peers
+of a job can't be selected, those peers are simply skipped by the
+entry selection algorithm (the pseudo-code described before) and
+only the selectable ones are used. If none of the peers may be
+selected, the job is declared a "blocker job". Blocker jobs are
+skipped by the entry selection algorithm and they are also excluded
+from the candidates for preemption of the current job. Thus the scheduler
+effectively behaves as if the blocker jobs didn't exist on the job
+list at all. As soon as at least one of the peers of a blocker job
+becomes unblocked (that is, the delivery agent handling the delivery
+of the recipient entry for the given destination successfully finishes),
+the job's blocker status is removed and the job again participates
+in all further scheduler actions normally.
+
+</p>
+
+<p>
+
+So the summary is that the users don't really have to be concerned
+about the interaction of the destination limits and scheduling
+algorithm. It works well on its own and there are no knobs they
+would need to control it.
+
+</p>
+
+<p>
+
+From a programmer's point of view, the blocker jobs complicate the
+scheduler quite a lot. Without them, the jobs on the job list would
+be normally delivered in strict FIFO order. If the current job is
+preempted, the job preempting it is completely delivered unless it
+is preempted itself. Without blockers, the current job is thus
+always either the first job on the job list, or the top of the stack
+of jobs preempting the first job on the job list.
+
+</p>
+
+<p>
+
+The visualization of the job list and the preemption stack without
+blockers would be like this:
+
+</p>
+
+<blockquote>
+<pre>
+first job-&gt; 1--2--3--5--6--8--... &lt;- job list
+on job list |
+ 4 &lt;- preemption stack
+ |
+current job-&gt; 7
+</pre>
+</blockquote>
+
+<p>
+
+In the example above we see that job 1 was preempted by job 4 and
+then job 4 was preempted by job 7. After job 7 is completed, remaining
+entries of job 4 are selected, and once they are all selected, job
+1 continues.
+
+</p>
+
+<p>
+
+As we see, it's all very clean and straightforward. Now how does
+this change because of blockers?
+
+</p>
+
+<p>
+
+The answer is: a lot. Any job may become a blocker job at any time,
+and also become a normal job again at any time. This has several
+important implications:
+
+</p>
+
+<ol>
+
+<li> <p>
+
+The jobs may be completed in arbitrary order. For example, in the
+example above, if the current job 7 becomes blocked, the next job
+4 may complete before the job 7 becomes unblocked again. Or if both
+7 and 4 are blocked, then 1 is completed, then 7 becomes unblocked
+and is completed, then 2 is completed and only after that 4 becomes
+unblocked and is completed... You get the idea.
+
+</p>
+
+<p>
+
+[Interesting side note: even when jobs are delivered out of order,
+from a single destination's point of view the jobs are still delivered
+in the expected order (that is, FIFO unless there was some preemption
+involved). This is because whenever a destination queue becomes
+unblocked (the destination limit allows selection of more recipient
+entries for that destination), all jobs which have peers for that
+destination are unblocked at once.]
+
+</p>
+
+<li> <p>
+
+The idea of the preemption stack at the head of the job list is
+gone. That is, it must be possible to preempt any job on the job
+list. For example, if the jobs 7, 4, 1 and 2 in the example above
+become all blocked, job 3 becomes the current job. And of course
+we do not want the preemption to be affected by the fact that there
+are some blocked jobs or not. Therefore, if it turns out that job
+3 might be preempted by job 6, the implementation shall make it
+possible.
+
+</p>
+
+<li> <p>
+
+The idea of the linear preemption stack itself is gone. It's no
+longer true that one job is always preempted by only one job at one
+time (that is directly preempted, not counting the recursively
+nested jobs). For example, in the example above, job 1 is directly
+preempted by only job 4, and job 4 by job 7. Now assume job 7 becomes
+blocked, and job 4 is being delivered. If it accumulates enough
+delivery slots, it is natural that it might be preempted for example
+by job 8. Now job 4 is preempted by both job 7 AND job 8 at the
+same time.
+
+</p>
+
+</ol>
+
+<p>
+
+Now combine the points 2) and 3) with point 1) again and you realize
+that the relations on the once linear job list became pretty
+complicated. If we extend the point 3) example: jobs 7 and 8 preempt
+job 4, now job 8 becomes blocked too, then job 4 completes. Tricky,
+huh?
+
+</p>
+
+<p>
+
+If I illustrate the relations after the above mentioned examples
+(but those in point 1), the situation would look like this:
+
+</p>
+
+<blockquote>
+<pre>
+ v- parent
+
+adoptive parent -&gt; 1--2--3--5--... &lt;- "stack" level 0
+ | |
+parent gone -&gt; ? 6 &lt;- "stack" level 1
+ / \
+children -&gt; 7 8 ^- child &lt;- "stack" level 2
+
+ ^- siblings
+</pre>
+</blockquote>
+
+<p>
+
+Now how does <tt>nqmgr</tt> deal with all these complicated relations?
+
+</p>
+
+<p>
+
+Well, it maintains them all as described, but fortunately, all these
+relations are necessary only for the purpose of proper counting of
+available delivery slots. For the purpose of ordering the jobs for
+entry selection, the original rule still applies: "the job preempting
+the current job is moved in front of the current job on the job
+list". So for entry selection purposes, the job relations remain
+as simple as this:
+
+</p>
+
+<blockquote>
+<pre>
+7--8--1--2--6--3--5--.. &lt;- scheduler's job list order
+</pre>
+</blockquote>
+
+<p>
+
+The job list order and the preemption parent/child/siblings relations
+are maintained separately. And because the selection works only
+with the job list, you can happily forget about those complicated
+relations unless you want to study the <tt>nqmgr</tt> sources. In
+that case the text above might provide some helpful introduction
+to the problem domain. Otherwise I suggest you just forget about
+all this and stick with the user's point of view: the blocker jobs
+are simply ignored.
+
+</p>
+
+<p>
+
+[By now, you should have a feeling that there are more things going
+on under the hood than you ever wanted to know. You decide that
+forgetting about this chapter is the best you can do for the sake
+of your mind's health and you basically stick with the idea how the
+scheduler works in ideal conditions, when there are no blockers,
+which is good enough.]
+
+</p>
+
+<h3> <a name="<tt>nqmgr</tt>_memory"> Dealing with memory resource
+limits </a> </h3>
+
+<p>
+
+When discussing the <tt>nqmgr</tt> scheduler, we have so far assumed
+that all recipients of all messages in the "active" queue are completely
+read into memory. This is simply not true. There is an upper
+bound on the amount of memory the <tt>nqmgr</tt> may use, and
+therefore it must impose some limits on the information it may store
+in memory at any given time.
+
+</p>
+
+<p>
+
+First of all, not all messages may be read in-core at once. At any
+time, only qmgr_message_active_limit messages may be read in-core
+at maximum. When read into memory, the messages are picked from the
+"incoming" and "deferred" queues and moved to the "active" queue
+(incoming having priority), so if there are more than
+qmgr_message_active_limit messages queued in the "active" queue, the
+rest will have to wait until (some of) the messages in the "active" queue
+are completely delivered (or deferred).
+
+</p>
+
+<p>
+
+Even with the limited amount of in-core messages, there is another
+limit which must be imposed in order to avoid memory exhaustion.
+Each message may contain a huge number of recipients (tens or hundreds
+of thousands are not uncommon), so if <tt>nqmgr</tt> read all
+recipients of all messages in the "active" queue, it may easily run
+out of memory. Therefore there must be some upper bound on the
+amount of message recipients which are read into memory at the
+same time.
+
+</p>
+
+<p>
+
+Before discussing how exactly <tt>nqmgr</tt> implements the recipient
+limits, let's see how the sole existence of the limits themselves
+affects the <tt>nqmgr</tt> and its scheduler.
+
+</p>
+
+<p>
+
+The message limit is straightforward - it just limits the size of
+the
+lookahead the <tt>nqmgr</tt>'s scheduler has when choosing which
+message can preempt the current one. Messages not in the "active" queue
+are simply not considered at all.
+
+</p>
+
+<p>
+
+The recipient limit complicates more things. First of all, the
+message reading code must support reading the recipients in batches,
+which among other things means accessing the queue file several
+times and continuing where the last recipient batch ended. This is
+invoked by the scheduler whenever the current job has space for more
+recipients, subject to transport's refill_limit and refill_delay parameters.
+It is also done any time when all
+in-core recipients of the message are dealt with (which may also
+mean they were deferred) but there are still more in the queue file.
+
+</p>
+
+<p>
+
+The second complication is that with some recipients left unread
+in the queue file, the scheduler can't operate with exact counts
+of recipient entries. With unread recipients, it is not clear how
+many recipient entries there will be, as they are subject to
+per-destination grouping. It is not even clear to what transports
+(and thus jobs) the recipients will be assigned. And with messages
+coming from the "deferred" queue, it is not even clear how many unread
+recipients are still to be delivered. This all means that the
+scheduler must use only estimates of how many recipients entries
+there will be. Fortunately, it is possible to estimate the minimum
+and maximum correctly, so the scheduler can always err on the safe
+side. Obviously, the better the estimates, the better the results, so
+it is best when we are able to read all recipients in-core and turn
+the estimates into exact counts, or at least try to read as many
+as possible to make the estimates as accurate as possible.
+
+</p>
+
+<p>
+
+The third complication is that it is no longer true that the scheduler
+is done with a job once all of its in-core recipients are delivered.
+It is possible that the job will be revived later, when another
+batch of recipients is read in core. It is also possible that some
+jobs will be created for the first time long after the first batch
+of recipients was read in core. The <tt>nqmgr</tt> code must be
+ready to handle all such situations.
+
+</p>
+
+<p>
+
+And finally, the fourth complication is that the <tt>nqmgr</tt>
+code must somehow impose the recipient limit itself. Now how does
+it achieve it?
+
+</p>
+
+<p>
+
+Perhaps the easiest solution would be to say that each message may
+have at maximum X recipients stored in-core, but such a solution would
+be poor for several reasons. With reasonable qmgr_message_active_limit
+values, the X would have to be quite low to maintain a reasonable
+memory footprint. And with low X lots of things would not work well.
+The <tt>nqmgr</tt> would have problems to use the
+<i>transport</i>_destination_recipient_limit efficiently. The
+scheduler's preemption would be suboptimal as the recipient count
+estimates would be inaccurate. The message queue file would have
+to be accessed many times to read in more recipients again and
+again.
+
+</p>
+
+<p>
+
+Therefore it seems reasonable to have a solution which does not use
+a limit imposed on a per-message basis, but which maintains a pool
+of available recipient slots, which can be shared among all messages
+in the most efficient manner. And as we do not want separate
+transports to compete for resources whenever possible, it seems
+appropriate to maintain such a recipient pool for each transport
+separately. This is the general idea, now how does it work in
+practice?
+
+</p>
+
+<p>
+
+First we have to solve a little chicken-and-egg problem. If we want
+to use the per-transport recipient pools, we first need to know to
+what transport(s) the message is assigned. But we will find that
+out only after we first read in the recipients. So it is obvious
+that we first have to read in some recipients, use them to find out
+to what transports the message is to be assigned, and only after
+that can we use the per-transport recipient pools.
+
+</p>
+
+<p>
+
+Now how many recipients shall we read for the first time? This is
+what qmgr_message_recipient_minimum and qmgr_message_recipient_limit
+values control. The qmgr_message_recipient_minimum value specifies
+how many recipients of each message we will read the first time,
+no matter what. It is necessary to read at least one recipient
+before we can assign the message to a transport and create the first
+job. However, reading only qmgr_message_recipient_minimum recipients
+even if there are only few messages with few recipients in-core would
+be wasteful. Therefore if there are fewer than qmgr_message_recipient_limit
+recipients in-core so far, the first batch of recipients may be
+larger than qmgr_message_recipient_minimum - as large as is required
+to reach the qmgr_message_recipient_limit limit.
+
+</p>
+
+<p>
+
+Once the first batch of recipients was read in core and the message
+jobs were created, the size of the subsequent recipient batches (if
+any - of course it's best when all recipients are read in one batch)
+is based solely on the position of the message jobs on their
+corresponding transports' job lists. Each transport has a pool of
+<i>transport</i>_recipient_limit recipient slots which it can
+distribute among its jobs (how this is done is described later).
+The subsequent recipient batch may be as large as the sum of all
+recipient slots of all jobs of the message permits (plus the
+qmgr_message_recipient_minimum amount which always applies).
+
+</p>
+
+<p>
+
+For example, if a message has three jobs, the first with 1 recipient
+still in-core and 4 recipient slots, the second with 5 recipients in-core
+and 5 recipient slots, and the third with 2 recipients in-core and 0
+recipient slots, it has 1+5+2=8 recipients in-core and 4+5+0=9 jobs'
+recipients slots in total. This means that we could immediately
+read 2+qmgr_message_recipient_minimum more recipients of that message
+in core.
+
+</p>
+
+<p>
+
+The above example illustrates several things which might be worth
+mentioning explicitly: first, note that although the per-transport
+slots are assigned to particular jobs, we can't guarantee that once
+the next batch of recipients is read in core, that the corresponding
+amounts of recipients will be assigned to those jobs. The jobs lend
+its slots to the message as a whole, so it is possible that some
+jobs end up sponsoring other jobs of their message. For example,
+if in the example above the 2 newly read recipients were assigned
+to the second job, the first job sponsored the second job with 2
+slots. The second notable thing is the third job, which has more
+recipients in-core than it has slots. Apart from sponsoring by other
+job we just saw it can be result of the first recipient batch, which
+is sponsored from global recipient pool of qmgr_message_recipient_limit
+recipients. It can be also sponsored from the message recipient
+pool of qmgr_message_recipient_minimum recipients.
+
+</p>
+
+<p>
+
+Now how does each transport distribute the recipient slots among
+its jobs? The strategy is quite simple. As most scheduler activity
+happens on the head of the job list, it is our intention to make
+sure that the scheduler has the best estimates of the recipient
+counts for those jobs. As we mentioned above, this means that we
+want to try to make sure that the messages of those jobs have all
+recipients read in-core. Therefore the transport distributes the
+slots "along" the job list from start to end. In this case the job
+list sorted by message enqueue time is used, because it doesn't
+change over time as the scheduler's job list does.
+
+</p>
+
+<p>
+
+More specifically, each time a job is created and appended to the
+job list, it gets all unused recipient slots from its transport's
+pool. It keeps them until all recipients of its message are read.
+When this happens, all unused recipient slots are transferred to
+the next job (which is now in fact the first such job) on the job
+list which still has some recipients unread, or eventually back to
+the transport pool if there is no such job. Such a transfer then also
+happens whenever a recipient entry of that job is delivered.
+
+</p>
+
+<p>
+
+There is also a scenario when a job is not appended to the end of
+the job list (for example it was created as a result of a second or
+later recipient batch). Then it works exactly as above, except that
+if it was put in front of the first unread job (that is, the job
+of a message which still has some unread recipients in the queue file),
+that job is first forced to return all of its unused recipient slots
+to the transport pool.
+
+</p>
+
+<p>
+
+The algorithm just described leads to the following state: The first
+unread job on the job list always gets all the remaining recipient
+slots of that transport (if there are any). The jobs queued before
+this job are completely read (that is, all recipients of their
+message were already read in core) and have at maximum as many slots
+as they still have recipients in-core (the maximum is there because
+of the sponsoring mentioned before) and the jobs after this job get
+nothing from the transport recipient pool (unless they got something
+before and then the first unread job was created and enqueued in
+front of them later - in such a case, they also get at maximum as many
+slots as they have recipients in-core).
+
+</p>
+
+<p>
+
+Things work fine in such a state for most of the time, because the
+current job is either completely read in-core or has as many recipient
+slots as there are, but there is one situation which we still have
+to take care of specially. Imagine if the current job is preempted
+by some unread job from the job list and there are no more recipient
+slots available, so this new current job could read only batches
+of qmgr_message_recipient_minimum recipients at a time. This would
+really degrade performance. For this reason, each transport has an
+extra pool of <i>transport</i>_extra_recipient_limit recipient
+slots, dedicated exactly for this situation. Each time an unread
+job preempts the current job, it gets half of the remaining recipient
+slots from the normal pool and this extra pool.
+
+</p>
+
+<p>
+
+And that's it. It sure does sound pretty complicated, but fortunately
+most people don't really have to care exactly how it works as long
+as it works. Perhaps the only important things to know for most
+people are the following upper bound formulas:
+
+</p>
+
+<p>
+
+Each transport has at maximum
+
+</p>
+
+<blockquote>
+<pre>
+max(
+qmgr_message_recipient_minimum * qmgr_message_active_limit
++ *_recipient_limit + *_extra_recipient_limit,
+qmgr_message_recipient_limit
+)
+</pre>
+</blockquote>
+
+<p>
+
+recipients in core.
+
+</p>
+
+<p>
+
+The total amount of recipients in core is
+
+</p>
+
+<blockquote>
+<pre>
+max(
+qmgr_message_recipient_minimum * qmgr_message_active_limit
++ sum( *_recipient_limit + *_extra_recipient_limit ),
+qmgr_message_recipient_limit
+)
+</pre>
+</blockquote>
+
+<p>
+
+where the sum is over all used transports.
+
+</p>
+
+<p>
+
+And this terribly complicated chapter concludes the documentation
+of the <tt>nqmgr</tt> scheduler.
+
+</p>
+
+<p>
+
+[By now you should theoretically know the <tt>nqmgr</tt> scheduler
+inside out. In practice, you still hope that you will never have
+to really understand the last or last two chapters completely, and
+fortunately most people really won't. Understanding how the scheduler
+works in ideal conditions is more than good enough for the vast majority
+of users.]
+
+</p>
+
+<h2> <a name="credits"> Credits </a> </h2>
+
+<ul>
+
+<li> Wietse Venema designed and implemented the initial queue manager
+with per-domain FIFO scheduling, and per-delivery +/-1 concurrency
+feedback.
+
+<li> Patrik Rak designed and implemented preemption where mail with
+fewer recipients can slip past mail with more recipients in a
+controlled manner, and wrote up its documentation.
+
+<li> Wietse Venema initiated a discussion with Patrik Rak and Victor
+Duchovni on alternatives for the +/-1 feedback scheduler's aggressive
+behavior. This is when K/N feedback was reviewed (N = concurrency).
+The discussion ended without a good solution for both negative
+feedback and dead site detection.
+
+<li> Victor Duchovni resumed work on concurrency feedback in the
+context of concurrency-limited servers.
+
+<li> Wietse Venema then re-designed the concurrency scheduler in
+terms of the simplest possible concepts: less-than-1 concurrency
+feedback per delivery, forward and reverse concurrency feedback
+hysteresis, and pseudo-cohort failure. At this same time, concurrency
+feedback was separated from dead site detection.
+
+<li> These simplifications, and their modular implementation, helped
+to develop further insights into the different roles that positive
+and negative concurrency feedback play, and helped to identify some
+worst-case scenarios.
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/SMTPD_ACCESS_README.html b/proto/SMTPD_ACCESS_README.html
new file mode 100644
index 0000000..ce38bc8
--- /dev/null
+++ b/proto/SMTPD_ACCESS_README.html
@@ -0,0 +1,439 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix SMTP relay and access control </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+SMTP relay and access control </h1>
+
+<hr>
+
+<h2> Introduction </h2>
+
+<p> The Postfix SMTP server receives mail from the network and is
+exposed to the big bad world of junk email and viruses. This document
+introduces the built-in and external methods that control what SMTP
+mail Postfix will accept, what mistakes to avoid, and how to test
+your configuration. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li> <a href="#relay"> Relay control, junk mail control, and per-user
+policies </a>
+
+<li> <a href="#global"> Restrictions that apply to all SMTP mail
+</a>
+
+<li> <a href="#lists"> Getting selective with SMTP access restriction
+lists </a>
+
+<li> <a href="#timing"> Delayed evaluation of SMTP access restriction lists </a>
+
+<li> <a href="#danger"> Dangerous use of smtpd_recipient_restrictions
+</a>
+
+<li> <a href="#testing"> SMTP access rule testing </a>
+
+</ul>
+
+<h2> <a name="relay"> Relay control, junk mail control, and per-user
+policies </a> </h2>
+
+<p> In a distant past, the Internet was a friendly environment.
+Mail servers happily forwarded mail on behalf of anyone towards
+any destination. On today's Internet, spammers abuse servers that
+forward mail from arbitrary systems, and abused systems end up on
+anti-spammer denylists. See, for example, the information on
+http://www.mail-abuse.org/ and other websites. </p>
+
+<p> By default, Postfix has a moderately restrictive approach to
+mail relaying. Postfix forwards mail only from clients in trusted
+networks, from clients that have authenticated with SASL, or to
+domains that are configured as authorized relay
+destinations. For a description of the default mail relay policy,
+see the smtpd_relay_restrictions parameter in the postconf(5) manual
+page, and the information that is referenced from there. </p>
+
+<blockquote> <p> NOTE: Postfix versions before 2.10 did not have
+smtpd_relay_restrictions. They combined the mail relay and spam
+blocking policies, under smtpd_recipient_restrictions. This could
+lead to unexpected results. For example, a permissive spam blocking
+policy could unexpectedly result in a permissive mail relay policy.
+An example of this is documented under "<a href="#danger">Dangerous
+use of smtpd_recipient_restrictions</a>". </p> </blockquote>
+
+<p> Most of the Postfix SMTP server access controls are targeted
+at stopping junk email. </p>
+
+<ul>
+
+<li> <p> Protocol oriented: some SMTP server access controls block
+mail by being very strict with respect to the SMTP protocol; these
+catch poorly implemented and/or poorly configured junk email
+software, as well as email worms that come with their own non-standard
+SMTP client implementations. Protocol-oriented access controls
+become less useful over time as spammers and worm writers learn to
+read RFC documents. </p>
+
+<li> <p> Denylist oriented: some SMTP server access controls
+query denylists with known to be bad sites such as open mail
+relays, open web proxies, and home computers that have been
+compromised and that are under remote control by criminals. The
+effectiveness of these denylists depends on how complete and how
+up to date they are. </p>
+
+<li> <p> Threshold oriented: some SMTP server access controls attempt
+to raise the bar by either making the client do more work (greylisting)
+or by asking for a second opinion (SPF and sender/recipient address
+verification). The greylisting and SPF policies are implemented
+externally, and are the subject of the SMTPD_POLICY_README document.
+Sender/recipient address verification is the subject of the
+ADDRESS_VERIFICATION_README document. </p>
+
+</ul>
+
+<p> Unfortunately, all junk mail controls have the possibility of
+falsely rejecting legitimate mail. This can be a problem for sites
+with many different types of users. For some users it is unacceptable
+when any junk email slips through, while for other users the world
+comes to an end when a single legitimate email message is blocked.
+Because there is no single policy that is "right" for all users,
+Postfix supports different SMTP access restrictions for different
+users. This is described in the RESTRICTION_CLASS_README document.
+</p>
+
+<h2> <a name="global"> Restrictions that apply to all SMTP mail </a> </h2>
+
+<p> Besides the restrictions that can be made configurable per
+client or per user as described in the next section, Postfix
+implements a few restrictions that apply to all SMTP mail. </p>
+
+<ul>
+
+<li> <p> The built-in header_checks and body_checks content
+restrictions, as described in the BUILTIN_FILTER_README document.
+This happens while Postfix receives mail, before it is stored in
+the incoming queue. </p>
+
+<li> <p> The external before-queue content restrictions, as described
+in the SMTPD_PROXY_README document. This happens while Postfix
+receives mail, before it is stored in the incoming queue. </p>
+
+<li> <p> Requiring that the client sends the HELO or EHLO command
+before sending the MAIL FROM or ETRN command. This may cause problems
+with home-grown applications that send mail. For this reason, the
+requirement is disabled by default ("smtpd_helo_required = no").
+</p>
+
+<li> <p> Disallowing illegal syntax in MAIL FROM or RCPT TO commands.
+This may cause problems with home-grown applications that send
+mail, and with ancient PC mail clients. For this reason, the
+requirement is disabled by default ("strict_rfc821_envelopes =
+no"). </p>
+
+<ul>
+
+<li> <p> Disallowing RFC 822 address syntax (example: "MAIL FROM: the
+dude &lt;dude@example.com&gt;"). </p>
+
+<li> <p> Disallowing addresses that are not enclosed with &lt;&gt;
+(example: "MAIL FROM: dude@example.com"). </p>
+
+</ul>
+
+<li> <p> Rejecting mail from a non-existent sender address. This form
+of egress filtering helps to slow down worms and other malware, but
+may cause problems with home-grown software that sends out mail
+software with an unreplyable address. For this reason the requirement
+is disabled by default ("smtpd_reject_unlisted_sender = no"). </p>
+
+<li> <p> Rejecting mail for a non-existent recipient address. This
+form of ingress filtering helps to keep the mail queue free of
+undeliverable MAILER-DAEMON messages. This requirement is enabled
+by default ("smtpd_reject_unlisted_recipient = yes"). </p>
+
+</ul>
+
+<h2> <a name="lists"> Getting selective with SMTP access restriction
+lists </a> </h2>
+
+<p> Postfix allows you to specify lists of access restrictions for
+each stage of the SMTP conversation. Individual restrictions are
+described in the postconf(5) manual page. </p>
+
+<p> Examples of simple restriction lists are: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Allow connections from trusted networks only.
+ smtpd_client_restrictions = permit_mynetworks, reject
+
+ # Don't talk to mail systems that don't know their own hostname.
+ # With Postfix &lt; 2.3, specify reject_unknown_hostname.
+ smtpd_helo_restrictions = reject_unknown_helo_hostname
+
+ # Don't accept mail from domains that don't exist.
+ smtpd_sender_restrictions = reject_unknown_sender_domain
+
+ # Spam control: exclude local clients and authenticated clients
+ # from DNSBL lookups.
+ smtpd_recipient_restrictions = permit_mynetworks,
+ permit_sasl_authenticated,
+ # reject_unauth_destination is not needed here if the mail
+ # relay policy is specified under smtpd_relay_restrictions
+ # (available with Postfix 2.10 and later).
+ reject_unauth_destination
+ reject_rbl_client zen.spamhaus.org,
+ reject_rhsbl_reverse_client dbl.spamhaus.org,
+ reject_rhsbl_helo dbl.spamhaus.org,
+ reject_rhsbl_sender dbl.spamhaus.org
+
+ # Relay control (Postfix 2.10 and later): local clients and
+ # authenticated clients may specify any destination domain.
+ smtpd_relay_restrictions = permit_mynetworks,
+ permit_sasl_authenticated,
+ reject_unauth_destination
+
+ # Block clients that speak too early.
+ smtpd_data_restrictions = reject_unauth_pipelining
+
+ # Enforce mail volume quota via policy service callouts.
+ smtpd_end_of_data_restrictions = check_policy_service unix:private/policy
+</pre>
+
+<p> Each restriction list is evaluated from left to right until
+some restriction produces a result of PERMIT, REJECT or DEFER (try
+again later). The end of each list is equivalent to a PERMIT result.
+By placing a PERMIT restriction before a REJECT restriction you
+can make exceptions for specific clients or users. This is called
+allowlisting; the smtpd_relay_restrictions example above allows mail from local
+networks, and from SASL authenticated clients, but otherwise rejects mail
+to arbitrary destinations. </p>
+
+<p> The table below summarizes the purpose of each SMTP access
+restriction list. All lists use the exact same syntax; they differ
+only in the time of evaluation and in the effect of a REJECT or
+DEFER result. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Restriction list name </th> <th> Version </th> <th> Status
+</th> <th> Effect
+of REJECT or DEFER result </th> </tr>
+
+<tr> <td> smtpd_client_restrictions </td> <td> All </td> <td>
+Optional </td> <td>
+Reject all client commands </td> </tr>
+
+<tr> <td> smtpd_helo_restrictions </td> <td> All </td> <td> Optional
+</td> <td>
+Reject HELO/EHLO information </td> </tr>
+
+<tr> <td> smtpd_sender_restrictions </td> <td> All </td> <td>
+Optional </td> <td>
+Reject MAIL FROM information </td> </tr>
+
+<tr> <td rowspan="2"> smtpd_recipient_restrictions </td> <td> &ge;
+2.10 </td> <td> Required if smtpd_relay_restrictions does not enforce
+relay policy</td>
+<td rowspan="2"> Reject RCPT TO information </td> </tr>
+
+<tr> <td> &lt; 2.10</td> <td> Required </td> </tr>
+
+<tr> <td rowspan="2"> smtpd_relay_restrictions </td> <td> &ge; 2.10
+</td> <td> Required if smtpd_recipient_restrictions does not enforce
+relay policy</td>
+<td rowspan="2"> Reject RCPT TO information </td> </tr>
+
+<tr> <td> &lt; 2.10</td> <td> Not available </td>
+</tr>
+
+<tr> <td> smtpd_data_restrictions </td> <td> &ge; 2.0 </td> <td>
+Optional </td> <td>
+Reject DATA command </td> </tr>
+
+<tr> <td> smtpd_end_of_data_restrictions </td> <td> &ge; 2.2 </td>
+<td> Optional </td> <td>
+Reject END-OF-DATA command </td> </tr>
+
+<tr> <td> smtpd_etrn_restrictions </td> <td> All </td> <td> Optional
+</td> <td>
+Reject ETRN command </td> </tr>
+
+</table>
+
+</blockquote>
+
+<h2> <a name="timing"> Delayed evaluation of SMTP access restriction lists
+</a> </h2>
+
+<p> Early Postfix versions evaluated SMTP access restrictions lists
+as early as possible. The client restriction list was evaluated
+before Postfix sent the "220 $myhostname..." greeting banner to
+the SMTP client, the helo restriction list was evaluated before
+Postfix replied to the HELO (EHLO) command, the sender restriction
+list was evaluated before Postfix replied to the MAIL FROM command,
+and so on. This approach turned out to be difficult to use. </p>
+
+<p> Current Postfix versions postpone the evaluation of client,
+helo and sender restriction lists until the RCPT TO or ETRN command.
+This behavior is controlled by the smtpd_delay_reject parameter.
+Restriction lists are still evaluated in the proper order of (client,
+helo, etrn) or (client, helo, sender, relay, recipient, data, or
+end-of-data) restrictions.
+When a restriction list (example: client) evaluates to REJECT or
+DEFER the restriction lists that follow (example: helo, sender, etc.)
+are skipped. </p>
+
+<p> Around the time that smtpd_delay_reject was introduced, Postfix
+was also changed to support mixed restriction lists that combine
+information about the client, helo, sender and recipient or etrn
+command. </p>
+
+<p> Benefits of delayed restriction evaluation, and of restriction
+mixing: </p>
+
+<ul>
+
+<li> <p> Some SMTP clients do not expect a negative reply early in
+the SMTP session. When the bad news is postponed until the RCPT TO
+reply, the client goes away as it is supposed to, instead of hanging
+around until a timeout happens, or worse, going into an endless
+connect-reject-connect loop. </p>
+
+<li> <p> Postfix can log more useful information. For example, when
+Postfix rejects a client name or address and delays the action
+until the RCPT TO command, it can log the sender and the recipient
+address. This is more useful than logging only the client hostname
+and IP address and not knowing whose mail was being blocked. </p>
+
+<li> <p> Mixing is needed for complex allowlisting policies. For
+example, in order to reject local sender addresses in mail from
+non-local clients, you need to be able to mix restrictions on client
+information with restrictions on sender information in the same
+restriction list. Without this ability, many per-user access
+restrictions would be impossible to express. </p>
+
+</ul>
+
+<h2> <a name="danger"> Dangerous use of smtpd_recipient_restrictions </a> </h2>
+
+<p> By now the reader may wonder why we need smtpd client, helo
+or sender restrictions, when their evaluation is postponed until
+the RCPT TO or ETRN command. Some people recommend placing ALL the
+access restrictions in the smtpd_recipient_restrictions list.
+Unfortunately, this can result in too permissive access. How is
+this possible? </p>
+
+<p> The purpose of the smtpd_recipient_restrictions feature is to
+control how Postfix replies to the RCPT TO command. If the restriction
+list evaluates to REJECT or DEFER, the recipient address is rejected;
+no surprises here. If the result is PERMIT, then the recipient
+address is accepted. And this is where surprises can happen. </p>
+
+<p> The problem is that Postfix versions before 2.10 did not have
+smtpd_relay_restrictions. They combined the mail relay and spam
+blocking policies, under smtpd_recipient_restrictions. The result
+is that a permissive spam blocking policy could unexpectedly result
+in a permissive mail relay policy. </p>
+
+<p> Here is an example that shows when a PERMIT result can result
+in too much access permission: </p>
+
+<pre>
+1 /etc/postfix/main.cf:
+2 smtpd_recipient_restrictions =
+3 permit_mynetworks
+4 check_helo_access hash:/etc/postfix/helo_access
+5 reject_unknown_helo_hostname
+6 <b>reject_unauth_destination</b>
+7
+8 /etc/postfix/helo_access:
+9 localhost.localdomain PERMIT
+</pre>
+
+<p> Line 5 rejects mail from hosts that don't specify a proper
+hostname in the HELO command (with Postfix &lt; 2.3, specify
+reject_unknown_hostname). Lines 4 and 9 make an exception to
+allow mail from some machine that announces itself with "HELO
+localhost.localdomain". </p>
+
+<p> The problem with this configuration is that
+smtpd_recipient_restrictions evaluates to PERMIT for EVERY host
+that announces itself as "localhost.localdomain", making Postfix
+an open relay for all such hosts. </p>
+
+<p> With Postfix before version 2.10 you should place non-recipient
+restrictions AFTER the reject_unauth_destination restriction, not
+before. In the above example, the HELO based restrictions should
+be placed AFTER reject_unauth_destination, or better, the HELO
+based restrictions should be placed under smtpd_helo_restrictions
+where they can do no harm. </p>
+
+<pre>
+1 /etc/postfix/main.cf:
+2 smtpd_recipient_restrictions =
+3 permit_mynetworks
+4 <b>reject_unauth_destination</b>
+5 check_helo_access hash:/etc/postfix/helo_access
+6 reject_unknown_helo_hostname
+7
+8 /etc/postfix/helo_access:
+9 localhost.localdomain PERMIT
+</pre>
+
+<p> The above mistake will not happen with Postfix 2.10 and later,
+when the relay policy is specified under smtpd_relay_restrictions,
+and the spam blocking policy under smtpd_recipient_restrictions.
+Then, a permissive spam blocking policy will not result in a
+permissive mail relay policy. </p>
+
+<h2> <a name="testing"> SMTP access rule testing </a> </h2>
+
+<p> Postfix has several features that aid in SMTP access rule
+testing: </p>
+
+<dl>
+
+<dt> soft_bounce </dt> <dd> <p> This is a safety net that changes
+SMTP server REJECT actions into DEFER (try again later) actions.
+This keeps mail queued that would otherwise be returned to the
+sender. Specify "soft_bounce = yes" in the main.cf file to prevent
+the Postfix SMTP server from rejecting mail permanently, by changing
+all 5xx SMTP reply codes into 4xx. </p> </dd>
+
+<dt> warn_if_reject </dt> <dd> <p> When placed before a reject-type
+restriction, access table query, or check_policy_service query,
+this logs a "reject_warning" message instead of rejecting a request
+(when a reject-type restriction fails due to a temporary error,
+this logs a "reject_warning" message for any implicit "defer_if_permit"
+actions that would normally prevent mail from being accepted by
+some later access restriction). This feature has no effect on
+defer_if_reject restrictions. </p> </dd>
+
+<dt> XCLIENT </dt> <dd> <p> With this feature, an authorized SMTP
+client can impersonate other systems and perform realistic SMTP
+access rule tests. Examples of how to impersonate other systems
+for access rule testing are given at the end of the XCLIENT_README
+document. <br> This feature is available in Postfix 2.1. </p>
+</dd>
+
+</dl>
+
+</body>
+
+</html>
diff --git a/proto/SMTPD_POLICY_README.html b/proto/SMTPD_POLICY_README.html
new file mode 100644
index 0000000..b8df76e
--- /dev/null
+++ b/proto/SMTPD_POLICY_README.html
@@ -0,0 +1,811 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix SMTP Access Policy Delegation </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix SMTP Access Policy Delegation </h1>
+
+<hr>
+
+<h2>Purpose of Postfix SMTP access policy delegation</h2>
+
+<p> The Postfix SMTP server has a number of built-in mechanisms to
+block or accept mail at specific SMTP protocol stages. In addition,
+the Postfix SMTP server can delegate decisions to an external policy
+server (Postfix 2.1 and later). </p>
+
+<p> With this policy delegation mechanism, a simple
+<a href="#greylist">greylist</a> policy can be implemented with only a dozen lines of
+Perl, as is shown at the end of this document. A complete example
+can be found in the Postfix source code, in the directory
+examples/smtpd-policy. </p>
+
+<p> Another example of policy delegation is the SPF policy server
+at https://web.archive.org/web/20190221142057/http://www.openspf.org/Software. </p>
+
+<p> Policy delegation is now the preferred method for adding policies
+to Postfix. It's much easier to develop a new feature in few lines
+of Perl, Python, Ruby, or TCL, than trying to do the same in C code.
+The difference in
+performance will be unnoticeable except in the most demanding
+environments. On active systems a policy daemon process is used
+multiple times, for up to $max_use incoming SMTP connections. </p>
+
+<p> This document covers the following topics: </p>
+
+<ul>
+
+<li><a href="#protocol">Policy protocol description</a>
+
+<li><a href="#client_config">Simple policy client/server configuration</a>
+
+<li><a href="#advanced">Advanced policy client configuration</a>
+
+<li><a href="#greylist">Example: greylist policy server</a>
+
+<li><a href="#frequent">Greylisting mail from frequently forged domains</a>
+
+<li><a href="#all_mail">Greylisting all your mail</a>
+
+<li><a href="#maintenance">Routine greylist maintenance</a>
+
+<li><a href="#greylist_code">Example Perl greylist server</a>
+
+</ul>
+
+<h2><a name="protocol">Protocol description</a></h2>
+
+<p> The Postfix policy delegation protocol is really simple. The client
+sends a request and the server sends a response. Unless there was an
+error, the server must not close the connection, so that the same
+connection can be used multiple times. </p>
+
+<p> The client request is a sequence of name=value attributes separated
+by newline, and is terminated by an empty line. The server reply is one
+name=value attribute and it, too, is terminated by an empty line. </p>
+
+<p> Here is an example of all the attributes that the Postfix SMTP
+server sends in a delegated SMTPD access policy request: </p>
+
+<blockquote>
+<pre>
+<b>Postfix version 2.1 and later:</b>
+request=smtpd_access_policy
+protocol_state=RCPT
+protocol_name=SMTP
+helo_name=some.domain.tld
+queue_id=8045F2AB23
+sender=foo@bar.tld
+recipient=bar@foo.tld
+recipient_count=0
+client_address=1.2.3.4
+client_name=another.domain.tld
+reverse_client_name=another.domain.tld
+instance=123.456.7
+<b>Postfix version 2.2 and later:</b>
+sasl_method=plain
+sasl_username=you
+sasl_sender=
+size=12345
+ccert_subject=solaris9.porcupine.org
+ccert_issuer=Wietse+20Venema
+ccert_fingerprint=C2:9D:F4:87:71:73:73:D9:18:E7:C2:F3:C1:DA:6E:04
+<b>Postfix version 2.3 and later:</b>
+encryption_protocol=TLSv1/SSLv3
+encryption_cipher=DHE-RSA-AES256-SHA
+encryption_keysize=256
+etrn_domain=
+<b>Postfix version 2.5 and later:</b>
+stress=
+<b>Postfix version 2.9 and later:</b>
+ccert_pubkey_fingerprint=68:B3:29:DA:98:93:E3:40:99:C7:D8:AD:5C:B9:C9:40
+<b>Postfix version 3.0 and later:</b>
+client_port=1234
+<b>Postfix version 3.1 and later:</b>
+policy_context=submission
+<b>Postfix version 3.2 and later:</b>
+server_address=10.3.2.1
+server_port=54321
+[empty line]
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+ <li> <p> The "request" attribute is required. In this example
+ the request type is "smtpd_access_policy". </p>
+
+ <li> <p> The order of the attributes does not matter. The policy
+ server should ignore any attributes that it does not care about.
+ </p>
+
+ <li> <p> When the same attribute name is sent more than once,
+ the server may keep the first value or the last attribute value.
+ </p>
+
+ <li> <p> When an attribute value is unavailable, the client
+ either does not send the attribute, sends the attribute with
+ an empty value ("name="), or sends a zero value ("name=0") in
+ the case of a numerical attribute. </p>
+
+ <li> <p> The "recipient" attribute is available in the "RCPT
+ TO" stage. It is also available in the "DATA" and "END-OF-MESSAGE"
+ stages if Postfix accepted only one recipient for the current
+ message.
+ The DATA protocol state also applies to email that is received
+ with BDAT commands (Postfix 3.4 and later). </p>
+
+ <li> <p> The "recipient_count" attribute (Postfix 2.3 and later)
+ is non-zero only in the "DATA" and "END-OF-MESSAGE" stages. It
+ specifies the number of recipients that Postfix accepted for
+ the current message.
+ The DATA protocol state also applies to email that is received
+ with BDAT commands (Postfix 3.4 and later). </p>
+
+ <li> <p> The remote client or local server IP address is an
+ IPv4 dotted quad in the form 1.2.3.4 or it is an IPv6 address
+ in the form 1:2:3::4:5:6. </p>
+
+ <li> <p> The remote client or local server port is a decimal
+ number in the range 0-65535. </p>
+
+ <li> <p> For a discussion of the differences between reverse
+ and verified client_name information, see the
+ reject_unknown_client_hostname discussion in the postconf(5)
+ document. </p>
+
+ <li> <p> An attribute name must not contain "=", null or newline,
+ and an attribute value must not contain null or newline. </p>
+
+ <li> <p> The "instance" attribute value can be used to correlate
+ different requests regarding the same message delivery. These
+ requests are sent over the same policy connection (unless the
+ policy daemon terminates the connection). Once Postfix sends
+ a query with a different instance attribute over that same
+ policy connection, the previous message delivery is either
+ completed or aborted. </p>
+
+ <li> <p> The "size" attribute value specifies the message size
+ that the client specified in the MAIL FROM command (zero if
+ none was specified). With Postfix 2.2 and later, it specifies
+ the actual message size after the client sends the END-OF-MESSAGE.
+ </p>
+
+ <li> <p> The "sasl_*" attributes (Postfix 2.2 and later) specify
+ information about how the client was authenticated via SASL.
+ These attributes are empty in case of no SASL authentication.
+ </p>
+
+ <li> <p> The "ccert_*" attributes (Postfix 2.2 and later) specify
+ information about how the client was authenticated via TLS.
+ These attributes are empty in case of no certificate authentication.
+ As of Postfix 2.2.11 these attribute values are encoded as
+ xtext: some characters are represented by +XX, where XX is the
+ two-digit hexadecimal representation of the character value. With
+ Postfix 2.6 and later, the decoded string is an UTF-8 string
+ without non-printable ASCII characters. </p>
+
+ <li> <p> The "encryption_*" attributes (Postfix 2.3 and later)
+ specify information about how the connection is encrypted. With
+ plaintext connections the protocol and cipher attributes are
+ empty and the keysize is zero. </p>
+
+ <li> <p> The "etrn_domain" attribute is defined only in the
+ context of the ETRN command, and specifies the ETRN command
+ parameter. </p>
+
+ <li> <p> The "stress" attribute is either empty or "yes". See
+ the STRESS_README document for further information. </p>
+
+ <li> <p> The "policy_context" attribute provides a way to pass
+ information that is not available via other attributes (Postfix
+ version 3.1 and later). </p>
+
+</ul>
+
+<p> The following is specific to SMTPD delegated policy requests:
+</p>
+
+<ul>
+
+ <li> <p> Protocol names are ESMTP or SMTP. </p>
+
+ <li> <p> Protocol states are CONNECT, EHLO, HELO, MAIL, RCPT,
+ DATA, END-OF-MESSAGE, VRFY or ETRN; these are the SMTP protocol
+ states where
+ the Postfix SMTP server makes an OK/REJECT/HOLD/etc. decision.
+ The DATA protocol state also applies to email that is received
+ with BDAT commands (Postfix 3.4 and later).
+ </p>
+
+</ul>
+
+<p> The policy server replies with any action that is allowed in a
+Postfix SMTPD access(5) table. Example: </p>
+
+<blockquote>
+<pre>
+action=defer_if_permit Service temporarily unavailable
+[empty line]
+</pre>
+</blockquote>
+
+<p> This causes the Postfix SMTP server to reject the request with
+a 450 temporary error code and with text "Service temporarily
+unavailable", if the Postfix SMTP server finds no reason to reject
+the request permanently. </p>
+
+<p> In case of trouble the policy server must not send a reply.
+Instead the server must log a warning and disconnect. Postfix will
+retry the request at some later time. </p>
+
+<h2><a name="client_config">Simple policy client/server configuration</a></h2>
+
+<p> The Postfix delegated policy client can connect to a TCP socket
+or to a UNIX-domain socket. Examples: </p>
+
+<blockquote>
+<pre>
+inet:127.0.0.1:9998
+unix:/some/where/policy
+unix:private/policy
+</pre>
+</blockquote>
+
+<p> The first example specifies that the policy server listens on
+a TCP socket at 127.0.0.1 port 9998. The second example specifies
+an absolute pathname of a UNIX-domain socket. The third example
+specifies a pathname relative to the Postfix queue directory; use
+this for policy servers that are spawned by the Postfix master
+daemon. On many systems, "local" is a synonym for "unix".</p>
+
+<p> To create a policy service that listens on a UNIX-domain socket
+called "policy", and that runs under control of the Postfix spawn(8)
+daemon, you would use something like this: </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/master.cf:
+ 2 policy unix - n n - 0 spawn
+ 3 user=nobody argv=/some/where/policy-server
+ 4
+ 5 /etc/postfix/main.cf:
+ 6 smtpd_recipient_restrictions =
+ 7 ...
+ 8 reject_unauth_destination
+ 9 check_policy_service unix:private/policy
+10 ...
+11 policy_time_limit = 3600
+12 # smtpd_policy_service_request_limit = 1
+</pre>
+</blockquote>
+
+<p> NOTES: </p>
+
+<ul>
+
+<li> <p> Lines 2-3: this creates the service called "policy" that
+listens on a UNIX-domain socket. The service is implemented by the
+Postfix spawn(8) daemon, which executes the policy server program
+that is specified with the <b>argv</b> attribute, using the privileges
+specified with the <b>user</b> attribute. </p>
+
+<li> <p> Line 2: specify a "0" process limit instead of the default
+"-", to avoid "connection refused" and other problems when you
+increase the smtpd process limit. </p>
+
+<li> <p> Line 8: reject_unauth_destination is not needed here if
+the mail relay policy is specified with smtpd_relay_restrictions
+(available with Postfix 2.10 and later). </p>
+
+<li> <p> Lines 8, 9: always specify "check_policy_service" AFTER
+"reject_unauth_destination" or else your system could become an
+open relay. </p>
+
+<li> <p> Line 11: this increases the time that a policy server
+process may run to 3600 seconds. The default time limit of 1000
+seconds is too short; the policy daemon needs to run as long as the
+SMTP server process that talks to it.
+See the spawn(8) manpage for more information about the
+<i>transport</i>_time_limit parameter. </p>
+
+<blockquote> <p> Note: the "policy_time_limit" parameter will not
+show up in "postconf" command output before Postfix version 2.9.
+This limitation applies to many parameters whose name is a combination
+of a master.cf service name (in the above example, "policy") and a
+built-in suffix (in the above example: "_time_limit"). </p>
+</blockquote>
+
+<li> <p> Line 12: specify smtpd_policy_service_request_limit to
+avoid error-recovery delays with policy servers that cannot
+maintain a persistent connection. </p>
+
+<li> <p> With Solaris &lt; 9, or Postfix &lt; 2.10 on any Solaris
+version, use TCP sockets instead of UNIX-domain sockets: </p>
+
+</ul>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/master.cf:
+ 2 127.0.0.1:9998 inet n n n - 0 spawn
+ 3 user=nobody argv=/some/where/policy-server
+ 4
+ 5 /etc/postfix/main.cf:
+ 6 smtpd_recipient_restrictions =
+ 7 ...
+ 8 reject_unauth_destination
+ 9 check_policy_service inet:127.0.0.1:9998
+10 ...
+11 127.0.0.1:9998_time_limit = 3600
+12 # smtpd_policy_service_request_limit = 1
+</pre>
+</blockquote>
+
+<p> Configuration parameters that control the client side of the
+policy delegation protocol: </p>
+
+<ul>
+
+<li> <p> smtpd_policy_service_default_action (default: 451 4.3.5
+Server configuration problem): The default action when an SMTPD
+policy service request fails. Available with Postfix 3.0 and
+later. </p>
+
+<li> <p> smtpd_policy_service_max_idle (default: 300s): The amount
+of time before the Postfix SMTP server closes an unused policy
+client connection. </p>
+
+<li> <p> smtpd_policy_service_max_ttl (default: 1000s): The amount
+of time before the Postfix SMTP server closes an active policy
+client connection. </p>
+
+<li> <p> smtpd_policy_service_request_limit (default: 0): The maximal
+number of requests per policy connection, or zero (no limit).
+Available with Postfix 3.0 and later. </p>
+
+<li> <p> smtpd_policy_service_timeout (default: 100s): The time
+limit to connect to, send to or receive from a policy server. </p>
+
+<li> <p> smtpd_policy_service_try_limit (default: 2): The maximal
+number of attempts to send an SMTPD policy service request before
+giving up. Available with Postfix 3.0 and later. </p>
+
+<li> <p> smtpd_policy_service_retry_delay (default: 1s): The delay
+between attempts to resend a failed SMTPD policy service request.
+Available with Postfix 3.0 and later. </p>
+
+<li> <p> smtpd_policy_service_policy_context (default: empty):
+Optional information that is passed in the "policy_context" attribute
+of an SMTPD policy service request (originally, to share the same
+SMTPD service endpoint among multiple check_policy_service clients).
+Available with Postfix 3.1 and later. </p>
+
+</ul>
+
+<p> Configuration parameters that control the server side of the
+policy delegation protocol: </p>
+
+<ul>
+
+<li> <p> <i>transport</i>_time_limit ($command_time_limit): The
+maximal amount of time the policy daemon is allowed to run before
+it is terminated. The <i>transport</i> is the service name of the
+master.cf entry for the policy daemon service. In the above
+examples, the service name is "policy" or "127.0.0.1:9998". </p>
+
+</ul>
+
+<h2><a name="advanced">Advanced policy client configuration</a></h2>
+
+<p> The previous section lists a number of Postfix main.cf parameters
+that control time limits and other settings for all policy clients.
+This is sufficient for simple configurations. With more complex
+configurations it becomes desirable to have different settings per
+policy client. This is supported with Postfix 3.0 and later. </p>
+
+<p> The following example shows a "non-critical" policy service
+with a short timeout, and with "DUNNO" as default action when the
+service is unvailable. The "DUNNO" action causes Postfix to ignore
+the result. </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 mua_recipient_restrictions =
+3 ...
+4 reject_unauth_destination
+5 check_policy_service { inet:host:port,
+6 timeout=10s, default_action=DUNNO
+7 policy_context=submission }
+8 ...
+</pre>
+</blockquote>
+
+<p> Instead of a server endpoint, we now have a list enclosed in {}. </p>
+
+<ul>
+
+<li> <p> Line 5: The first item in the list is the server endpoint.
+This supports the exact same "inet" and "unix" syntax as described
+earlier. </p>
+
+<li> <p> Line 6-7: The remainder of the list contains per-client
+settings. These settings override global main.cf parameters,
+and have the same name as those parameters, without the
+"smtpd_policy_service_" prefix. </p>
+
+</ul>
+
+<p> Inside the list, syntax is similar to what we already know from
+main.cf: items separated by space or comma. There is one difference:
+<b>you must enclose a setting in parentheses, as in "{ name = value
+}", if you want to have space or comma within a value or around
+"="</b>. This comes in handy when different policy servers require
+different default actions with different SMTP status codes or text:
+</p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 smtpd_recipient_restrictions =
+3 ...
+4 reject_unauth_destination
+5 check_policy_service {
+6 inet:host:port1,
+7 { default_action = 451 4.3.5 See http://www.example.com/support1 }
+8 }
+9 ...
+</pre>
+</blockquote>
+
+<h2><a name="greylist">Example: greylist policy server</a></h2>
+
+<p> Greylisting is a defense against junk email that is described at
+http://www.greylisting.org/. The idea was discussed on the
+postfix-users mailing list <a
+href="http://archives.neohapsis.com/archives/postfix/2002-03/0846.html">
+one year before it was popularized</a>. </p>
+
+<p> The file examples/smtpd-policy/greylist.pl in the Postfix source
+tree implements a simplified greylist policy server. This server
+stores a time stamp for every (client, sender, recipient) triple.
+By default, mail is not accepted until a time stamp is more than
+60 seconds old. This stops junk mail with randomly selected sender
+addresses, and mail that is sent through randomly selected open
+proxies. It also stops junk mail from spammers that change their
+IP address frequently. </p>
+
+<p> Copy examples/smtpd-policy/greylist.pl to /usr/libexec/postfix
+or whatever location is appropriate for your system. </p>
+
+<p> In the greylist.pl Perl script you need to specify the
+location of the greylist database file, and how long mail will
+be delayed before it is accepted. The default settings are:
+</p>
+
+<blockquote>
+<pre>
+$database_name="/var/mta/greylist.db";
+$greylist_delay=60;
+</pre>
+</blockquote>
+
+<p> The /var/mta directory (or whatever you choose) should be
+writable by "nobody", or by whatever username you configure below
+in master.cf for the policy service. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+# mkdir /var/mta
+# chown nobody /var/mta
+</pre>
+</blockquote>
+
+<p> Note: DO NOT create the greylist database in a world-writable
+directory such as /tmp or /var/tmp, and DO NOT create the greylist
+database in a file system that may run out of space. Postfix can
+survive "out of space" conditions with the mail queue and with the
+mailbox store, but it cannot survive a corrupted greylist database.
+If the file becomes corrupted you may not be able to receive mail
+at all until you delete the file by hand. </p>
+
+<p> The greylist.pl Perl script can be run under control by
+the Postfix master daemon. For example, to run the script as user
+"nobody", using a UNIX-domain socket that is accessible by Postfix
+processes only: </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/master.cf:
+ 2 greylist unix - n n - 0 spawn
+ 3 user=nobody argv=/usr/bin/perl /usr/libexec/postfix/greylist.pl
+ 4
+ 5 /etc/postfix/main.cf:
+ 6 greylist_time_limit = 3600
+ 7 smtpd_recipient_restrictions =
+ 8 ...
+ 9 reject_unauth_destination
+10 check_policy_service unix:private/greylist
+11 ...
+12 # smtpd_policy_service_request_limit = 1
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Lines 2-3: this creates the service called "greylist" that
+listens on a UNIX-domain socket. The service is implemented by the
+Postfix spawn(8) daemon, which executes the greylist.pl script that
+is specified with the <b>argv</b> attribute, using the privileges
+specified with the <b>user</b> attribute. </p>
+
+<li> <p> Line 2: specify a "0" process limit instead of the default
+"-", to avoid "connection refused" and other problems when you
+increase the smtpd process limit. </p>
+
+<li> <p> Line 3: Specify "greylist.pl -v" for verbose logging of
+each request and reply. </p>
+
+<li> <p> Line 6: this increases the time that a greylist server
+process may run to 3600 seconds. The default time limit of 1000
+seconds is too short; the greylist daemon needs to run as long as the
+SMTP server process that talks to it.
+See the spawn(8) manpage for more information about the
+<i>transport</i>_time_limit parameter. </p>
+
+<li> <p> Line 9: reject_unauth_destination is not needed here if
+the mail relay policy is specified with smtpd_relay_restrictions
+(available with Postfix 2.10 and later). </p>
+
+<blockquote> <p> Note: the "greylist_time_limit" parameter will not
+show up in "postconf" command output before Postfix version 2.9.
+This limitation applies to many parameters whose name is a combination
+of a master.cf service name (in the above example, "greylist") and
+a built-in suffix (in the above example: "_time_limit"). </p>
+</blockquote>
+
+<li> <p> Line 12: specify smtpd_policy_service_request_limit to
+avoid error-recovery delays with policy servers that cannot
+maintain a persistent connection. </p>
+
+</ul>
+
+<p> With Solaris &lt; 9, or Postfix &lt; 2.10 on any Solaris
+version, use inet: style sockets instead of unix:
+style, as detailed in the "<a href="#client_config">Policy
+client/server configuration</a>" section above. </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/master.cf:
+ 2 127.0.0.1:9998 inet n n n - 0 spawn
+ 3 user=nobody argv=/usr/bin/perl /usr/libexec/postfix/greylist.pl
+ 4
+ 5 /etc/postfix/main.cf:
+ 6 127.0.0.1:9998_time_limit = 3600
+ 7 smtpd_recipient_restrictions =
+ 8 ...
+ 9 reject_unauth_destination
+10 check_policy_service inet:127.0.0.1:9998
+11 ...
+12 # smtpd_policy_service_request_limit = 1
+</pre>
+</blockquote>
+
+<h2><a name="frequent">Greylisting mail from frequently forged domains</a></h2>
+
+<p> It is relatively safe to turn on greylisting for specific
+domains that often appear in forged email. At some point
+in cyberspace/time a list of frequently
+forged MAIL FROM domains could be found at
+https://web.archive.org/web/20080526153208/http://www.monkeys.com/anti-spam/filtering/sender-domain-validate.in.
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 smtpd_recipient_restrictions =
+ 3 reject_unlisted_recipient
+ 4 ...
+ 5 reject_unauth_destination
+ 6 check_sender_access hash:/etc/postfix/sender_access
+ 7 ...
+ 8 smtpd_restriction_classes = greylist
+ 9 greylist = check_policy_service unix:private/greylist
+10
+11 /etc/postfix/sender_access:
+12 aol.com greylist
+13 hotmail.com greylist
+14 bigfoot.com greylist
+15 ... <i>etcetera</i> ...
+</pre>
+</blockquote>
+
+<p> NOTES: </p>
+
+<ul>
+
+<li> <p> Line 9: On Solaris &lt; 9, or Postfix &lt; 2.10 on any
+Solaris version, use inet: style sockets
+instead of unix: style, as detailed in the "<a href="#greylist">Example:
+greylist policy server</a>" section above. </p>
+
+<li> <p> Line 5: reject_unauth_destination is not needed here if
+the mail relay policy is specified with smtpd_relay_restrictions
+(available with Postfix 2.10 and later). </p>
+
+<li> <p> Line 6: Be sure to specify "check_sender_access" AFTER
+"reject_unauth_destination" or else your system could become an
+open mail relay. </p>
+
+<li> <p> Line 3: With Postfix 2.0 snapshot releases,
+"reject_unlisted_recipient" is called "check_recipient_maps".
+Postfix 2.1 understands both forms. </p>
+
+<li> <p> Line 3: The greylist database gets polluted quickly with
+bogus addresses. It helps if you protect greylist lookups with
+other restrictions that reject unknown senders and/or recipients.
+</p>
+
+</ul>
+
+<h2><a name="all_mail">Greylisting all your mail</a></h2>
+
+<p> If you turn on greylisting for all mail you may want to make
+exceptions for mailing lists that use one-time sender addresses,
+because each message will be delayed due to greylisting, and the
+one-time sender addresses can pollute your greylist database
+relatively quickly. Instead of making exceptions, you can automatically
+allowlist clients that survive greylisting repeatedly; this avoids
+most of the delays and most of the database pollution problem. </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 smtpd_recipient_restrictions =
+ 3 reject_unlisted_recipient
+ 4 ...
+ 5 reject_unauth_destination
+ 6 check_sender_access hash:/etc/postfix/sender_access
+ 7 check_policy_service unix:private/policy
+ 8 ...
+ 9
+10 /etc/postfix/sender_access:
+11 securityfocus.com OK
+12 ...
+</pre>
+</blockquote>
+
+<p> NOTES: </p>
+
+<ul>
+
+<li> <p> Line 7: On Solaris &lt; 9, or Postfix &lt; 2.10 on any
+Solaris version, use inet: style sockets
+instead of unix: style, as detailed in the "<a href="#greylist">Example:
+greylist policy server</a>" section above. </p>
+
+<li> <p> Line 5: reject_unauth_destination is not needed here if
+the mail relay policy is specified with smtpd_relay_restrictions
+(available with Postfix 2.10 and later). </p>
+
+<li> <p> Lines 6-7: Be sure to specify check_sender_access and
+check_policy_service AFTER reject_unauth_destination or else your
+system could become an open mail relay. </p>
+
+<li> <p> Line 3: The greylist database gets polluted quickly with
+bogus addresses. It helps if you precede greylist lookups with
+restrictions that reject unknown senders and/or recipients. </p>
+
+</ul>
+
+<h2><a name="maintenance">Routine greylist maintenance</a></h2>
+
+<p> The greylist database grows over time, because the greylist server
+never removes database entries. If left unattended, the greylist
+database will eventually run your file system out of space. </p>
+
+<p> When the status file size exceeds some threshold you can simply
+rename or remove the file without adverse effects; Postfix
+automatically creates a new file. In the worst case, new mail will
+be delayed by an hour or so. To lessen the impact, rename or remove
+the file in the middle of the night at the beginning of a weekend.
+</p>
+
+<h2><a name="greylist_code">Example Perl greylist server</a></h2>
+
+<p> This is the Perl subroutine that implements the example greylist
+policy. It is part of a general purpose sample policy server that
+is distributed with the Postfix source as
+examples/smtpd-policy/greylist.pl. </p>
+
+<pre>
+#
+# greylist status database and greylist time interval. DO NOT create the
+# greylist status database in a world-writable directory such as /tmp
+# or /var/tmp. DO NOT create the greylist database in a file system
+# that can run out of space.
+#
+$database_name="/var/mta/greylist.db";
+$greylist_delay=60;
+
+#
+# Auto-allowlist threshold. Specify 0 to disable, or the number of
+# successful "come backs" after which a client is no longer subject
+# to greylisting.
+#
+$auto_allowlist_threshold = 10;
+
+#
+# Demo SMTPD access policy routine. The result is an action just like
+# it would be specified on the right-hand side of a Postfix access
+# table. Request attributes are available via the %attr hash.
+#
+sub smtpd_access_policy {
+ my($key, $time_stamp, $now);
+
+ # Open the database on the fly.
+ open_database() unless $database_obj;
+
+ # Search the auto-allowlist.
+ if ($auto_allowlist_threshold &gt; 0) {
+ $count = read_database($attr{"client_address"});
+ if ($count &gt; $auto_allowlist_threshold) {
+ return "dunno";
+ }
+ }
+
+ # Lookup the time stamp for this client/sender/recipient.
+ $key =
+ lc $attr{"client_address"}."/".$attr{"sender"}."/".$attr{"recipient"};
+ $time_stamp = read_database($key);
+ $now = time();
+
+ # If new request, add this client/sender/recipient to the database.
+ if ($time_stamp == 0) {
+ $time_stamp = $now;
+ update_database($key, $time_stamp);
+ }
+
+ # The result can be any action that is allowed in a Postfix access(5) map.
+ #
+ # To label the mail, return ``PREPEND headername: headertext''
+ #
+ # In case of success, return ``DUNNO'' instead of ``OK'', so that the
+ # check_policy_service restriction can be followed by other restrictions.
+ #
+ # In case of failure, return ``DEFER_IF_PERMIT optional text...'',
+ # so that mail can still be blocked by other access restrictions.
+ #
+ syslog $syslog_priority, "request age %d", $now - $time_stamp if $verbose;
+ if ($now - $time_stamp &gt; $greylist_delay) {
+ # Update the auto-allowlist.
+ if ($auto_allowlist_threshold &gt; 0) {
+ update_database($attr{"client_address"}, $count + 1);
+ }
+ return "dunno";
+ } else {
+ return "defer_if_permit Service temporarily unavailable";
+ }
+}
+</pre>
+
+</body>
+
+</html>
diff --git a/proto/SMTPD_PROXY_README.html b/proto/SMTPD_PROXY_README.html
new file mode 100644
index 0000000..710183b
--- /dev/null
+++ b/proto/SMTPD_PROXY_README.html
@@ -0,0 +1,412 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Before-Queue Content Filter </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Before-Queue Content Filter </h1>
+
+<hr>
+
+<h2>WARNING </h2>
+
+<p> The before-queue content filtering feature described in this
+document limits the amount of mail that a site can handle. See the
+"<a href="#pros_cons">Pros and Cons</a>" section below for details.
+</p>
+
+<h2>The Postfix before-queue content filter feature</h2>
+
+<p> As of version 2.1, the Postfix SMTP server can forward all
+incoming mail to a content filtering proxy server that inspects all
+mail BEFORE it is stored in the Postfix mail queue. It is roughly
+equivalent in capabilities to the approach described in MILTER_README,
+except that the latter uses a dedicated protocol instead of SMTP.
+
+<p> The before-queue content filter is meant to be used as follows: </p>
+
+<blockquote>
+
+<table>
+
+<tr>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> Internet </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> <a href="smtpd.8.html">Postfix SMTP server</a>
+ </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> <b>Before</b> <b>queue</b> <b>filter</b> </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> <a href="smtpd.8.html">Postfix SMTP server</a>
+ </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> <a href="cleanup.8.html">Postfix cleanup
+ server</a> </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> Postfix queue </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&lt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> <a href="smtp.8.html">smtp</a><br> <a
+ href="local.8.html">local</a><br> <a
+ href="virtual.8.html">virtual</a> </td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<p> The before-queue content filter is not to be confused with the
+approach described in the FILTER_README document, where mail is
+filtered AFTER it is stored in the Postfix mail queue. </p>
+
+<p> This document describes the following topics: </p>
+
+<ul>
+
+<li><a href="#principles">Principles of operation</a>
+
+<li><a href="#pros_cons">Pros and cons of before-queue content filtering</a>
+
+<li><a href="#config">Configuring the Postfix SMTP pass-through
+proxy feature</a>
+
+<li><a href="#parameters">Configuration parameters</a>
+
+<li><a href="#protocol">How Postfix talks to the before-queue content
+filter</a>
+
+</ul>
+
+<h2><a name="principles">Principles of operation</a></h2>
+
+<p> As shown in the diagram above, the before-queue filter sits
+between two Postfix SMTP server processes. </p>
+
+<ul>
+
+<li> <p> The before-filter Postfix SMTP server accepts connections from the
+Internet and does the usual relay access control, SASL authentication,
+TLS negotiation,
+RBL lookups, rejecting non-existent sender or recipient addresses,
+etc. </p>
+
+<li> <p> The before-queue filter receives unfiltered mail content from
+Postfix and does one of the following: </p>
+
+<ol>
+
+ <li> <p> Re-inject the mail back into Postfix via SMTP, perhaps
+ after changing its content and/or destination. </p>
+
+ <li> <p> Discard or quarantine the mail. </p>
+
+ <li> <p> Reject the mail by sending a suitable SMTP status code
+ back to Postfix. Postfix passes the status back to the remote
+ SMTP client. This way, Postfix does not have to send a bounce
+ message. </p>
+
+</ol>
+
+<li> <p>The after-filter Postfix SMTP server receives mail from the
+content filter. From then on Postfix processes the mail as usual. </p>
+
+</ul>
+
+<p> The before-queue content filter described here works just like
+the after-queue content filter described in the FILTER_README
+document. In many cases you can use the same software, within the
+limitations as discussed in the "<a href="#pros_cons">Pros and
+Cons</a>" section below. </p>
+
+<h2><a name="pros_cons">Pros and cons of before-queue content
+filtering</a></h2>
+
+<ul>
+
+<li> <p> Pro: Postfix can reject mail before the incoming SMTP mail
+transfer completes, so that Postfix does not have to send rejected
+mail back to the sender (which is usually forged anyway). Mail
+that is not accepted remains the responsibility of the remote SMTP
+client. </p>
+
+<li> <p> Con: The remote SMTP client expects an SMTP reply within
+a deadline. As the system load increases, fewer and fewer CPU
+cycles remain available to answer within the deadline, and eventually
+you either have to stop accepting mail or you have to stop filtering
+mail. It is for this reason that the before-queue content filter
+limits the amount of mail that a site can handle. </p>
+
+<li> <p> Con: Content filtering software can use lots of memory
+resources. You have to reduce the number of simultaneous content
+filter processes so that a burst of mail will not drive your system
+into the ground. </p>
+
+<ul>
+
+<li> <p> With Postfix versions 2.7 and later, SMTP clients will
+experience an increase in the delay between the time the client
+sends "end-of-message" and the time the Postfix SMTP server replies
+(here, the number of before-filter SMTP server processes can be
+larger than the number of filter processes). </p>
+
+<li> <p> With Postfix versions before 2.7, SMTP clients will
+experience an increase in the delay before they can receive service
+(here, the number of before-filter SMTP server processes is always
+equal to the number of filter processes). </p>
+
+</ul>
+
+</ul>
+
+<h2><a name="config">Configuring the Postfix SMTP pass-through
+proxy feature</a></h2>
+
+<p> In the following example, the before-filter Postfix SMTP server
+gives mail to a content filter that listens on localhost port 10025.
+The after-filter Postfix SMTP server receives mail from the content
+filter via localhost port 10026. From then on mail is processed as
+usual. </p>
+
+<p> The content filter itself is not described here. You can use
+any filter that is SMTP enabled. For non-SMTP capable content
+filtering software, Bennett Todd's SMTP proxy implements a nice
+Perl-based framework. See:
+https://web.archive.org/web/20151022025756/http://bent.latency.net/smtpprox/
+or https://github.com/jnorell/smtpprox/ </p>
+
+<blockquote>
+
+<table border="0">
+
+<tr>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> Internet </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> <a href="smtpd.8.html">Postfix SMTP server on
+ port 25</a> </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> filter on localhost port 10025 </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> <a href="smtpd.8.html">Postfix SMTP server on
+ localhost port 10026</a> </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> <a href="cleanup.8.html">Postfix cleanup
+ server</a> </td>
+
+ <td align="center" valign="middle" width="5%"> <tt> -&gt; </tt> </td>
+
+ <td bgcolor="#f0f0ff" align="center" valign="middle"
+ width="10%"> Postfix incoming queue </td>
+
+</tr>
+
+</table>
+
+</blockquote>
+
+<p> This is configured by editing the master.cf file: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ # =============================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =============================================================
+ #
+ # Before-filter SMTP server. Receive mail from the network and
+ # pass it to the content filter on localhost port 10025.
+ #
+ smtp inet n - n - 20 smtpd
+ -o smtpd_proxy_filter=127.0.0.1:10025
+ -o smtpd_client_connection_count_limit=10
+ # Postfix 2.7 and later performance feature.
+ # -o smtpd_proxy_options=speed_adjust
+ #
+ # After-filter SMTP server. Receive mail from the content filter
+ # on localhost port 10026.
+ #
+ 127.0.0.1:10026 inet n - n - - smtpd
+ -o smtpd_authorized_xforward_hosts=127.0.0.0/8
+ -o smtpd_client_restrictions=
+ -o smtpd_helo_restrictions=
+ -o smtpd_sender_restrictions=
+ # Postfix 2.10 and later: specify empty smtpd_relay_restrictions.
+ -o smtpd_relay_restrictions=
+ -o smtpd_recipient_restrictions=permit_mynetworks,reject
+ -o smtpd_data_restrictions=
+ -o mynetworks=127.0.0.0/8
+ -o receive_override_options=no_unknown_recipient_checks
+</pre>
+</blockquote>
+
+<p> Note: do not specify spaces around the "=" or "," characters. </p>
+
+<p> The before-filter SMTP server entry is a modified version of the
+default Postfix SMTP server entry that is normally configured at
+the top of the master.cf file: </p>
+
+<ul>
+
+ <li> <p> The number of SMTP sessions is reduced from the default
+ 100 to only 20. This prevents a burst of mail from running your
+ system into the ground with too many content filter processes. </p>
+
+ <li> <p> The "-o smtpd_client_connection_count_limit=10" prevents
+ one SMTP client from using up all 20 SMTP server processes.
+ This limit is not necessary if you receive all mail from a
+ trusted relay host. </p>
+
+ <p> Note: this setting is available in Postfix version 2.2 and
+ later. Earlier Postfix versions will ignore it. </p>
+
+ <li> <p> The "-o smtpd_proxy_filter=127.0.0.1:10025" tells the
+ before-filter SMTP server that it should give incoming mail to
+ the content filter that listens on localhost TCP port 10025.
+
+ <li> <p> The "-o smtpd_proxy_options=speed_adjust" tells the
+ before-filter SMTP server that it should receive an entire email
+ message before it connects to a content filter. This reduces
+ the number of simultaneous filter processes. </p>
+
+ <p> NOTE 1: When this option is turned on, a content filter must
+ not <i>selectively</i> reject recipients of a multi-recipient
+ message. Rejecting all recipients is OK, as is accepting all
+ recipients. </p>
+
+ <p> NOTE 2: This feature increases the minimum amount of free
+ queue space by $message_size_limit. The extra space is needed
+ to save the message to a temporary file. </p>
+
+ <li> <p> Postfix &ge; 2.3 supports both TCP and UNIX-domain filters.
+ The above filter could be specified as "inet:127.0.0.1:10025".
+ To specify a UNIX-domain filter, specify "unix:<i>pathname</i>".
+ A relative pathname is interpreted relative to the Postfix queue
+ directory. </p>
+
+</ul>
+
+<p> The after-filter SMTP server is a new master.cf entry: </p>
+
+<ul>
+
+ <li> <p> The "127.0.0.1:10026" makes the after-filter SMTP
+ server listen
+ on the localhost address only, without exposing it to the
+ network. NEVER expose the after-filter SMTP server to the
+ Internet :-) </p>
+
+ <li> <p> The "-o smtpd_authorized_xforward_hosts=127.0.0.0/8"
+ allows the after-filter SMTP server to receive remote SMTP
+ client information from the before-filter SMTP server, so that
+ the after-filter Postfix daemons log the remote SMTP client
+ information instead of logging localhost[127.0.0.1]. </p>
+
+ <li> <p> The other after-filter SMTP server settings avoid
+ duplication of work that is already done in the "before filter"
+ SMTP server. </p>
+
+</ul>
+
+<p> By default, the filter has 100 seconds to do its work. If it
+takes longer then Postfix gives up and reports an error to the
+remote SMTP client. You can increase this time limit (see the <a href="#parameters">"Configuration
+parameters"</a> section below) but doing so is pointless because you
+can't control when the remote SMTP client times out. </p>
+
+<h2><a name="parameters">Configuration parameters</a></h2>
+
+<p> Parameters that control proxying: </p>
+
+<ul>
+
+<li> <p> smtpd_proxy_filter (syntax: host:port): The host and TCP
+port of the before-queue content filter. When no host or host:
+is specified here, localhost is assumed. </p>
+
+<li> <p> smtpd_proxy_timeout (default: 100s): Timeout for connecting
+to the before-queue content filter and for sending and receiving
+commands and data. All proxy errors are logged to the maillog
+file. For privacy reasons, all the remote SMTP client sees is "451
+Error: queue file write error". It would not be right to disclose
+internal details to strangers. </p>
+
+<li> <p> smtpd_proxy_ehlo (default: $myhostname): The hostname to
+use when sending an EHLO command to the before-queue content filter.
+</p>
+
+</ul>
+
+<h2><a name="protocol">How Postfix talks to the before-queue content
+filter</a></h2>
+
+<p> The before-filter Postfix SMTP server connects to the content
+filter, delivers one message, and disconnects. While sending mail
+into the content filter, Postfix speaks ESMTP but uses no command
+pipelining. Postfix generates its own EHLO, XFORWARD (for logging
+the remote client IP address instead of localhost[127.0.0.1]), DATA
+and QUIT commands, and forwards unmodified copies of all the MAIL
+FROM and RCPT TO commands that the before-filter Postfix SMTP server
+didn't reject itself.
+Postfix sends no other SMTP commands. </p>
+
+<p> The content filter should accept the same MAIL FROM and RCPT
+TO command syntax as the before-filter Postfix SMTP server, and
+should forward the commands without modification to the after-filter
+SMTP server. If the content filter or after-filter SMTP server
+does not support all the ESMTP features that the before-filter
+Postfix SMTP server supports, then the missing features must be
+turned off in the before-filter Postfix SMTP server with the
+smtpd_discard_ehlo_keywords parameter. </p>
+
+<p> When the filter rejects content, it should send a negative SMTP
+response back to the before-filter Postfix SMTP server, and it
+should abort the connection with the after-filter Postfix SMTP
+server without completing the SMTP conversation with the after-filter
+Postfix SMTP server. </p>
+
+</body>
+
+</html>
diff --git a/proto/SMTPUTF8_README.html b/proto/SMTPUTF8_README.html
new file mode 100644
index 0000000..c0e5608
--- /dev/null
+++ b/proto/SMTPUTF8_README.html
@@ -0,0 +1,399 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix SMTPUTF8 support</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">
+Postfix SMTPUTF8 support
+</h1>
+
+<hr>
+
+<h2> Overview </h2>
+
+<p> This document describes Postfix support for Email Address
+Internationalization (EAI) as defined in RFC 6531 (SMTPUTF8 extension),
+RFC 6532 (Internationalized email headers) and RFC 6533 (Internationalized
+delivery status notifications). Introduced with Postfix version
+3.0, this fully supports UTF-8 email addresses and UTF-8 message
+header values. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#building">Building with/without SMTPUTF8 support</a>
+
+<li><a href="#enabling">Enabling Postfix SMTPUTF8 support</a>
+
+<li><a href="#using">Using Postfix SMTPUTF8 support</a>
+
+<li><a href="#detecting">SMTPUTF8 autodetection</a>
+
+<li><a href="#limitations">Limitations of the current implementation</a>
+
+<li><a href="#compatibility">Compatibility with pre-SMTPUTF8 environments</a>
+
+<li><a href="#idna2003">Compatibility with IDNA2003</a>
+
+<li><a href="#credits">Credits</a>
+
+</ul>
+
+<h2> <a name="building">Building Postfix with/without SMTPUTF8 support</a> </h2>
+
+<p> Postfix will build with SMTPUTF8 support if the ICU version
+&ge; 46 library and header files are installed on the system. The
+package name varies with the OS distribution. The table shows package
+names for a number of platforms at the time this text was written.
+</p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> OS Distribution </th> <th> Package </th> </tr>
+
+<tr> <td> FreeBSD, NetBSD, etc. </td> <td> icu </td> </tr>
+
+<tr> <td> Centos, Fedora, RHEL </td> <td> libicu-devel </td> </tr>
+
+<tr> <td> Debian, Ubuntu </td> <td> libicu-dev </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> To force Postfix to build without SMTPUTF8, specify: </p>
+
+<blockquote>
+<pre>
+$ <b>make makefiles CCARGS="-DNO_EAI ..."</b>
+</pre>
+</blockquote>
+
+<p> See the INSTALL document for more "make makefiles" options. </p>
+
+<h2> <a name="enabling">Enabling Postfix SMTPUTF8 support</a> </h2>
+
+<p> There is more to SMTPUTF8 than just Postfix itself. The rest
+of your email infrastructure also needs to be able to handle UTF-8
+email addresses and message header values. This includes SMTPUTF8
+protocol support in SMTP-based content filters (Amavisd), LMTP
+servers (Dovecot), and down-stream SMTP servers. </p>
+
+<p> Postfix SMTPUTF8 support is enabled by default, but it may be
+disabled as part of a backwards-compatibility safety net (see the
+COMPATIBILITY_README file). </p>
+
+<p> SMTPUTF8 support is enabled by setting the smtputf8_enable
+parameter in main.cf:</p>
+
+<blockquote>
+<pre>
+# <b>postconf "smtputf8_enable = yes"</b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> (With Postfix &le; 3.1, you may also need to specify "<b>option_group
+= client</b>" in Postfix MySQL client files, to enable UTF8 support
+in MySQL queries. This setting is the default as of Postfix 3.2.) </p>
+
+<p> With SMTPUTF8 support enabled, Postfix changes behavior with
+respect to earlier Postfix releases: </p>
+
+<ul>
+
+<li> <p> UTF-8 is permitted in the myorigin parameter value. However,
+the myhostname and mydomain parameters must currently specify
+ASCII-only domain names. This limitation may be removed later. </p>
+
+<li> <p> UTF-8 is the only form of non-ASCII text that Postfix
+supports in access tables, address rewriting tables, and other
+tables that are indexed with an email address, hostname, or domain
+name. </p>
+
+<li> <p> The header_checks-like and body_checks-like features are
+not UTF-8 enabled, and therefore they do not enforce UTF-8 syntax
+rules on inputs and outputs. The reason is that non-ASCII text may
+be sent in encodings other than UTF-8, and that real email sometimes
+contains malformed headers. Instead of skipping non-UTF-8 content,
+Postfix should be able to filter it. You may try to enable UTF-8
+processing by starting a PCRE pattern with the sequence (*UTF8),
+but this is will result in "message not accepted, try again later"
+errors when the PCRE pattern matcher encounters non-UTF-8 input.
+Other features that are not UTF-8 enabled are smtpd_command_filter,
+smtp_reply_filter, the *_delivery_status_filter features, and the
+*_dns_reply_filter features (the latter because DNS is by definition
+an ASCII protocol). </p>
+
+<li> <p> The Postfix SMTP server announces SMTPUTF8 support in the
+EHLO response. </p>
+
+<pre>
+220 server.example.com ESMTP Postfix
+<b>EHLO client.example.com</b>
+250-server.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-VRFY
+250-ETRN
+250-STARTTLS
+250-AUTH PLAIN LOGIN
+250-ENHANCEDSTATUSCODES
+250-8BITMIME
+250-DSN
+250 SMTPUTF8
+</pre>
+
+<li> <p> The Postfix SMTP server accepts the SMTPUTF8 request in
+MAIL FROM and VRFY commands. </p>
+
+<pre>
+<b>MAIL FROM:&lt;address&gt; SMTPUTF8 ...</b>
+
+<b>VRFY address SMTPUTF8</b>
+</pre>
+
+<li> <p> The Postfix SMTP client may issue the SMTPUTF8 request in
+MAIL FROM commands. </p>
+
+<li> <p> The Postfix SMTP server accepts UTF-8 in email address
+domains, but only after the remote SMTP client issues the
+SMTPUTF8 request in MAIL FROM or VRFY commands. </p>
+
+</ul>
+
+<p> Postfix already permitted UTF-8 in message header values
+and in address localparts. This does not change. </p>
+
+<h2> <a name="using">Using Postfix SMTPUTF8 support</a> </h2>
+
+<p> After Postfix SMTPUTF8 support is turned on, Postfix behavior
+will depend on 1) whether a remote SMTP client requests SMTPUTF8
+support, 2) the presence of UTF-8 content in the message envelope
+and headers, and 3) whether a down-stream SMTP (or LMTP) server
+announces SMTPUTF8 support. </p>
+
+<ul>
+
+<li> <p> When the Postfix SMTP server receives a message WITHOUT
+the SMTPUTF8 request, Postfix handles the message as it has always
+done (at least that is the default, see autodetection below).
+Specifically, the Postfix SMTP server does not accept UTF-8 in the
+envelope sender domain name or envelope recipient domain name, and
+the Postfix SMTP client does not issue the SMTPUTF8 request when
+delivering that message to an SMTP or LMTP server that announces
+SMTPUTF8 support (again, that is the default). Postfix will accept
+UTF-8 in message header values and in the localpart of envelope
+sender and recipient addresses, because it has always done that.
+</p>
+
+<li> <p> When the Postfix SMTP server receives a message WITH the
+SMTPUTF8 request, Postfix will issue the SMTPUTF8 request when
+delivering that message to an SMTP or LMTP server that announces
+SMTPUTF8 support. This is not configurable. </p>
+
+<li> <p> When a message is received with the SMTPUTF8 request,
+Postfix will deliver the message to a non-SMTPUTF8 SMTP or LMTP
+server ONLY if: </p>
+
+ <ul>
+
+ <li> <p> No message header value contains UTF-8. </p>
+
+ <li> <p> The envelope sender address contains no UTF-8, </p>
+
+ <li> <p> No envelope recipient address for that specific
+ SMTP/LMTP delivery transaction contains UTF-8. </p>
+
+ <blockquote> <p> NOTE: Recipients in other email delivery
+ transactions for that same message may still contain UTF-8.
+ </p> </blockquote>
+
+ </ul>
+
+ <p> Otherwise, Postfix will return the recipient(s) for that
+ email delivery transaction as undeliverable. The delivery status
+ notification message will be an SMTPUTF8 message. It will therefore
+ be subject to the same restrictions as email that is received
+ with the SMTPUTF8 request. </p>
+
+<li> <p> When the Postfix SMTP server receives a message with the
+SMTPUTF8 request, that request also applies after the message is
+forwarded via a virtual or local alias, or $HOME/.forward file.
+</p>
+
+</ul>
+
+<h2> <a name="detecting">SMTPUTF8 autodetection</a> </h2>
+
+<p> This section applies only to systems that have SMTPUTF8 support
+turned on (smtputf8_enable = yes). </p>
+
+<p> For compatibility with pre-SMTPUTF8 environments, Postfix does
+not automatically set the "SMTPUTF8 requested" flag on messages
+from non-SMTPUTF8 clients that contain a UTF-8 header value or
+UTF-8 address localpart. This would make such messages undeliverable
+to non-SMTPUTF8 servers, and could be a barrier to SMTPUTF8 adoption.
+</p>
+
+<p> By default, Postfix sets the "SMTPUTF8 requested" flag only on
+address verification probes and on Postfix sendmail submissions
+that contain UTF-8 in the sender address, UTF-8 in a recipient
+address, or UTF-8 in a message header value. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtputf8_autodetect_classes = sendmail, verify
+</pre>
+</blockquote>
+
+<p> However, if you have a non-ASCII myorigin or mydomain setting,
+or if you have a configuration that introduces UTF-8 addresses with
+virtual aliases, canonical mappings, or BCC mappings, then you may
+have to apply SMTPUTF8 autodetection to all email: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtputf8_autodetect_classes = all
+</pre>
+</blockquote>
+
+<p> This will, of course, also flag email that was received without
+SMTPUTF8 request, but that contains UTF-8 in a sender address
+localpart, receiver address localpart, or message header value.
+Such email was not standards-compliant, but Postfix would have
+delivered it if SMTPUTF8 support was disabled. </p>
+
+<h2> <a name="limitations">Limitations of the current implementation</a>
+</h2>
+
+<p> The Postfix implementation is a work in progress; limitations
+are steadily being removed. The text below describes the situation
+at one point in time. </p>
+
+<h3> No automatic conversions between ASCII and UTF-8 domain names. </h3>
+
+<p> Some background: According to RFC 6530 and related documents,
+an internationalized domain name can appear in two forms: the UTF-8
+form, and the ASCII (xn--mumble) form. An internationalized address
+localpart must be encoded in UTF-8; the RFCs do not define an ASCII
+alternative form. </p>
+
+<p> Postfix currently does not convert internationalized domain
+names from UTF-8 into ASCII (or from ASCII into UTF-8) before using
+domain names in SMTP commands and responses, before looking up
+domain names in lists such as mydestination, relay_domains or in
+lookup tables such as access tables, etc., before using domain names
+in a policy daemon or Milter request, or before logging events.
+</p>
+
+<p> Postfix does, however, casefold domain names and email addresses
+before matching them against a Postfix configuration parameter or
+lookup table. </p>
+
+<p> In order to use Postfix SMTPUTF8 support: </p>
+
+<ul>
+
+<li> <p> The Postfix parameters myhostname and mydomain must be in
+ASCII form. One is a substring of the other, and the myhostname
+value is used in SMTP commands and responses that require ASCII.
+The parameter myorigin (added to local addresses without domain)
+supports UTF-8. </p>
+
+<li> <p> You need to configure both the ASCII and UTF-8 forms of
+an Internationalized domain name in Postfix parameters such as
+mydestination and relay_domains, as well as lookup table search
+keys. </p>
+
+<li> <p> Milters, content filters, policy servers and logfile
+analysis tools need to be able to handle both the ASCII and UTF-8
+forms of Internationalized domain names. </p>
+
+</ul>
+
+<h2> <a name="compatibility">Compatibility with pre-SMTPUTF8
+environments</a> </h2>
+
+<h3> Mailing lists with UTF-8 and non-UTF-8 subscribers </h3>
+
+<p> With Postfix, there is no need to split mailing lists into UTF-8 and
+non-UTF-8 members. Postfix will try to deliver the non-UTF8 subscribers
+over "traditional" non-SMTPUTF8 sessions, as long as the message
+has an ASCII envelope sender address and all-ASCII header values.
+The mailing list manager may have to apply RFC 2047 encoding to
+satisfy that last condition. </p>
+
+<h3> Pre-existing non-ASCII email flows </h3>
+
+<p> With "smtputf8_enable = no", Postfix handles email with non-ASCII
+in address localparts (and in headers) as before. The vast majority
+of email software is perfectly capable of handling such email, even
+if pre-SMTPUTF8 standards do not support such practice. </p>
+
+<h3> Rejecting non-UTF8 addresses </h3>
+
+<p> With "smtputf8_enable = yes", Postfix
+requires that non-ASCII address information is encoded in UTF-8 and
+will reject other encodings such as ISO-8859. It is not practical
+for Postfix to support multiple encodings at the same time. There
+is no problem with RFC 2047 encodings such as "=?ISO-8859-1?Q?text?=",
+because those use only characters from the ASCII characterset. </p>
+
+<h3> Rejecting non-ASCII addresses in non-SMTPUTF8 transactions </h3>
+
+<p> Setting "strict_smtputf8 = yes" in addition to "smtputf8_enable
+= yes" will enable stricter enforcement of the SMTPUTF8 protocol.
+Specifically, the Postfix SMTP server will not only reject non-UTF8
+sender or recipient addresses, it will in addition accept UTF-8
+sender or recipient addresses only when the client requests an
+SMTPUTF8 mail transaction. </p>
+
+<h2> <a name="idna2003">Compatibility with IDNA2003</a> </h2>
+
+<p> Postfix &ge; 3.2 by default disables the 'transitional'
+compatibility between IDNA2003 and IDNA2008, when converting UTF-8
+domain names to/from the ASCII form that is used in DNS lookups.
+This makes Postfix behavior consistent with current versions of the
+Firefox and Chrome web browsers. Specify "enable_idna2003_compatibility
+= yes" to get the historical behavior. </p>
+
+<p> This affects the conversion of domain names that contain for
+example the German sz (ß) and the Greek zeta (ς). See
+http://unicode.org/cldr/utility/idna.jsp for more examples. </p>
+
+<h2> <a name="credits">Credits</a> </h2>
+
+<ul>
+
+<li> <p> May 15, 2014: Arnt Gulbrandsen posted his patch for Unicode
+email support. This work was sponsored by CNNIC. </p>
+
+<li> <p> July 15, 2014: Wietse integrated Arnt Gulbrandsen's code
+and released Postfix with SMTPUTF8 support. </p>
+
+<li> <p> January 2015: Wietse added UTF-8 support for casefolding
+in Postfix lookup tables and caseless string comparison in Postfix
+list-based features. </p>
+
+</ul>
+
+</body>
+
+</html>
+
diff --git a/proto/SQLITE_README.html b/proto/SQLITE_README.html
new file mode 100644
index 0000000..598f80c
--- /dev/null
+++ b/proto/SQLITE_README.html
@@ -0,0 +1,114 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix SQLite Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix SQLite Howto</h1>
+
+<hr>
+
+<h2>Introduction</h2>
+
+<p> The Postfix sqlite map type allows you to hook up Postfix to a
+SQLite database. This implementation allows for multiple sqlite
+databases: you can use one for a virtual(5) table, one for an
+access(5) table, and one for an aliases(5) table if you want. </p>
+
+<h2>Building Postfix with SQLite support</h2>
+
+<p> The Postfix SQLite client utilizes the sqlite3 library,
+which can be obtained from: </p>
+
+<blockquote>
+ <p> http://www.sqlite.org/ </p>
+</blockquote>
+
+<p> In order to build Postfix with sqlite map support, you will
+need to add to CCARGS the flags -DHAS_SQLITE and -I with the directory
+containing the sqlite header files, and you will need to add to
+AUXLIBS the directory and name of the sqlite3 library, plus the
+name of the standard POSIX thread library (pthread). For example:
+</p>
+
+<blockquote>
+<pre>
+make -f Makefile.init makefiles \
+ 'CCARGS=-DHAS_SQLITE -I/usr/local/include' \
+ 'AUXLIBS_SQLITE=-L/usr/local/lib -lsqlite3 -lpthread'
+</pre>
+</blockquote>
+
+<p> If your SQLite shared library is in a directory that the RUN-TIME
+linker does not know about, add a "-Wl,-R,/path/to/directory" option after
+"-lsqlite3". </p>
+
+<p> Postfix versions before 3.0 use AUXLIBS instead of AUXLIBS_SQLITE.
+With Postfix 3.0 and later, the old AUXLIBS variable still supports
+building a statically-loaded SQLite database client, but only the new
+AUXLIBS_SQLITE variable supports building a dynamically-loaded or
+statically-loaded SQLite database client. </p>
+
+<blockquote>
+
+<p> Failure to use the AUXLIBS_SQLITE variable will defeat the purpose
+of dynamic database client loading. Every Postfix executable file
+will have SQLITE database library dependencies. And that was exactly
+what dynamic database client loading was meant to avoid. </p>
+
+</blockquote>
+
+<p> Then, just run 'make'.</p>
+
+<h2>Using SQLite tables</h2>
+
+<p> Once Postfix is built with sqlite support, you can specify a
+map type in main.cf like this: </p>
+
+<blockquote>
+<pre>
+alias_maps = sqlite:/etc/postfix/sqlite-aliases.cf
+</pre>
+</blockquote>
+
+<p> The file /etc/postfix/sqlite-aliases.cf specifies lots of
+information telling Postfix how to reference the sqlite database.
+For a complete description, see the sqlite_table(5) manual page. </p>
+
+<h2>Example: local aliases </h2>
+
+<pre>
+#
+# sqlite config file for local(8) aliases(5) lookups
+#
+
+# Path to database
+dbpath = /some/path/to/sqlite_database
+
+# See sqlite_table(5) for details.
+query = SELECT forw_addr FROM mxaliases WHERE alias='%s' AND status='paid'
+</pre>
+
+<h2>Credits</h2>
+
+<p> SQLite support was added with Postfix version 2.8. </p>
+
+<ul>
+
+<li>Implementation by Axel Steiner</li>
+<li>Documentation by Jesus Garcia Crespo</li>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/STANDARD_CONFIGURATION_README.html b/proto/STANDARD_CONFIGURATION_README.html
new file mode 100644
index 0000000..b4f4efc
--- /dev/null
+++ b/proto/STANDARD_CONFIGURATION_README.html
@@ -0,0 +1,851 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Standard Configuration Examples</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix Standard Configuration Examples</h1>
+
+<hr>
+
+<h2>Purpose of this document</h2>
+
+<p> This document presents a number of typical Postfix configurations.
+This document should be reviewed after you have followed the basic
+configuration steps as described in the BASIC_CONFIGURATION_README
+document. In particular, do not proceed here if you don't already
+have Postfix working for local mail submission and for local mail
+delivery. </p>
+
+<p> The first part of this document presents standard configurations
+that each solve one specific problem. </p>
+
+<ul>
+
+<li><a href="#stand_alone">Postfix on a stand-alone Internet host</a>
+
+<li><a href="#null_client">Postfix on a null client</a>
+
+<li><a href="#local_network">Postfix on a local network</a>
+
+<li><a href="#firewall">Postfix email firewall/gateway</a>
+
+</ul>
+
+<p> The second part of this document presents additional configurations
+for hosts in specific environments. </p>
+
+<ul>
+
+<li><a href="#some_local">Delivering some but not all accounts locally</a>
+
+<li><a href="#intranet">Running Postfix behind a firewall</a>
+
+<li><a href="#backup">Configuring Postfix as primary or backup MX host for a remote
+site</a>
+
+<li><a href="#dialup">Postfix on a dialup machine</a>
+
+<li><a href="#fantasy">Postfix on hosts without a real
+Internet hostname</a>
+
+</ul>
+
+<h2><a name="stand_alone">Postfix on a stand-alone Internet host</a></h2>
+
+<p> Postfix should work out of the box without change on a stand-alone
+machine that has direct Internet access. At least, that is how
+Postfix installs when you download the Postfix source code via
+http://www.postfix.org/. </p>
+
+<p> You can use the command "<b>postconf -n</b>" to find out what
+settings are overruled by your main.cf. Besides a few pathname
+settings, few parameters should be set on a stand-alone box, beyond
+what is covered in the BASIC_CONFIGURATION_README document: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Optional: send mail as user@domainname instead of user@hostname.
+ #myorigin = $mydomain
+
+ # Optional: specify NAT/proxy external address.
+ #proxy_interfaces = 1.2.3.4
+
+ # Alternative 1: don't relay mail from other hosts.
+ mynetworks_style = host
+ relay_domains =
+
+ # Alternative 2: relay mail from local clients only.
+ # mynetworks = 192.168.1.0/28
+ # relay_domains =
+</pre>
+</blockquote>
+
+<p> See also the section "<a href="#fantasy">Postfix on hosts without
+a real Internet hostname</a>" if this is applicable to your configuration.
+</p>
+
+<h2><a name="null_client">Postfix on a null client</a></h2>
+
+<p> A null client is a machine that can only send mail. It receives no
+mail from the network, and it does not deliver any mail locally. A
+null client typically uses POP, IMAP or NFS for mailbox access. </p>
+
+<p> In this example we assume that the Internet domain name is
+"example.com" and that the machine is named "hostname.example.com".
+As usual, the examples show only parameters that are not left at
+their default settings. </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 myhostname = hostname.example.com
+3 myorigin = $mydomain
+4 relayhost = $mydomain
+5 inet_interfaces = loopback-only
+6 mydestination =
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li> <p> Line 2: Set myhostname to hostname.example.com, in case
+the machine name isn't set to a fully-qualified domain name (use
+the command "postconf -d myhostname" to find out what the machine
+name is). </p>
+
+<li> <p> Line 2: The myhostname value also provides the default
+value for the mydomain parameter (here, "mydomain = example.com").
+</p>
+
+<li> <p> Line 3: Send mail as "user@example.com" (instead of
+"user@hostname.example.com"), so that nothing ever has a reason
+to send mail to "user@hostname.example.com". </p>
+
+<li> <p> Line 4: Forward all mail to the mail server that is
+responsible for the "example.com" domain. This prevents mail from
+getting stuck on the null client if it is turned off while some
+remote destination is unreachable. Specify a real hostname
+here if your "example.com" domain has no MX record. </p>
+
+<li> <p> Line 5: Do not accept mail from the network. </p>
+
+<li> <p> Line 6: Disable local mail delivery. All mail goes to
+the mail server as specified in line 4. </p>
+
+</ul>
+
+<h2><a name="local_network">Postfix on a local network</a></h2>
+
+<p> This section describes a local area network environment of one
+main server and multiple other systems that send and receive email.
+As usual we assume that the Internet domain name is "example.com".
+All systems are configured to send mail as "user@example.com", and
+all systems receive mail for "user@hostname.example.com". The main
+server also receives mail for "user@example.com". We call this
+machine by the name of mailhost.example.com. </p>
+
+<p> A drawback of sending mail as "user@example.com" is that mail
+for "root" and other system accounts is also sent to the central
+mailhost. See the section "<a href="#some_local">Delivering some
+but not all accounts locally</a>" below for possible solutions.
+</p>
+
+<p> As usual, the examples show only parameters that are not left
+at their default settings. </p>
+
+<p> First we present the non-mailhost configuration, because it is
+the simpler one. This machine sends mail as "user@example.com" and
+is the final destination for "user@hostname.example.com". </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 myorigin = $mydomain
+3 mynetworks = 127.0.0.0/8 10.0.0.0/24
+4 relay_domains =
+5 # Optional: forward all non-local mail to mailhost
+6 #relayhost = $mydomain
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li> <p> Line 2: Send mail as "user@example.com". </p>
+
+<li> <p> Line 3: Specify the trusted networks. </p>
+
+<li> <p> Line 4: This host does not relay mail from untrusted networks. </p>
+
+<li> <p> Line 6: This is needed if no direct Internet access is
+available. See also below, "<a href="#firewall">Postfix behind
+a firewall</a>". </p>
+
+</ul>
+
+<p> Next we present the mailhost configuration. This machine sends
+mail as "user@example.com" and is the final destination for
+"user@hostname.example.com" as well as "user@example.com". </p>
+
+<blockquote>
+<pre>
+ 1 DNS:
+ 2 example.com IN MX 10 mailhost.example.com.
+ 3
+ 4 /etc/postfix/main.cf:
+ 5 myorigin = $mydomain
+ 6 mydestination = $myhostname localhost.$mydomain localhost $mydomain
+ 7 mynetworks = 127.0.0.0/8 10.0.0.0/24
+ 8 relay_domains =
+ 9 # Optional: forward all non-local mail to firewall
+10 #relayhost = [firewall.example.com]
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li> <p> Line 2: Send mail for the domain "example.com" to the
+machine mailhost.example.com. Remember to specify the "." at the
+end of the line. </p>
+
+<li> <p> Line 5: Send mail as "user@example.com". </p>
+
+<li> <p> Line 6: This host is the final mail destination for the
+"example.com" domain, in addition to the names of the machine
+itself. </p>
+
+<li> <p> Line 7: Specify the trusted networks. </p>
+
+<li> <p> Line 8: This host does not relay mail from untrusted networks. </p>
+
+<li> <p> Line 10: This is needed only when the mailhost has to
+forward non-local mail via a mail server on a firewall. The
+<tt>[]</tt> forces Postfix to do no MX record lookups. </p>
+
+</ul>
+
+<p> In an environment like this, users access their mailbox in one
+or more of the following ways:
+
+<ul>
+
+<li> <p> Mailbox access via NFS or equivalent. </p>
+
+<li> <p> Mailbox access via POP or IMAP. </p>
+
+<li> <p> Mailbox on the user's preferred machine. </p>
+
+</ul>
+
+<p> In the latter case, each user has an alias on the mailhost that
+forwards mail to her preferred machine: </p>
+
+<blockquote>
+<pre>
+/etc/aliases:
+ joe: joe@joes.preferred.machine
+ jane: jane@janes.preferred.machine
+</pre>
+</blockquote>
+
+<p> On some systems the alias database is not in /etc/aliases. To
+find out the location for your system, execute the command "<b>postconf
+alias_maps</b>". </p>
+
+<p> Execute the command "<b>newaliases</b>" whenever you change
+the aliases file. </p>
+
+<h2><a name="firewall">Postfix email firewall/gateway</a></h2>
+
+<p> The idea is to set up a Postfix email firewall/gateway that
+forwards mail for "example.com" to an inside gateway machine but
+rejects mail for "anything.example.com". There is only one problem:
+with "relay_domains = example.com", the firewall normally also
+accepts mail for "anything.example.com". That would not be right.
+</p>
+
+<p> Note: this example requires Postfix version 2.0 and later. To find
+out what Postfix version you have, execute the command "<b>postconf
+mail_version</b>". </p>
+
+<p> The solution is presented in multiple parts. This first part
+gets rid of local mail delivery on the firewall, making the firewall
+harder to break. </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 myorigin = example.com
+3 mydestination =
+4 local_recipient_maps =
+5 local_transport = error:local mail delivery is disabled
+6
+7 /etc/postfix/master.cf:
+8 Comment out the local delivery agent
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li> <p> Line 2: Send mail from this machine as "user@example.com",
+so that no reason exists to send mail to "user@firewall.example.com".
+</p>
+
+<li> <p> Lines 3-8: Disable local mail delivery on the firewall
+machine. </p>
+
+</ul>
+
+<p> For the sake of technical correctness the firewall must be able
+to receive mail for postmaster@[firewall ip address]. Reportedly,
+some things actually expect this ability to exist. The second part
+of the solution therefore adds support for postmaster@[firewall ip
+address], and as a bonus we do abuse@[firewall ip address] as well.
+All the mail to these two accounts is forwarded to an inside address.
+</p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 virtual_alias_maps = hash:/etc/postfix/virtual
+3
+4 /etc/postfix/virtual:
+5 postmaster postmaster@example.com
+6 abuse abuse@example.com
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li> <p> Because mydestination is empty (see the previous example),
+only address literals matching $inet_interfaces or $proxy_interfaces
+are deemed local. So "localpart@[a.d.d.r]" can be matched as simply
+"localpart" in canonical(5) and virtual(5). This avoids the need to
+specify firewall IP addresses in Postfix configuration files. </p>
+
+</ul>
+
+<p> The last part of the solution does the email forwarding, which
+is the real purpose of the firewall email function. </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 mynetworks = 127.0.0.0/8 12.34.56.0/24
+ 3 relay_domains = example.com
+ 4 parent_domain_matches_subdomains =
+ 5 debug_peer_list smtpd_access_maps
+<br>
+ 6a # Postfix 2.10 and later support separate relay control and
+ 7a # spam control.
+ 8a smtpd_relay_restrictions =
+ 9a permit_mynetworks reject_unauth_destination
+10a smtpd_recipient_restrictions = ...spam blocking rules....
+<br>
+ 6b # Older configurations combine relay control and spam control. To
+ 7b # use this with Postfix &ge; 2.10 specify "smtpd_relay_restrictions=".
+ 8b smtpd_recipient_restrictions =
+ 9b permit_mynetworks reject_unauth_destination
+10b ...spam blocking rules....
+<br>
+11 relay_recipient_maps = hash:/etc/postfix/relay_recipients
+12 transport_maps = hash:/etc/postfix/transport
+13
+14 /etc/postfix/relay_recipients:
+15 user1@example.com x
+16 user2@example.com x
+17 . . .
+18
+19 /etc/postfix/transport:
+20 example.com smtp:[inside-gateway.example.com]
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li><p> Lines 1-10: Accept mail from local systems in $mynetworks,
+and accept mail from outside for "user@example.com" but not for
+"user@anything.example.com". The magic is in lines 4-5. </p>
+
+<li> <p> Lines 11, 13-16: Define the list of valid addresses in the
+"example.com" domain that can receive mail from the Internet. This
+prevents the mail queue from filling up with undeliverable
+MAILER-DAEMON messages. If you can't maintain a list of valid
+recipients then you must specify "relay_recipient_maps =" (that
+is, an empty value), or you must specify an "@example.com x"
+wild-card in the relay_recipients table. </p>
+
+<li> <p> Lines 12, 19-20: Route mail for "example.com" to the inside
+gateway machine. The <tt>[]</tt> forces Postfix to do no MX lookup.
+</p>
+
+</ul>
+
+<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
+tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/relay_recipients</b>"
+whenever you change the relay_recipients table. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/transport</b>"
+whenever you change the transport table. </p>
+
+<p> In some installations, there may be separate instances of Postfix
+processing inbound and outbound mail on a multi-homed firewall. The
+inbound Postfix instance has an SMTP server listening on the external
+firewall interface, and the outbound Postfix instance has an SMTP server
+listening on the internal interface. In such a configuration is it is
+tempting to configure $inet_interfaces in each instance with just the
+corresponding interface address. </p>
+
+<p> In most cases, using inet_interfaces in this way will not work,
+because as documented in the $inet_interfaces reference manual, the
+smtp(8) delivery agent will also use the specified interface address
+as the source address for outbound connections and will be unable to
+reach hosts on "the other side" of the firewall. The symptoms are that
+the firewall is unable to connect to hosts that are in fact up. See the
+inet_interfaces parameter documentation for suggested work-arounds.</p>
+
+<h2><a name="some_local">Delivering some but not all accounts
+locally</a></h2>
+
+<p> A drawback of sending mail as "user@example.com" (instead of
+"user@hostname.example.com") is that mail for "root" and other
+system accounts is also sent to the central mailhost. In order to
+deliver such accounts locally, you can set up virtual aliases as
+follows: </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 virtual_alias_maps = hash:/etc/postfix/virtual
+3
+4 /etc/postfix/virtual:
+5 root root@localhost
+6 . . .
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li> <p> Line 5: As described in the virtual(5) manual page, the
+bare name "root" matches "root@site" when "site" is equal to
+$myorigin, when "site" is listed in $mydestination, or when it
+matches $inet_interfaces or $proxy_interfaces. </p>
+
+</ul>
+
+<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
+editing the file. </p>
+
+<h2><a name="intranet">Running Postfix behind a firewall</a></h2>
+
+<p> The simplest way to set up Postfix on a host behind a firewalled
+network is to send all mail to a gateway host, and to let that mail
+host take care of internal and external forwarding. Examples of that
+are shown in the <a href="#local_network">local area network</a>
+section above. A more sophisticated approach is to send only external
+mail to the gateway host, and to send intranet mail directly. </p>
+
+<p> Note: this example requires Postfix version 2.0 and later. To find
+out what Postfix version you have, execute the command "<b>postconf
+mail_version</b>". </p>
+
+<p> The following example presents additional configuration. You
+need to combine this with basic configuration information as
+discussed in the first half of this document. </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 transport_maps = hash:/etc/postfix/transport
+ 3 relayhost =
+ 4 # Optional for a machine that isn't "always on"
+ 5 #fallback_relay = [gateway.example.com]
+ 6
+ 7 /etc/postfix/transport:
+ 8 # Internal delivery.
+ 9 example.com :
+10 .example.com :
+11 # External delivery.
+12 * smtp:[gateway.example.com]
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li> <p> Lines 2, 7-12: Request that intranet mail is delivered
+directly, and that external mail is given to a gateway. Obviously,
+this example assumes that the organization uses DNS MX records
+internally. The <tt>[]</tt> forces Postfix to do no MX lookup.
+</p>
+
+<li> <p> Line 3: IMPORTANT: do not specify a relayhost in main.cf.
+</p>
+
+<li> <p> Line 5: This prevents mail from being stuck in the queue
+when the machine is turned off. Postfix tries to deliver mail
+directly, and gives undeliverable mail to a gateway. </p>
+
+</ul>
+
+<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
+tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/transport</b>" whenever
+you edit the transport table. </p>
+
+<h2><a name="backup">Configuring Postfix as primary or backup MX host for a remote site</a></h2>
+
+<p> This section presents additional configuration. You need to
+combine this with basic configuration information as discussed in the
+first half of this document. </p>
+
+<p> When your system is SECONDARY MX host for a remote site this
+is all you need: </p>
+
+<blockquote>
+<pre>
+ 1 DNS:
+ 2 the.backed-up.domain.tld IN MX 100 your.machine.tld.
+ 3
+ 4 /etc/postfix/main.cf:
+ 5 relay_domains = . . . the.backed-up.domain.tld
+<br>
+ 6a # Postfix 2.10 and later support separate relay control and
+ 7a # spam control.
+ 8a smtpd_relay_restrictions =
+ 9a permit_mynetworks reject_unauth_destination
+10a smtpd_recipient_restrictions = ...spam blocking rules....
+<br>
+ 6b # Older configurations combine relay control and spam control. To
+ 7b # use this with Postfix &ge; 2.10 specify "smtpd_relay_restrictions=".
+ 8b smtpd_recipient_restrictions =
+ 9b permit_mynetworks reject_unauth_destination
+10b ...spam blocking rules....
+<br>
+11 # You must specify your NAT/proxy external address.
+12 #proxy_interfaces = 1.2.3.4
+13
+14 relay_recipient_maps = hash:/etc/postfix/relay_recipients
+15
+16 /etc/postfix/relay_recipients:
+17 user1@the.backed-up.domain.tld x
+18 user2@the.backed-up.domain.tld x
+19 . . .
+</pre>
+</blockquote>
+
+<p> When your system is PRIMARY MX host for a remote site you
+need the above, plus: </p>
+
+<blockquote>
+<pre>
+20 /etc/postfix/main.cf:
+21 transport_maps = hash:/etc/postfix/transport
+22
+23 /etc/postfix/transport:
+24 the.backed-up.domain.tld relay:[their.mail.host.tld]
+</pre>
+</blockquote>
+
+<p> Important notes:
+
+<ul>
+
+<li><p>Do not list the.backed-up.domain.tld in mydestination.</p>
+
+<li><p>Do not list the.backed-up.domain.tld in virtual_alias_domains.</p>
+
+<li><p>Do not list the.backed-up.domain.tld in virtual_mailbox_domains.</p>
+
+<li> <p> Lines 1-9: Forward mail from the Internet for
+"the.backed-up.domain.tld" to the primary MX host for that domain.
+</p>
+
+<li> <p> Line 12: This is a must if Postfix receives mail via a
+NAT relay or proxy that presents a different IP address to the
+world than the local machine. </p>
+
+<li> <p> Lines 14-18: Define the list of valid addresses in the
+"the.backed-up.domain.tld" domain. This prevents your mail queue
+from filling up with undeliverable MAILER-DAEMON messages. If you
+can't maintain a list of valid recipients then you must specify
+"relay_recipient_maps =" (that is, an empty value), or you must
+specify an "@the.backed-up.domain.tld x" wild-card in the
+relay_recipients table. </p>
+
+<li> <p> Line 24: The <tt>[]</tt> forces Postfix to do no MX lookup. </p>
+
+</ul>
+
+<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
+tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/transport</b>"
+whenever you change the transport table. </p>
+
+<p> NOTE for Postfix &lt; 2.2: Do not use the fallback_relay feature
+when relaying mail
+for a backup or primary MX domain. Mail would loop between the
+Postfix MX host and the fallback_relay host when the final destination
+is unavailable. </p>
+
+<ul>
+
+<li> In main.cf specify "<tt>relay_transport = relay</tt>",
+
+<li> In master.cf specify "<tt>-o fallback_relay =</tt>" at the
+end of the <tt>relay</tt> entry.
+
+<li> In transport maps, specify "<tt>relay:<i>nexthop...</i></tt>"
+as the right-hand side for backup or primary MX domain entries.
+
+</ul>
+
+<p> These are default settings in Postfix version 2.2 and later.
+</p>
+
+<h2><a name="dialup">Postfix on a dialup machine</a></h2>
+
+<p> This section applies to dialup connections that are down most
+of the time. For dialup connections that are up 24x7, see the <a
+href="#local_network">local area network</a> section above. </p>
+
+<p> This section presents additional configuration. You need to
+combine this with basic configuration information as discussed in the
+first half of this document. </p>
+
+<p> If you do not have your own hostname and IP address (usually
+with dialup, cable TV or DSL connections) then you should also
+study the section on "<a href="#fantasy">Postfix on hosts without
+a real Internet hostname</a>". </p>
+
+<ul>
+
+<li> Route all outgoing mail to your network provider.
+
+<p> If your machine is disconnected most of the time, there isn't
+a lot of opportunity for Postfix to deliver mail to hard-to-reach
+corners of the Internet. It's better to give the mail to a machine
+that is connected all the time. In the example below, the <tt>[]</tt>
+prevents Postfix from trying to look up DNS MX records. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ relayhost = [smtprelay.someprovider.com]
+</pre>
+
+<li> <p><a name="spontaneous_smtp">Disable spontaneous SMTP mail
+delivery (if using on-demand dialup IP only).</a> </p>
+
+<p> Normally, Postfix attempts to deliver outbound mail at its convenience.
+If your machine uses on-demand dialup IP, this causes your system
+to place a telephone call whenever you submit new mail, and whenever
+Postfix retries to deliver delayed mail. To prevent such telephone
+calls from being placed, disable spontaneous SMTP mail deliveries. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ defer_transports = smtp (Only for on-demand dialup IP hosts)
+</pre>
+
+<li> <p>Disable SMTP client DNS lookups (dialup LAN only).</p>
+
+<pre>
+/etc/postfix/main.cf:
+ disable_dns_lookups = yes (Only for on-demand dialup IP hosts)
+</pre>
+
+<li> Flush the mail queue whenever the Internet link is established.
+
+<p> Put the following command into your PPP or SLIP dialup scripts: </p>
+
+<pre>
+/usr/sbin/sendmail -q (whenever the Internet link is up)
+</pre>
+
+<p> The exact location of the Postfix sendmail command is system-specific.
+Use the command "<b>postconf sendmail_path</b>" to find out where the
+Postfix sendmail command is located on your machine. </p>
+
+<p> In order to find out if the mail queue is flushed, use something
+like: </p>
+
+<pre>
+#!/bin/sh
+
+# Start mail deliveries.
+/usr/sbin/sendmail -q
+
+# Allow deliveries to start.
+sleep 10
+
+# Loop until all messages have been tried at least once.
+while mailq | grep '^[^ ]*\*' &gt;/dev/null
+do
+ sleep 10
+done
+</pre>
+
+<p> If you have disabled <a href="#spontaneous_smtp">spontaneous
+SMTP mail delivery</a>, you also need to run the "<b>sendmail -q</b>"
+command every now and then while the dialup link is up, so that
+newly-posted mail is flushed from the queue. </p>
+
+</ul>
+
+<h2><a name="fantasy">Postfix on hosts without a real Internet
+hostname</a></h2>
+
+<p> This section is for hosts that don't have their own Internet
+hostname. Typically these are systems that get a dynamic IP address
+via DHCP or via dialup. Postfix will let you send and receive mail
+just fine between accounts on a machine with a fantasy name. However,
+you cannot use a fantasy hostname in your email address when sending
+mail into the Internet, because no-one would be able to reply to
+your mail. In fact, more and more sites refuse mail addresses with
+non-existent domain names. </p>
+
+<p> Note: the following information is Postfix version dependent.
+To find out what Postfix version you have, execute the command
+"<b>postconf mail_version</b>". </p>
+
+<h3>Solution 1: Postfix version 2.2 and later </h3>
+
+<p> Postfix 2.2 uses the generic(5) address mapping to replace
+local fantasy email addresses by valid Internet addresses. This
+mapping happens ONLY when mail leaves the machine; not when you
+send mail between users on the same machine. </p>
+
+<p> The following example presents additional configuration. You
+need to combine this with basic configuration information as
+discussed in the first half of this document. </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 smtp_generic_maps = hash:/etc/postfix/generic
+3
+4 /etc/postfix/generic:
+5 his@localdomain.local hisaccount@hisisp.example
+6 her@localdomain.local heraccount@herisp.example
+7 @localdomain.local hisaccount+local@hisisp.example
+</pre>
+</blockquote>
+
+<p> When mail is sent to a remote host via SMTP: </p>
+
+<ul>
+
+<li> <p> Line 5 replaces <i>his@localdomain.local</i> by his ISP
+mail address, </p>
+
+<li> <p> Line 6 replaces <i>her@localdomain.local</i> by her ISP
+mail address, and </p>
+
+<li> <p> Line 7 replaces other local addresses by his ISP account,
+with an address extension of +<i>local</i> (this example assumes
+that the ISP supports "+" style address extensions). </p>
+
+</ul>
+
+<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
+tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/generic</b>"
+whenever you change the generic table. </p>
+
+<h3>Solution 2: Postfix version 2.1 and earlier </h3>
+
+<p> The solution with older Postfix systems is to use valid
+Internet addresses where possible, and to let Postfix map valid
+Internet addresses to local fantasy addresses. With this, you can
+send mail to the Internet and to local fantasy addresses, including
+mail to local fantasy addresses that don't have a valid Internet
+address of their own.</p>
+
+<p> The following example presents additional configuration. You
+need to combine this with basic configuration information as
+discussed in the first half of this document. </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 myhostname = hostname.localdomain
+ 3 mydomain = localdomain
+ 4
+ 5 canonical_maps = hash:/etc/postfix/canonical
+ 6
+ 7 virtual_alias_maps = hash:/etc/postfix/virtual
+ 8
+ 9 /etc/postfix/canonical:
+10 your-login-name your-account@your-isp.com
+11
+12 /etc/postfix/virtual:
+13 your-account@your-isp.com your-login-name
+</pre>
+</blockquote>
+
+<p> Translation: </p>
+
+<ul>
+
+<li> <p> Lines 2-3: Substitute your fantasy hostname here. Do not
+use a domain name that is already in use by real organizations
+on the Internet. See RFC 2606 for examples of domain
+names that are guaranteed not to be owned by anyone. </p>
+
+<li> <p> Lines 5, 9, 10: This provides the mapping from
+"your-login-name@hostname.localdomain" to "your-account@your-isp.com".
+This part is required. </p>
+
+<li> <p> Lines 7, 12, 13: Deliver mail for "your-account@your-isp.com"
+locally, instead of sending it to the ISP. This part is not required
+but is convenient.
+
+</ul>
+
+<p>Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what lookup
+tables Postfix supports, use the command "<b>postconf -m</b>". </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/canonical</b>"
+whenever you change the canonical table. </p>
+
+<p> Execute the command "<b>postmap /etc/postfix/virtual</b>"
+whenever you change the virtual table. </p>
+
+</body>
+
+</html>
diff --git a/proto/STRESS_README.html b/proto/STRESS_README.html
new file mode 100644
index 0000000..30fa5f2
--- /dev/null
+++ b/proto/STRESS_README.html
@@ -0,0 +1,566 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Stress-Dependent Configuration</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Stress-Dependent Configuration</h1>
+
+<hr>
+
+<h2>Overview </h2>
+
+<p> This document describes the symptoms of Postfix SMTP server
+overload. It presents permanent main.cf changes to avoid overload
+during normal operation, and temporary main.cf changes to cope with
+an unexpected burst of mail. This document makes specific suggestions
+for Postfix 2.5 and later which support stress-adaptive behavior,
+and for earlier Postfix versions that don't. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#overload"> Symptoms of Postfix SMTP server overload </a>
+
+<li><a href="#adapt"> Automatic stress-adaptive behavior </a>
+
+<li><a href="#concurrency"> Service more SMTP clients at the same time </a>
+
+<li><a href="#time"> Spend less time per SMTP client </a>
+
+<li><a href="#hangup"> Disconnect suspicious SMTP clients </a>
+
+<li><a href="#legacy"> Temporary measures for older Postfix releases </a>
+
+<li><a href="#feature"> Detecting support for stress-adaptive behavior </a>
+
+<li><a href="#forcing"> Forcing stress-adaptive behavior on or off </a>
+
+<li><a href="#other"> Other measures to off-load zombies </a>
+
+<li><a href="#credits"> Credits </a>
+
+</ul>
+
+<h2><a name="overload"> Symptoms of Postfix SMTP server overload </a></h2>
+
+<p> Under normal conditions, the Postfix SMTP server responds
+immediately when an SMTP client connects to it; the time to deliver
+mail is noticeable only with large messages. Performance degrades
+dramatically when the number of SMTP clients exceeds the number of
+Postfix SMTP server processes. When an SMTP client connects while
+all Postfix SMTP server processes are busy, the client must wait
+until a server process becomes available. </p>
+
+<p> SMTP server overload may be caused by a surge of legitimate
+mail (example: a DNS registrar opens a new zone for registrations),
+by mistake (mail explosion caused by a forwarding loop) or by malice
+(worm outbreak, botnet, or other illegitimate activity). </p>
+
+<p> Symptoms of Postfix SMTP server overload are: </p>
+
+<ul>
+
+<li> <p> Remote SMTP clients experience a long delay before Postfix
+sends the "220 hostname.example.com ESMTP Postfix" greeting. </p>
+
+<ul>
+
+<li> <p> NOTE: Broken DNS configurations can also cause lengthy
+delays before Postfix sends "220 hostname.example.com ...". These
+delays also exist when Postfix is NOT overloaded. </p>
+
+<li> <p> NOTE: To avoid "overload" delays for end-user mail
+clients, enable the "submission" service entry in master.cf (present
+since Postfix 2.1), and tell users to connect to this instead of
+the public SMTP service. </p>
+
+</ul>
+
+<li> <p> The Postfix SMTP server logs an increased number of "lost
+connection after CONNECT" events. This happens because remote SMTP
+clients disconnect before Postfix answers the connection. </p>
+
+<ul>
+
+<li> <p> NOTE: A portscan for open SMTP ports can also result in
+"lost connection ..." logfile messages. </p>
+
+</ul>
+
+<li> <p> Postfix 2.3 and later logs a warning that all server ports
+are busy: </p>
+
+<pre>
+Oct 3 20:39:27 spike postfix/master[28905]: warning: service "smtp"
+ (25) has reached its process limit "30": new clients may experience
+ noticeable delays
+Oct 3 20:39:27 spike postfix/master[28905]: warning: to avoid this
+ condition, increase the process count in master.cf or reduce the
+ service time per client
+Oct 3 20:39:27 spike postfix/master[28905]: warning: see
+ <a href="http://www.postfix.org/STRESS_README.html">http://www.postfix.org/STRESS_README.html</a> for examples of
+ stress-adapting configuration settings
+</pre>
+
+</ul>
+
+<p> Legitimate mail that doesn't get through during an episode of
+Postfix SMTP server overload is not necessarily lost. It should
+still arrive once the situation returns to normal, as long as the
+overload condition is temporary. </p>
+
+<h2><a name="adapt"> Automatic stress-adaptive behavior </a></h2>
+
+<p> Postfix version 2.5 introduces automatic stress-adaptive behavior.
+It works as follows. When a "public" network service such as the
+SMTP server runs into an "all server ports are busy" condition, the
+Postfix master(8) daemon logs a warning, restarts the service
+(without interrupting existing network sessions), and runs the
+service with "-o stress=yes" on the server process command line:
+</p>
+
+<blockquote>
+<pre>
+80821 ?? S 0:00.24 smtpd -n smtp -t inet -u -c -o stress=yes
+</pre>
+</blockquote>
+
+<p> Normally, the Postfix master(8) daemon runs such a service with
+"-o stress=" on the command line (i.e. with an empty parameter
+value): </p>
+
+<blockquote>
+<pre>
+83326 ?? S 0:00.28 smtpd -n smtp -t inet -u -c -o stress=
+</pre>
+</blockquote>
+
+<p> You won't see "-o stress" command-line parameters with services
+that have local clients only. These include services internal to
+Postfix such as the queue manager, and services that listen on a
+loopback interface only, such as after-filter SMTP services. </p>
+
+<p> The "stress" parameter value is the key to making main.cf
+parameter settings stress adaptive. The following settings are the
+default with Postfix 2.6 and later. </p>
+
+<blockquote>
+<pre>
+1 smtpd_timeout = ${stress?{10}:{300}}s
+2 smtpd_hard_error_limit = ${stress?{1}:{20}}
+3 smtpd_junk_command_limit = ${stress?{1}:{100}}
+4 # Parameters added after Postfix 2.6:
+5 smtpd_per_record_deadline = ${stress?{yes}:{no}}
+6 smtpd_starttls_timeout = ${stress?{10}:{300}}s
+7 address_verify_poll_count = ${stress?{1}:{3}}
+</pre>
+</blockquote>
+
+<p> Postfix versions before 3.0 use the older form ${stress?x}${stress:y}
+instead of the newer form ${stress?{x}:{y}}. </p>
+
+<p> The syntax of ${name?{value}:{value}}, ${name?value} and
+${name:value} is explained at the beginning of the postconf(5)
+manual page. </p>
+
+<p> Translation: <p>
+
+<ul>
+
+<li> <p> Line 1: under conditions of stress, use an smtpd_timeout
+value of 10 seconds instead of the default 300 seconds. Experience
+on the postfix-users list from a variety of sysadmins shows that
+reducing the "normal" smtpd_timeout to 60s is unlikely to affect
+legitimate clients. However, it is unlikely to become the Postfix
+default because it's not RFC compliant. Setting smtpd_timeout to
+10s or even 5s under stress will still allow most
+legitimate clients to connect and send mail, but may delay mail
+from some clients. No mail should be lost, as long as this measure
+is used only temporarily. </p>
+
+<li> <p> Line 2: under conditions of stress, use an smtpd_hard_error_limit
+of 1 instead of the default 20. This disconnects clients
+after a single error, giving other clients a chance to connect.
+However, this may cause significant delays with legitimate mail,
+such as a mailing list that contains a few no-longer-active user
+names that didn't bother to unsubscribe. No mail should be lost,
+as long as this measure is used only temporarily. </p>
+
+<li> <p> Line 3: under conditions of stress, use an
+smtpd_junk_command_limit of 1 instead of the default 100. This
+prevents clients from keeping connections open by repeatedly
+sending HELO, EHLO, NOOP, RSET, VRFY or ETRN commands. </p>
+
+<li> <p> Line 5: under conditions of stress, change the behavior
+of smtpd_timeout and smtpd_starttls_timeout, from a time limit per
+read or write system call, to a time limit to send or receive a
+complete record (an SMTP command line, SMTP response line, SMTP
+message content line, or TLS protocol message). </p>
+
+<li> <p> Line 6: under conditions of stress, reduce the time limit
+for TLS protocol handshake messages to 10 seconds, from the default
+value of 300 seconds. See also the smtpd_timeout discussion above.
+</p>
+
+<li> <p> Line 7: under conditions of stress, do not wait up to 6
+seconds for the completion of an address verification probe. If the
+result is not already in the address verification cache, reply
+immediately with $unverified_recipient_tempfail_action or
+$unverified_sender_tempfail_action. No mail should be lost, as long
+as this measure is used only temporarily. </p>
+
+</ul>
+
+<p> NOTE: Please keep in mind that the stress-adaptive feature is
+a fairly desperate measure to keep <b>some</b> legitimate mail
+flowing under overload conditions. If a site is reaching the SMTP
+server process limit when there isn't an attack or bot flood
+occurring, then either the process limit needs to be raised or more
+hardware needs to be added. </p>
+
+<h2><a name="concurrency"> Service more SMTP clients at the same time </a> </h2>
+
+<p> This section and the ones that follow discuss permanent measures
+against mail server overload. </p>
+
+<p> One measure to avoid the "all server processes busy" condition
+is to service more SMTP clients simultaneously. For this you need
+to increase the number of Postfix SMTP server processes. This will
+improve the
+responsiveness for remote SMTP clients, as long as the server machine
+has enough hardware and software resources to run the additional
+processes, and as long as the file system can keep up with the
+additional load. </p>
+
+<ul>
+
+<li> <p> You increase the number of SMTP server processes either
+by increasing the default_process_limit in main.cf (line 3 below),
+or by increasing the SMTP server's "maxproc" field in master.cf
+(line 10 below). Either way, you need to issue a "postfix reload"
+command to make the change effective. </p>
+
+<li> <p> Process limits above 1000 require Postfix version 2.4 or
+later, and an operating system that supports kernel-based event
+filters (BSD kqueue(2), Linux epoll(4), or Solaris /dev/poll).
+</p>
+
+<li> <p> More processes use more memory. You can reduce the Postfix
+memory footprint by using cdb:
+lookup tables instead of Berkeley DB's hash: or btree: tables. </p>
+
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 # Raise the global process limit, 100 since Postfix 2.0.
+ 3 default_process_limit = 200
+ 4
+ 5 /etc/postfix/master.cf:
+ 6 # =============================================================
+ 7 # service type private unpriv chroot wakeup maxproc command
+ 8 # =============================================================
+ 9 # Raise the SMTP service process limit only.
+10 smtp inet n - n - 200 smtpd
+</pre>
+
+<li> <p> NOTE: older versions of the SMTPD_POLICY_README document
+contain a mistake: they configure a fixed number of policy daemon
+processes. When you raise the SMTP server's "maxproc" field in
+master.cf, SMTP server processes will report problems when connecting
+to policy server processes, because there aren't enough of them.
+Examples of errors are "connection refused" or "operation timed
+out". </p>
+
+<p> To fix, edit master.cf and specify a zero "maxproc" field
+in all policy server entries; see line 6 in the example below.
+Issue a "postfix reload" command to make the change effective. </p>
+
+<pre>
+1 /etc/postfix/master.cf:
+2 # =============================================================
+3 # service type private unpriv chroot wakeup maxproc command
+4 # =============================================================
+5 # Disable the policy service process limit.
+6 policy unix - n n - 0 spawn
+7 user=nobody argv=/some/where/policy-server
+</pre>
+
+</ul>
+
+<h2><a name="time"> Spend less time per SMTP client </a></h2>
+
+<p> When increasing the number of SMTP server processes is not
+practical, you can improve Postfix server responsiveness by eliminating
+delays. When Postfix spends less time per SMTP session, the same
+number of SMTP server processes can service more clients in a given
+amount of time. </p>
+
+<ul>
+
+<li> <p> Eliminate non-functional RBL lookups (blocklists that are
+no longer in operation). These lookups can degrade performance.
+Postfix logs a warning when an RBL server does not respond. </p>
+
+<li> <p> Eliminate redundant RBL lookups (people often use multiple
+Spamhaus RBLs that include each other). To find out whether RBLs
+include other RBLs, look up the websites that document the RBL's
+policies. </p>
+
+<li> <p> Eliminate header_checks and body_checks, and keep just a few
+emergency patterns to block the latest worm explosion or backscatter
+mail. See BACKSCATTER_README for examples of the latter.
+
+<li> <p> Group your header_checks and body_checks patterns to avoid
+unnecessary pattern matching operations:
+
+<pre>
+ 1 /etc/postfix/header_checks:
+ 2 if /^Subject:/
+ 3 /^Subject: virus found in mail from you/ reject
+ 4 /^Subject: ..other../ reject
+ 5 endif
+ 6
+ 7 if /^Received:/
+ 8 /^Received: from (postfix\.org) / reject forged client name in received header: $1
+ 9 /^Received: from ..other../ reject ....
+10 endif
+</pre>
+
+</ul>
+
+<h2><a name="hangup"> Disconnect suspicious SMTP clients </a></h2>
+
+<p> Under conditions of overload you can improve Postfix SMTP server
+responsiveness by hanging up on suspicious clients, so that other
+clients get a chance to talk to Postfix. </p>
+
+<ul>
+
+<li> <p> Use "521" SMTP reply codes (Postfix 2.6 and later) or "421"
+(Postfix 2.3-2.5) to hang up on clients that that match botnet-related
+RBLs (see next bullet) or that match selected non-RBL restrictions
+such as SMTP access maps. The Postfix SMTP server will reject mail
+and disconnect without waiting for the remote SMTP client to send
+a QUIT command. </p>
+
+<li> <p> To hang up connections from denylisted zombies, you can
+set specific Postfix SMTP server reject codes for specific RBLs,
+and for individual responses from specific RBLs. We'll use
+zen.spamhaus.org as an example; by the time you read this document,
+details may have changed. Right now, their documents say that a
+response of 127.0.0.10 or 127.0.0.11 indicates a dynamic client IP
+address, which means that the machine is probably running a bot of
+some kind. To give a 521 response instead of the default 554
+response, use something like: </p>
+
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 smtpd_client_restrictions =
+ 3 permit_mynetworks
+ 4 reject_rbl_client zen.spamhaus.org=127.0.0.10
+ 5 reject_rbl_client zen.spamhaus.org=127.0.0.11
+ 6 reject_rbl_client zen.spamhaus.org
+ 7
+ 8 rbl_reply_maps = hash:/etc/postfix/rbl_reply_maps
+ 9
+10 /etc/postfix/rbl_reply_maps:
+11 # With Postfix 2.3-2.5 use "421" to hang up connections.
+12 zen.spamhaus.org=127.0.0.10 521 4.7.1 Service unavailable;
+13 $rbl_class [$rbl_what] blocked using
+14 $rbl_domain${rbl_reason?; $rbl_reason}
+15
+16 zen.spamhaus.org=127.0.0.11 521 4.7.1 Service unavailable;
+17 $rbl_class [$rbl_what] blocked using
+18 $rbl_domain${rbl_reason?; $rbl_reason}
+</pre>
+
+<p> Although the above example shows three RBL lookups (lines 4-6),
+Postfix will only do a single DNS query, so it does not affect the
+performance. </p>
+
+<li> <p> With Postfix 2.3-2.5, use reply code 421 (521 will not
+cause Postfix to disconnect). The down-side of replying with 421
+is that it works only for zombies and other malware. If the client
+is running a real MTA, then it may connect again several times until
+the mail expires in its queue. When this is a problem, stick with
+the default 554 reply, and use "smtpd_hard_error_limit = 1" as
+described below. </p>
+
+<li> <p> You can automatically turn on the above overload measure
+with Postfix 2.5 and later, or with earlier releases that contain
+the stress-adaptive behavior source code patch from the mirrors
+listed at http://www.postfix.org/download.html. Simply replace line
+above 8 with: </p>
+
+<pre>
+ 8 rbl_reply_maps = ${stress?hash:/etc/postfix/rbl_reply_maps}
+</pre>
+
+</ul>
+
+<p> More information about automatic stress-adaptive behavior is
+in section "<a href="#adapt">Automatic stress-adaptive behavior</a>".
+</p>
+
+<h2><a name="legacy"> Temporary measures for older Postfix releases </a></h2>
+
+<p> See the section "<a href="#adapt">Automatic stress-adaptive
+behavior</a>" if you are running Postfix version 2.5 or later, or
+if you have applied the source code patch for stress-adaptive
+behavior from the mirrors listed at http://www.postfix.org/download.html.
+</p>
+
+<p> The following measures can be applied temporarily during overload.
+They still allow <b>most</b> legitimate clients to connect and send
+mail, but may affect some legitimate clients. </p>
+
+<ul>
+
+<li> <p> Reduce smtpd_timeout (default: 300s). Experience on the
+postfix-users list from a variety of sysadmins shows that reducing
+the "normal" smtpd_timeout to 60s is unlikely to affect legitimate
+clients. However, it is unlikely to become the Postfix default
+because it's not RFC compliant. Setting smtpd_timeout to 10s (line
+2 below) or even 5s under stress will still allow <b>most</b>
+legitimate clients to connect and send mail, but may delay mail
+from some clients. No mail should be lost, as long as this measure
+is used only temporarily. </p>
+
+<li> <p> Reduce smtpd_hard_error_limit (default: 20). Setting this
+to 1 under stress (line 3 below) helps by disconnecting clients
+after a single error, giving other clients a chance to connect.
+However, this may cause significant delays with legitimate mail,
+such as a mailing list that contains a few no-longer-active user
+names that didn't bother to unsubscribe. No mail should be lost,
+as long as this measure is used only temporarily. </p>
+
+<li> <p> Use an smtpd_junk_command_limit of 1 instead of the default
+100. This prevents clients from keeping idle connections open by
+repeatedly sending NOOP or RSET commands. </p>
+
+</ul>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 smtpd_timeout = 10
+3 smtpd_hard_error_limit = 1
+4 smtpd_junk_command_limit = 1
+</pre>
+</blockquote>
+
+<p> With these measures, no mail should be lost, as long
+as these measures are used only temporarily. The next section of
+this document introduces a way to automate this process. </p>
+
+<h2><a name="feature"> Detecting support for stress-adaptive behavior </a></h2>
+
+<p> To find out if your Postfix installation supports stress-adaptive
+behavior, use the "ps" command, and look for the smtpd processes.
+Postfix has stress-adaptive support when you see "-o stress=" or
+"-o stress=yes" command-line options. Remember that Postfix never
+enables stress-adaptive behavior on servers that listen on local
+addresses only. </p>
+
+<p> The following example is for FreeBSD or Linux. On Solaris, HP-UX
+and other System-V flavors, use "ps -ef" instead of "ps ax". </p>
+
+<blockquote>
+<pre>
+$ ps ax|grep smtpd
+83326 ?? S 0:00.28 smtpd -n smtp -t inet -u -c -o stress=
+84345 ?? Ss 0:00.11 /usr/bin/perl /usr/libexec/postfix/smtpd-policy.pl
+</pre>
+</blockquote>
+
+<p> You can't use postconf(1) to detect stress-adaptive support.
+The postconf(1) command ignores the existence of the stress parameter
+in main.cf, because the parameter has no effect there. Command-line
+"-o parameter" settings always take precedence over main.cf parameter
+settings. <p>
+
+<p> If you configure stress-adaptive behavior in main.cf when it
+isn't supported, nothing bad will happen. The processes will run
+as if the stress parameter always has an empty value. </p>
+
+<h2><a name="forcing"> Forcing stress-adaptive behavior on or off </a></h2>
+
+<p> You can manually force stress-adaptive behavior on, by adding
+a "-o stress=yes" command-line option in master.cf. This can be
+useful for testing overrides on the SMTP service. Issue "postfix
+reload" to make the change effective. </p>
+
+<p> Note: setting the stress parameter in main.cf has no effect for
+services that accept remote connections. </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/master.cf:
+2 # =============================================================
+3 # service type private unpriv chroot wakeup maxproc command
+4 # =============================================================
+5 #
+6 smtp inet n - n - - smtpd
+7 -o stress=yes
+8 -o . . .
+</pre>
+</blockquote>
+
+<p> To permanently force stress-adaptive behavior off with a specific
+service, specify "-o stress=" on its master.cf command line. This
+may be desirable for the "submission" service. Issue "postfix reload"
+to make the change effective. </p>
+
+<p> Note: setting the stress parameter in main.cf has no effect for
+services that accept remote connections. </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/master.cf:
+2 # =============================================================
+3 # service type private unpriv chroot wakeup maxproc command
+4 # =============================================================
+5 #
+6 submission inet n - n - - smtpd
+7 -o stress=
+8 -o . . .
+</pre>
+</blockquote>
+
+<h2><a name="other"> Other measures to off-load zombies </a> </h2>
+
+<p> The postscreen(8) daemon, introduced with Postfix 2.8, provides
+additional protection against mail server overload. One postscreen(8)
+process handles multiple inbound SMTP connections, and decides which
+clients may talk to a Postfix SMTP server process. By keeping
+spambots away, postscreen(8) leaves more SMTP server processes
+available for legitimate clients, and delays the onset of server
+overload conditions. </p>
+
+<h2><a name="credits"> Credits </a></h2>
+
+<ul>
+
+<li> Thanks to the postfix-users mailing list members for sharing
+early experiences with the stress-adaptive feature.
+
+<li> The RBL example and several other paragraphs of text were
+adapted from postfix-users postings by Noel Jones.
+
+<li> Wietse implemented stress-adaptive behavior as the smallest
+possible patch while he should be working on other things.
+
+</ul>
+
+</body> </html>
diff --git a/proto/TLS_LEGACY_README.html b/proto/TLS_LEGACY_README.html
new file mode 100644
index 0000000..dacf1c1
--- /dev/null
+++ b/proto/TLS_LEGACY_README.html
@@ -0,0 +1,1606 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix legacy TLS Support </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix legacy TLS Support
+</h1>
+
+<hr>
+
+<h2> NOTE </h2>
+
+<p> This document describes an old TLS user interface that is based
+on a third-party TLS patch by Lutz J&auml;nicke. As of Postfix
+version 2.3, the old user interface still exists to allow migration
+from earlier Postfix releases, but its functionality is frozen. </p>
+
+<h2> What Postfix TLS support does for you </h2>
+
+<p> Transport Layer Security (TLS, formerly called SSL) provides
+certificate-based authentication and encrypted sessions. An
+encrypted session protects the information that is transmitted with
+SMTP mail or with SASL authentication.
+
+<p> Postfix version 2.2 introduces support for TLS as described in
+RFC 3207. TLS Support for older Postfix versions was available as
+an add-on patch. The section "<a href="#compat">Compatibility with
+Postfix &lt; 2.2 TLS support</a>" below discusses the differences
+between these implementations. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#how">How Postfix TLS support works</a>
+
+<li><a href="#build_tls">Building Postfix with TLS support</a>
+
+<li><a href="#server_tls">SMTP Server specific settings</a>
+
+<li> <a href="#client_tls">SMTP Client specific settings</a>
+
+<li><a href="#tlsmgr_controls"> TLS manager specific settings </a>
+
+<li><a href="#problems"> Reporting problems </a>
+
+<li><a href="#compat">Compatibility with Postfix &lt; 2.2 TLS support</a>
+
+<li><a href="#credits"> Credits </a>
+
+</ul>
+
+<p> And last but not least, for the impatient: </p>
+
+<ul>
+
+<li><a href="#quick-start">Getting started, quick and dirty</a>
+
+</ul>
+
+<h2><a name="how">How Postfix TLS support works</a></h2>
+
+<p> The diagram below shows the main elements of the Postfix TLS
+architecture and their relationships. Colored boxes with numbered
+names represent Postfix daemon programs. Other colored boxes
+represent storage elements. </p>
+
+<ul>
+
+<li> <p> The smtpd(8) server implements the SMTP over TLS server
+side. </p>
+
+<li> <p> The smtp(8) client implements the SMTP over TLS client
+side. </p>
+
+<li> <p> The tlsmgr(8) server maintains the pseudo-random number
+generator (PRNG) that seeds the TLS engines in the smtpd(8) server
+and smtp(8) client processes, and maintains the TLS session key
+cache files. </p>
+
+</ul>
+
+<table>
+
+<tr> <td>Network<tt>-&gt; </tt> </td> <td align="center"
+bgcolor="#f0f0ff"> <br> <a href="smtpd.8.html">smtpd(8)</a> <br> &nbsp; </td> <td colspan="2">
+
+<tt> &lt;---seed---<br><br>&lt;-session-&gt; </tt> </td> <td
+align="center" bgcolor="#f0f0ff"> <br> <a href="tlsmgr.8.html">tlsmgr(8)</a> <br> &nbsp; </td>
+<td colspan="3"> <tt> ---seed---&gt;<br> <br>&lt;-session-&gt;
+
+</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> <a href="smtp.8.html">smtp(8)</a> <br>
+&nbsp; </td> <td> <tt> -&gt;</tt>Network </td> </tr>
+
+<tr> <td colspan="3"> </td> <td align="right"> <table> <tr> <td>
+
+</td> <td> / </td> </tr> <tr> <td> / </td> <td> </td> </tr> </table>
+</td> <td align="center"> |<br> |</td> <td align="left"> <table>
+
+<tr> <td> \ </td> <td> </td> </tr> <tr> <td> </td> <td> \ </td>
+</tr> </table> </td> <td colspan="3"> </td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff">
+smtpd<br> session<br> key cache </td> <td> </td> <td align="center"
+bgcolor="#f0f0ff"> PRNG<br> state <br>file </td> <td> </td> <td
+align="center" bgcolor="#f0f0ff"> smtp<br> session<br> key cache
+</td>
+
+<td colspan="2"> </td> </tr>
+
+</table>
+
+<h2><a name="build_tls">Building Postfix with TLS support</a></h2>
+
+<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
+top-level directory and with arguments as shown next. </p>
+
+<p> <b> NOTE: Do not use Gnu TLS. It will spontaneously terminate
+a Postfix daemon process with exit status code 2, instead of allowing
+Postfix to 1) report the error to the maillog file, and to 2) provide
+plaintext service where this is appropriate. </b> </p>
+
+<ul>
+
+<li> <p> If the OpenSSL include files (such as <tt>ssl.h</tt>) are
+in directory <tt>/usr/include/openssl</tt>, and the OpenSSL libraries
+(such as <tt>libssl.so</tt> and <tt>libcrypto.so</tt>) are in
+directory <tt>/usr/lib</tt>: </p>
+
+<blockquote>
+<pre>
+% <b>make tidy</b> # if you have left-over files from a previous build
+% <b>make makefiles CCARGS="-DUSE_TLS" AUXLIBS="-lssl -lcrypto"</b>
+</pre>
+</blockquote>
+
+<li> <p> If the OpenSSL include files (such as <tt>ssl.h</tt>) are
+in directory <tt>/usr/local/include/openssl</tt>, and the OpenSSL
+libraries (such as <tt>libssl.so</tt> and <tt>libcrypto.so</tt>)
+are in directory <tt>/usr/local/lib</tt>: </p>
+
+<blockquote>
+<pre>
+% <b>make tidy</b> # if you have left-over files from a previous build
+% <b>make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \
+ AUXLIBS="-L/usr/local/lib -lssl -lcrypto" </b>
+</pre>
+</blockquote>
+
+<p> On Solaris, specify the <tt>-R</tt> option as shown below:
+
+<blockquote>
+<pre>
+% <b>make tidy</b> # if you have left-over files from a previous build
+% <b>make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \
+ AUXLIBS="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto" </b>
+</pre>
+</blockquote>
+
+</ul>
+
+<p> If you need to apply other customizations (such as Berkeley DB
+databases, MySQL, PosgreSQL, LDAP or SASL), see the respective
+Postfix README documents, and combine their "<tt>make makefiles</tt>"
+instructions with the instructions above: </p>
+
+<blockquote>
+<pre>
+% <b>make tidy</b> # if you have left-over files from a previous build
+% <b>make makefiles CCARGS="-DUSE_TLS \
+ <i>(other -D or -I options)</i>" \
+ AUXLIBS="-lssl -lcrypto \
+ <i>(other -l options for libraries in /usr/lib)</i> \
+ <i>(-L/path/name + -l options for other libraries)</i>"</b>
+</pre>
+</blockquote>
+
+<p> To complete the build process, see the Postfix INSTALL
+instructions. Postfix has TLS support turned off by default, so
+you can start using Postfix as soon as it is installed. </p>
+
+<h2><a name="server_tls">SMTP Server specific settings</a></h2>
+
+<p> Topics covered in this section: </p>
+
+<ul>
+
+<li><a href="#server_cert_key">Server-side certificate and private
+key configuration </a>
+
+<li><a href="#server_logging"> Server-side TLS activity logging
+</a>
+
+<li><a href="#server_enable">Enabling TLS in the Postfix SMTP server </a>
+
+<li><a href="#server_vrfy_client">Client certificate verification</a>
+
+<li><a href="#server_tls_auth">Supporting AUTH over TLS only</a>
+
+<li><a href="#server_tls_cache">Server-side TLS session cache</a>
+
+<li><a href="#server_access">Server access control</a>
+
+<li><a href="#server_cipher">Server-side cipher controls</a>
+
+<li><a href="#server_misc"> Miscellaneous server controls</a>
+
+</ul>
+
+<h3><a name="server_cert_key">Server-side certificate and private
+key configuration </a> </h3>
+
+<p> In order to use TLS, the Postfix SMTP server needs a certificate
+and a private key. Both must be in "pem" format. The private key
+must not be encrypted, meaning: the key must be accessible without
+a password. Both certificate and private key may be in the same
+file. </p>
+
+<p> Both RSA and DSA certificates are supported. Typically you will
+only have RSA certificates issued by a commercial CA. In addition,
+the tools supplied with OpenSSL will by default issue RSA certificates.
+You can have both at the same time, in which case the cipher used
+determines which certificate is presented. For Netscape and OpenSSL
+clients without special cipher choices, the RSA certificate is
+preferred. </p>
+
+<p> In order for remote SMTP clients to check the Postfix SMTP
+server certificates, the CA certificate (in case of a certificate
+chain, all CA certificates) must be available. You should add
+these certificates to the server certificate, the server certificate
+first, then the issuing CA(s). </p>
+
+<p> Example: the certificate for "server.dom.ain" was issued by
+"intermediate CA" which itself has a certificate issued by "root
+CA". Create the server.pem file with: </p>
+
+<blockquote>
+<pre>
+% <b>cat server_cert.pem intermediate_CA.pem &gt; server.pem</b>
+</pre>
+</blockquote>
+
+<p> A Postfix SMTP server certificate supplied here must be usable
+as an SSL server certificate and hence pass the "openssl verify -purpose
+sslserver ..." test. </p>
+
+<p> A client that trusts the root CA has a local copy of the root
+CA certificate, so it is not necessary to include the root CA
+certificate here. Leaving it out of the "server.pem" file reduces
+the overhead of the TLS exchange. </p>
+
+<p> If you want the Postfix SMTP server to accept remote SMTP client
+certificates issued by these CAs, append the root certificate to
+$smtpd_tls_CAfile or install it in the $smtpd_tls_CApath directory. When
+you configure trust in a root CA, it is not necessary to explicitly trust
+intermediary CAs signed by the root CA, unless $smtpd_tls_ccert_verifydepth
+is less than the number of CAs in the certificate chain for the clients
+of interest. With a verify depth of 1 you can only verify certificates
+directly signed by a trusted CA, and all trusted intermediary CAs need to
+be configured explicitly. With a verify depth of 2 you can verify clients
+signed by a root CA or a direct intermediary CA (so long as the client
+is correctly configured to supply its intermediate CA certificate). </p>
+
+<p> RSA key and certificate examples: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_cert_file = /etc/postfix/server.pem
+ smtpd_tls_key_file = $smtpd_tls_cert_file
+</pre>
+</blockquote>
+
+<p> Their DSA counterparts: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem
+ smtpd_tls_dkey_file = $smtpd_tls_dcert_file
+</pre>
+</blockquote>
+
+<p> To verify a remote SMTP client certificate, the Postfix SMTP
+server needs to trust the certificates of the issuing Certification
+Authorities. These certificates in "pem" format can be stored in a
+single $smtpd_tls_CAfile or in multiple files, one CA per file in
+the $smtpd_tls_CApath directory. If you use a directory, don't forget
+to create the necessary "hash" links with: </p>
+
+<blockquote>
+<pre>
+# <b>$OPENSSL_HOME/bin/c_rehash <i>/path/to/directory</i> </b>
+</pre>
+</blockquote>
+
+<p> The $smtpd_tls_CAfile contains the CA certificates of one or
+more trusted CAs. The file is opened (with root privileges) before
+Postfix enters the optional chroot jail and so need not be accessible
+from inside the chroot jail. </p>
+
+<p> Additional trusted CAs can be specified via the $smtpd_tls_CApath
+directory, in which case the certificates are read (with $mail_owner
+privileges) from the files in the directory when the information
+is needed. Thus, the $smtpd_tls_CApath directory needs to be
+accessible inside the optional chroot jail. </p>
+
+<p> When you configure Postfix to request client certificates (by
+setting $smtpd_tls_ask_ccert = yes), any certificates in
+$smtpd_tls_CAfile are sent to the client, in order to allow it to
+choose an identity signed by a CA you trust. If no $smtpd_tls_CAfile
+is specified, no preferred CA list is sent, and the client is free
+to choose an identity signed by any CA. Many clients use a fixed
+identity regardless of the preferred CA list and you may be able
+to reduce TLS negotiation overhead by installing client CA certificates
+mostly or only in $smtpd_tls_CApath. In the latter case you need
+not specify a $smtpd_tls_CAfile. </p>
+
+<p> Note, that unless client certificates are used to allow greater
+access to TLS authenticated clients, it is best to not ask for
+client certificates at all, as in addition to increased overhead
+some clients (notably in some cases qmail) are unable to complete
+the TLS handshake when client certificates are requested. </p>
+
+<p> Example: </p>
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_CAfile = /etc/postfix/CAcert.pem
+ smtpd_tls_CApath = /etc/postfix/certs
+</pre>
+</blockquote>
+
+<h3><a name="server_logging"> Server-side TLS activity logging </a> </h3>
+
+<p> To get additional information about Postfix SMTP server TLS
+activity you can increase the loglevel from 0..4. Each logging
+level also includes the information that is logged at a lower
+logging level. </p>
+
+<blockquote>
+
+<table>
+
+<tr> <td> 0 </td> <td> Disable logging of TLS activity.</td> </tr>
+
+<tr> <td> 1 </td> <td> Log TLS handshake and certificate information.
+</td> </tr>
+
+<tr> <td> 2 </td> <td> Log levels during TLS negotiation. </td>
+</tr>
+
+<tr> <td> 3 </td> <td> Log hexadecimal and ASCII dump of TLS
+negotiation process </td> </tr>
+
+<tr> <td> 4 </td> <td> Log hexadecimal and ASCII dump of complete
+transmission after STARTTLS </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> Use loglevel 3 only in case of problems. Use of loglevel 4 is
+strongly discouraged. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_loglevel = 0
+</pre>
+</blockquote>
+
+<p> To include information about the protocol and cipher used as
+well as the client and issuer CommonName into the "Received:"
+message header, set the smtpd_tls_received_header variable to true.
+The default is no, as the information is not necessarily authentic.
+Only information recorded at the final destination is reliable,
+since the headers may be changed by intermediate servers. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_received_header = yes
+</pre>
+</blockquote>
+
+<h3><a name="server_enable">Enabling TLS in the Postfix SMTP server </a> </h3>
+
+<p> By default, TLS is disabled in the Postfix SMTP server, so no
+difference to plain Postfix is visible. Explicitly switch it on
+using "smtpd_use_tls = yes". </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_use_tls = yes
+</pre>
+</blockquote>
+
+<p> With this, Postfix SMTP server announces STARTTLS support to
+SMTP clients, but does not require that clients use TLS encryption.
+</p>
+
+<p> Note: when an unprivileged user invokes "sendmail -bs", STARTTLS
+is never offered due to insufficient privileges to access the server
+private key. This is intended behavior. </p>
+
+<p> You can ENFORCE the use of TLS, so that the Postfix SMTP server
+announces STARTTLS and accepts no mail without TLS encryption, by
+setting "smtpd_enforce_tls = yes". According to RFC 2487 this MUST
+NOT be applied in case of a publicly-referenced Postfix SMTP server.
+This option is off by default and should only seldom be used. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_enforce_tls = yes
+</pre>
+</blockquote>
+
+<p> TLS is sometimes used in the non-standard "wrapper" mode where
+a server always uses TLS, instead of announcing STARTTLS support
+and waiting for clients to request TLS service. Some clients, namely
+Outlook [Express] prefer the "wrapper" mode. This is true for OE
+(Win32 &lt; 5.0 and Win32 &gt;=5.0 when run on a port&lt;&gt;25
+and OE (5.01 Mac on all ports). </p>
+
+<p> It is strictly discouraged to use this mode from main.cf. If
+you want to support this service, enable a special port in master.cf
+and specify "-o smtpd_tls_wrappermode = yes" as an smtpd(8) command
+line option. Port 465 (smtps) was once chosen for this feature.
+</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtps inet n - n - - smtpd
+ -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
+</pre>
+</blockquote>
+
+<h3><a name="server_vrfy_client">Client certificate verification</a> </h3>
+
+<p> To receive a remote SMTP client certificate, the Postfix SMTP
+server must explicitly ask for one (any contents of $smtpd_tls_CAfile
+are also sent to the client as a hint for choosing a certificate
+from a suitable CA). Unfortunately, Netscape clients will either
+complain if no matching client certificate is available or will
+offer the user client a list of certificates to choose from.
+Additionally some MTAs (notably some versions of qmail) are unable
+to complete TLS negotiation when client certificates are requested,
+and abort the SMTP session. So this option is "off" by default.
+You will however need the certificate if you want to use certificate
+based relaying with, for example, the permit_tls_clientcerts
+feature. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_ask_ccert = no
+</pre>
+</blockquote>
+
+<p> You may also decide to REQUIRE a remote SMTP client certificate
+before allowing TLS connections. This feature is included for
+completeness, and implies "smtpd_tls_ask_ccert = yes". </p>
+
+<p> Please be aware, that this will inhibit TLS connections without
+a proper client certificate and that it makes sense only when
+non-TLS submission is disabled (smtpd_enforce_tls = yes). Otherwise,
+clients could bypass the restriction by simply not using STARTTLS
+at all. </p>
+
+<p> When TLS is not enforced, the connection will be handled as
+if only "smtpd_tls_ask_ccert = yes" is specified, and a warning is
+logged. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_req_ccert = no
+</pre>
+</blockquote>
+
+<p> A client certificate verification depth of 1 is sufficient if
+the certificate is directly issued by a CA listed in the CA file.
+The default value (5) should also suffice for longer chains (root
+CA issues special CA which then issues the actual certificate...)
+</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_ccert_verifydepth = 5
+</pre>
+</blockquote>
+
+<h3><a name="server_tls_auth">Supporting AUTH over TLS only</a></h3>
+
+<p> Sending AUTH data over an unencrypted channel poses a security
+risk. When TLS layer encryption is required (smtpd_enforce_tls =
+yes), the Postfix SMTP server will announce and accept AUTH only
+after the TLS layer has been activated with STARTTLS. When TLS
+layer encryption is optional (smtpd_enforce_tls = no), it may
+however still be useful to only offer AUTH when TLS is active. To
+maintain compatibility with non-TLS clients, the default is to
+accept AUTH without encryption. In order to change this behavior,
+set "smtpd_tls_auth_only = yes". </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_auth_only = no
+</pre>
+</blockquote>
+
+<h3><a name="server_tls_cache">Server-side TLS session cache</a> </h3>
+
+<p> The Postfix SMTP server and the remote SMTP client negotiate
+a session, which takes some computer time and network bandwidth.
+By default, this session information is cached only in the smtpd(8)
+process actually using this session and is lost when the process
+terminates. To share the session information between multiple
+smtpd(8) processes, a persistent session cache can be used. You
+can specify any database type that can store objects of several
+kbytes and that supports the sequence operator. DBM databases are
+not suitable because they can only store small objects. The cache
+is maintained by the tlsmgr(8) process, so there is no problem with
+concurrent access. Session caching is highly recommended, because
+the cost of repeatedly negotiating TLS session keys is high.</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_session_cache_database = btree:/etc/postfix/smtpd_scache
+</pre>
+</blockquote>
+
+<p> As of version 2.5, Postfix will no longer maintain this file
+in a directory with non-Postfix ownership. As a migration aid,
+attempts to open such files are redirected to the Postfix-owned
+$data_directory, and a warning is logged. </p>
+
+<p> Cached Postfix SMTP server session information expires after
+a certain amount of time. Postfix/TLS does not use the OpenSSL
+default of 300s, but a longer time of 3600sec (=1 hour). RFC 2246
+recommends a maximum of 24 hours. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_session_cache_timeout = 3600s
+</pre>
+</blockquote>
+
+<h3><a name="server_access">Server access control</a> </h3>
+
+<p> Postfix TLS support introduces three additional features for
+Postfix SMTP server access control: </p>
+
+<blockquote>
+
+<dl>
+
+<dt> permit_tls_clientcerts </dt> <dd> <p> Allow the remote SMTP
+client SMTP request if the client certificate passes verification,
+and if its fingerprint is listed in the list of client certificates
+(see relay_clientcerts discussion below). </p> </dd>
+
+<dt> permit_tls_all_clientcerts </dt> <dd> <p> Allow the remote
+client SMTP request if the client certificate passes verification.
+</p> </dd>
+
+<dt> check_ccert_access type:table</dt> <dd>
+<p> If the client certificate passes verification, use its fingerprint
+as a key for the specified access(5) table. </p> </dd>
+
+</dl>
+
+</blockquote>
+
+<p> The permit_tls_all_clientcerts feature must be used with caution,
+because it can result in too many access permissions. Use this
+feature only if a special CA issues the client certificates, and
+only if this CA is listed as a trusted CA. If other CAs are trusted,
+any owner of a valid client certificate would be authorized.
+The permit_tls_all_clientcerts feature can be practical for a
+specially created email relay server. </p>
+
+<p> It is however recommended to stay with the permit_tls_clientcerts
+feature and list all certificates via $relay_clientcerts, as
+permit_tls_all_clientcerts does not permit any control when a
+certificate must no longer be used (e.g. an employee leaving). </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ ...
+ permit_tls_clientcerts
+ reject_unauth_destination
+ ...
+</pre>
+</blockquote>
+
+<p> The Postfix list manipulation routines give special treatment
+to whitespace and some other characters, making the use of certificate
+names impractical. Instead we use the certificate fingerprints as
+they are difficult to fake but easy to use for lookup. Postfix
+lookup tables are in the form of (key, value) pairs. Since we only
+need the key, the value can be chosen freely, e.g. the name of
+the user or host.</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relay_clientcerts = hash:/etc/postfix/relay_clientcerts
+
+/etc/postfix/relay_clientcerts:
+ D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home
+</pre>
+</blockquote>
+
+<h3><a name="server_cipher">Server-side cipher controls</a> </h3>
+
+<p> To influence the Postfix SMTP server cipher selection scheme,
+you can give cipherlist string. A detailed description would go
+too far here; please refer to the OpenSSL documentation. If you
+don't know what to do with it, simply don't touch it and leave the
+(openssl-)compiled in default! </p>
+
+<p> DO NOT USE " to enclose the string, specify just the string!!! </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_cipherlist = DEFAULT
+</pre>
+</blockquote>
+
+<p> If you want to take advantage of ciphers with EDH, DH parameters
+are needed. Instead of using the built-in DH parameters for both
+1024bit and 512bit, it is better to generate "own" parameters,
+since otherwise it would "pay" for a possible attacker to start a
+brute force attack against parameters that are used by everybody.
+For this reason, the parameters chosen are already different from
+those distributed with other TLS packages. </p>
+
+<p> To generate your own set of DH parameters, use: </p>
+
+<blockquote>
+<pre>
+% <b>openssl gendh -out /etc/postfix/dh_1024.pem -2 -rand /var/run/egd-pool 1024</b>
+% <b>openssl gendh -out /etc/postfix/dh_512.pem -2 -rand /var/run/egd-pool 512</b>
+</pre>
+</blockquote>
+
+<p> Examples: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_dh1024_param_file = /etc/postfix/dh_1024.pem
+ smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
+</pre>
+</blockquote>
+
+<h3><a name="server_misc"> Miscellaneous server controls</a> </h3>
+
+<p> The smtpd_starttls_timeout parameter limits the time of Postfix
+SMTP server write and read operations during TLS startup and shutdown
+handshake procedures. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_starttls_timeout = 300s
+</pre>
+</blockquote>
+
+<h2> <a name="client_tls">SMTP Client specific settings</a> </h2>
+
+<p> Topics covered in this section: </p>
+
+<ul>
+
+<li><a href="#client_cert_key">Client-side certificate and private
+key configuration </a>
+
+<li><a href="#client_logging"> Client-side TLS activity logging
+</a>
+
+<li><a href="#client_tls_cache">Client-side TLS session cache</a>
+
+<li><a href="#client_tls_enable"> Enabling TLS in the Postfix SMTP client </a>
+
+<li><a href="#client_tls_require"> Requiring TLS encryption </a>
+
+<li><a href="#client_tls_nopeer"> Disabling server certificate verification </a>
+
+<li><a href="#client_tls_per_site"> Per-site TLS policies </a>
+
+<!--
+<li><a href="#client_tls_obs"> Obsolete per-site TLS policy support </a>
+-->
+
+<li><a href="#client_tls_harden"> Closing a DNS loophole with <!-- legacy --> per-site TLS policies </a>
+
+<li><a href="#client_tls_discover"> Discovering servers that support TLS </a>
+
+<li><a href="#client_vrfy_server">Server certificate verification depth</a>
+
+<li> <a href="#client_cipher">Client-side cipher controls </a>
+
+<li> <a href="#client_misc"> Miscellaneous client controls </a>
+
+</ul>
+
+<h3><a name="client_cert_key">Client-side certificate and private
+key configuration </a> </h3>
+
+<p> During TLS startup negotiation the Postfix SMTP client may present
+a certificate to the remote SMTP server. The Netscape client is
+rather clever here and lets the user select between only those
+certificates that match CA certificates offered by the remote SMTP
+server. As the Postfix SMTP client uses the "SSL_connect()" function
+from the OpenSSL package, this is not possible and we have to choose
+just one certificate. So for now the default is to use _no_
+certificate and key unless one is explicitly specified here. </p>
+
+<p> Both RSA and DSA certificates are supported. You can have both
+at the same time, in which case the cipher used determines which
+certificate is presented. </p>
+
+<p> It is possible for the Postfix SMTP client to use the same
+key/certificate pair as the Postfix SMTP server. If a certificate
+is to be presented, it must be in "pem" format. The private key
+must not be encrypted, meaning: it must be accessible without
+a password. Both parts (certificate and private key) may be in the
+same file. </p>
+
+<p> In order for remote SMTP servers to verify the Postfix SMTP
+client certificates, the CA certificate (in case of a certificate
+chain, all CA certificates) must be available. You should add
+these certificates to the client certificate, the client certificate
+first, then the issuing CA(s). </p>
+
+<p> Example: the certificate for "client.example.com" was issued by
+"intermediate CA" which itself has a certificate of "root CA".
+Create the client.pem file with: </p>
+
+<blockquote>
+<pre>
+% <b>cat client_cert.pem intermediate_CA.pem &gt; client.pem </b>
+</pre>
+</blockquote>
+
+<p> A Postfix SMTP client certificate supplied here must be usable
+as an SSL client certificate and hence pass the "openssl verify -purpose
+sslclient ..." test. </p>
+
+<p> A server that trusts the root CA has a local copy of the root
+CA certificate, so it is not necessary to include the root CA
+certificate here. Leaving it out of the "client.pem" file reduces
+the overhead of the TLS exchange. </p>
+
+<p> If you want the Postfix SMTP client to accept remote SMTP server
+certificates issued by these CAs, append the root certificate to
+$smtp_tls_CAfile or install it in the $smtp_tls_CApath directory. When
+you configure trust in a root CA, it is not necessary to explicitly trust
+intermediary CAs signed by the root CA, unless $smtp_tls_scert_verifydepth
+is less than the number of CAs in the certificate chain for the servers
+of interest. With a verify depth of 1 you can only verify certificates
+directly signed by a trusted CA, and all trusted intermediary CAs need to
+be configured explicitly. With a verify depth of 2 you can verify servers
+signed by a root CA or a direct intermediary CA (so long as the server
+is correctly configured to supply its intermediate CA certificate). </p>
+
+<p> RSA key and certificate examples: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_cert_file = /etc/postfix/client.pem
+ smtp_tls_key_file = $smtp_tls_cert_file
+</pre>
+</blockquote>
+
+<p> Their DSA counterparts: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_dcert_file = /etc/postfix/client-dsa.pem
+ smtp_tls_dkey_file = $smtp_tls_dcert_file
+</pre>
+</blockquote>
+
+<p> To verify a remote SMTP server certificate, the Postfix SMTP
+client needs to trust the certificates of the issuing Certification
+Authorities. These certificates in "pem" format can be stored in a
+single $smtp_tls_CAfile or in multiple files, one CA per file in
+the $smtp_tls_CApath directory. If you use a directory, don't forget
+to create the necessary "hash" links with: </p>
+
+<blockquote>
+<pre>
+# <b>$OPENSSL_HOME/bin/c_rehash <i>/path/to/directory</i> </b>
+</pre>
+</blockquote>
+
+<p> The $smtp_tls_CAfile contains the CA certificates of one or more
+trusted CAs. The file is opened (with root privileges) before Postfix
+enters the optional chroot jail and so need not be accessible from inside the
+chroot jail. </p>
+
+<p> Additional trusted CAs can be specified via the $smtp_tls_CApath
+directory, in which case the certificates are read (with $mail_owner
+privileges) from the files in the directory when the information
+is needed. Thus, the $smtp_tls_CApath directory needs to be accessible
+inside the optional chroot jail. </p>
+
+<p> The choice between $smtp_tls_CAfile and $smtp_tls_CApath is
+a space/time tradeoff. If there are many trusted CAs, the cost of
+preloading them all into memory may not pay off in reduced access time
+when the certificate is needed. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_CAfile = /etc/postfix/CAcert.pem
+ smtp_tls_CApath = /etc/postfix/certs
+</pre>
+</blockquote>
+
+<h3><a name="client_logging"> Client-side TLS activity logging </a> </h3>
+
+<p> To get additional information about Postfix SMTP client TLS
+activity you can increase the loglevel from 0..4. Each logging
+level also includes the information that is logged at a lower
+logging level. </p>
+
+<blockquote>
+
+<table>
+
+<tr> <td> 0 </td> <td> Disable logging of TLS activity.</td> </tr>
+
+<tr> <td> 1 </td> <td> Log TLS handshake and certificate information.
+</td> </tr>
+
+<tr> <td> 2 </td> <td> Log levels during TLS negotiation. </td>
+</tr>
+
+<tr> <td> 3 </td> <td> Log hexadecimal and ASCII dump of TLS
+negotiation process </td> </tr>
+
+<tr> <td> 4 </td> <td> Log hexadecimal and ASCII dump of complete
+transmission after STARTTLS </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_loglevel = 0
+</pre>
+</blockquote>
+
+<h3><a name="client_tls_cache">Client-side TLS session cache</a> </h3>
+
+<p> The remote SMTP server and the Postfix SMTP client negotiate a
+session, which takes some computer time and network bandwidth. By
+default, this session information is cached only in the smtp(8)
+process actually using this session and is lost when the process
+terminates. To share the session information between multiple
+smtp(8) processes, a persistent session cache can be used. You
+can specify any database type that can store objects of several
+kbytes and that supports the sequence operator. DBM databases are
+not suitable because they can only store small objects. The cache
+is maintained by the tlsmgr(8) process, so there is no problem with
+concurrent access. Session caching is highly recommended, because
+the cost of repeatedly negotiating TLS session keys is high. Future
+Postfix SMTP servers may limit the number of sessions that a client
+is allowed to negotiate per unit time.</p>
+
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_session_cache_database = btree:/etc/postfix/smtp_scache
+</pre>
+</blockquote>
+
+<p> As of version 2.5, Postfix will no longer maintain this file
+in a directory with non-Postfix ownership. As a migration aid,
+attempts to open such files are redirected to the Postfix-owned
+$data_directory, and a warning is logged. </p>
+
+<p> Cached Postfix SMTP client session information expires after
+a certain amount of time. Postfix/TLS does not use the OpenSSL
+default of 300s, but a longer time of 3600s (=1 hour). RFC 2246
+recommends a maximum of 24 hours. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_session_cache_timeout = 3600s
+</pre>
+</blockquote>
+
+<h3><a name="client_tls_enable"> Enabling TLS in the Postfix SMTP
+client </a> </h3>
+
+<p> By default, TLS is disabled in the Postfix SMTP client, so no
+difference to plain Postfix is visible. If you enable TLS, the
+Postfix SMTP client will send STARTTLS when TLS support is announced
+by the remote SMTP server. </p>
+
+<p> When the server accepts the STARTTLS command, but the subsequent
+TLS handshake fails, and no other server is available, the Postfix SMTP
+client defers the delivery attempt, and the mail stays in the queue. After
+a handshake failure, the communications channel is in an indeterminate
+state and cannot be used for non-TLS deliveries. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_use_tls = yes
+</pre>
+</blockquote>
+
+<h3><a name="client_tls_require"> Requiring TLS encryption </a>
+</h3>
+
+<p> You can ENFORCE the use of TLS, so that the Postfix SMTP client
+will not deliver mail over unencrypted connections. In this mode,
+the remote SMTP server hostname must match the information in the
+remote server certificate, and the server certificate must be issued
+by a CA that is trusted by the Postfix SMTP client. If the remote
+server certificate doesn't verify or the remote SMTP server hostname
+doesn't match, and no other server is available, the delivery
+attempt is deferred and the mail stays in the queue. </p>
+
+<p> The remote SMTP server hostname is verified against all names
+provided as dNSNames
+in the SubjectAlternativeName. If no dNSNames are specified, the
+CommonName is checked. Verification may be turned off with the
+smtp_tls_enforce_peername option which is discussed below. </p>
+
+<p> Enforcing the use of TLS is useful if you know that you will
+only
+connect to servers that support RFC 2487 _and_ that present server
+certificates that meet the above requirements. An example would
+be a client only sends email to one specific mailhub that offers
+the necessary STARTTLS support. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_enforce_tls = yes
+</pre>
+</blockquote>
+
+<h3> <a name="client_tls_nopeer"> Disabling server certificate
+verification </a> </h3>
+
+<p> As of RFC 2487 the requirements for hostname checking for MTA
+clients are not set. When TLS is required (smtp_enforce_tls = yes),
+the option smtp_tls_enforce_peername can be set to "no" to disable
+strict remote SMTP server hostname checking. In this case, the mail
+delivery will proceed regardless of the CommonName etc. listed in
+the certificate. </p>
+
+<p> Despite the potential for eliminating "man-in-the-middle" and
+other attacks, mandatory certificate/peername verification is not
+viable as a default Internet mail delivery policy at this time. A
+significant fraction of TLS enabled MTAs uses self-signed certificates,
+or certificates that are signed by a private Certification Authority.
+On a machine that delivers mail to the Internet, if you set
+smtp_enforce_tls = yes, you should probably also set
+smtp_tls_enforce_peername = no. You can use the per-site TLS
+policies (see below) to enable full peer verification for specific
+destinations that are known to have verifiable TLS server certificates.
+</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_enforce_tls = yes
+ smtp_tls_enforce_peername = no
+</pre>
+</blockquote>
+
+<h3> <a name="client_tls_per_site"> Per-site TLS policies </a> </h3>
+
+<p> A small fraction of servers offer STARTTLS but the negotiation
+consistently fails, leading to mail aging out of the queue and
+bouncing back to the sender. In such cases, you can use the per-site
+policies to disable TLS for the problem sites. Alternatively, you
+can enable TLS for just a few specific sites and not enable it for
+all sites. </p>
+
+<!-- insert new-style TLS policy mechanism here
+
+<h3> <a name="client_tls_obs"> Obsolete per-site TLS policy support
+</a> </h3>
+
+<p> This section describes an obsolete per-site TLS policy mechanism.
+Unlike the newer mechanism it supports TLS policy lookup by server
+hostname, and lacks control over what names can appear in server
+certificates. Because of this, the obsolete mechanism is vulnerable
+to false DNS hostname information in MX or CNAME records. These
+attacks can be eliminated only with great difficulty. </p>
+
+-->
+
+<p> The smtp_tls_per_site table is searched for a policy that matches
+the following information: </p>
+
+<blockquote>
+
+<dl>
+
+<dt> remote SMTP server hostname </dt> <dd> This is simply the DNS
+name of the server that the Postfix SMTP client connects to; this
+name may be obtained from other DNS lookups, such as MX lookups or
+CNAME lookups. </dd>
+
+<dt> next-hop destination </dt> <dd> This is normally the domain
+portion of the recipient address, but it may be overruled by
+information from the transport(5) table, from the relayhost parameter
+setting, or from the relay_transport setting. When it's not the
+recipient domain, the next-hop destination can have the Postfix-specific
+form "<tt>[name]</tt>", <tt>[name]:port</tt>", "<tt>name</tt>" or
+"<tt>name:port</tt>". </dd>
+
+</dl>
+
+</blockquote>
+
+<p> When both the hostname lookup and the next-hop lookup succeed,
+the host policy does not automatically override the next-hop policy.
+Instead, precedence is given to either the more specific or the
+more secure per-site policy as described below. </p>
+
+<p> The smtp_tls_per_site table uses a simple "<i>name whitespace
+value</i>" format. Specify host names or next-hop destinations on
+the left-hand side; no wildcards are allowed. On the right hand
+side specify one of the following keywords: </p>
+
+<blockquote>
+
+<dl>
+
+<dt> NONE </dt> <dd> Don't use TLS at all. This overrides a less
+specific <b>MAY</b> lookup result from the alternate host or next-hop
+lookup key, and overrides the global smtp_use_tls, smtp_enforce_tls,
+and smtp_tls_enforce_peername settings. </dd>
+
+<dt> MAY </dt> <dd> Try to use TLS if the server announces support,
+otherwise use the unencrypted connection. This has less precedence
+than a more specific result (including <b>NONE</b>) from the alternate
+host or next-hop lookup key, and has less precedence than the more
+specific global "smtp_enforce_tls = yes" or "smtp_tls_enforce_peername
+= yes". </dd>
+
+<dt> MUST_NOPEERMATCH </dt> <dd> Require TLS encryption, but do not
+require that the remote SMTP server hostname matches the information
+in the remote SMTP server certificate, or that the server certificate
+was issued by a trusted CA. This overrides a less secure <b>NONE</b>
+or a less specific <b>MAY</b> lookup result from the alternate host
+or next-hop lookup key, and overrides the global smtp_use_tls,
+smtp_enforce_tls and smtp_tls_enforce_peername settings. </dd>
+
+<dt> MUST </dt> <dd> Require TLS encryption, require that the remote
+SMTP server hostname matches the information in the remote SMTP
+server certificate, and require that the remote SMTP server certificate
+was issued by a trusted CA. This overrides a less secure <b>NONE</b>
+and <b>MUST_NOPEERMATCH</b> or a less specific <b>MAY</b> lookup
+result from the alternate host or next-hop lookup key, and overrides
+the global smtp_use_tls, smtp_enforce_tls and smtp_tls_enforce_peername
+settings. </dd>
+
+</dl>
+
+</blockquote>
+
+<p> The precedences between global (main.cf) and per-site TLS
+policies can be summarized as follows: </p>
+
+<ul>
+
+<li> <p> When neither the remote SMTP server hostname nor the
+next-hop destination are found in the smtp_tls_per_site table, the
+policy is based on smtp_use_tls, smtp_enforce_tls and
+smtp_tls_enforce_peername. Note: "smtp_enforce_tls = yes" and
+"smtp_tls_enforce_peername = yes" imply "smtp_use_tls = yes". </p>
+
+<li> <p> When both hostname and next-hop destination lookups produce
+a result, the more specific per-site policy (NONE, MUST, etc.)
+overrides the less specific one (MAY), and the more secure per-site
+policy (MUST, etc.) overrides the less secure one (NONE). </p>
+
+<li> <p> After the per-site policy lookups are combined, the result
+generally overrides the global policy. The exception is the less
+specific <b>MAY</b> per-site policy, which is overruled by the more
+specific global "smtp_enforce_tls = yes" with server certificate
+verification as specified with the smtp_tls_enforce_peername
+parameter. </p>
+
+</ul>
+
+<h3> <a name="client_tls_harden"> Closing a DNS loophole with
+<!-- legacy --> per-site TLS policies </a> </h3>
+
+<p> As long as no secure DNS lookup mechanism is available, false
+hostnames in MX or CNAME responses can change the server hostname
+that Postfix uses for TLS policy lookup and server certificate
+verification. Even with a perfect match between the server hostname
+and the server certificate, there is no guarantee that Postfix is
+connected to the right server. To avoid this loophole take the
+following steps: </p>
+
+<ul>
+
+<li> <p> Eliminate MX lookups. Specify local transport(5) table
+entries for sensitive domains with explicit smtp:[<i>mailhost</i>]
+or smtp:[<i>mailhost</i>]:<i>port</i> destinations (you can assure
+security of this table unlike DNS); in the smtp_tls_per_site table
+specify the value <b>MUST</b> for the key [<i>mailhost</i>] or
+smtp:[<i>mailhost</i>]:<i>port</i>. This prevents false hostname
+information in DNS MX records from changing the server hostname
+that Postfix uses for TLS policy lookup and server certificate
+verification. </p>
+
+<li> <p> Disallow CNAME hostname overrides. In main.cf specify
+"smtp_cname_overrides_servername = no". This prevents false hostname
+information in DNS CNAME records from changing the server hostname
+that Postfix uses for TLS policy lookup and server certificate
+verification. This feature requires Postfix 2.2.9 or later. </p>
+
+</ul>
+
+<p> Example: </p>
+
+<blockquote> <pre>
+/etc/postfix/main.cf:
+ smtp_tls_per_site = hash:/etc/postfix/tls_per_site
+ relayhost = [msa.example.net]:587
+
+/etc/postfix/tls_per_site:
+ # relayhost exact nexthop match
+ [msa.example.net]:587 MUST
+
+ # TLS should not be used with the <i>example.org</i> MX hosts.
+ example.org NONE
+
+ # TLS should not be used with the host <i>smtp.example.com</i>.
+ [smtp.example.com] NONE
+</pre>
+</blockquote>
+
+<h3> <a name="client_tls_discover"> Discovering servers that support
+TLS </a> </h3>
+
+<p> As we decide on a "per site" basis whether or not to use TLS,
+it would be good to have a list of sites that offered "STARTTLS".
+We can collect it ourselves with this option. </p>
+
+<p> If the smtp_tls_note_starttls_offer feature is enabled and a
+server offers STARTTLS while TLS is not already enabled for that
+server, the Postfix SMTP client logs a line as follows: </p>
+
+<blockquote>
+<pre>
+postfix/smtp[pid]: Host offered STARTTLS: [hostname.example.com]
+</pre>
+</blockquote>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_note_starttls_offer = yes
+</pre>
+</blockquote>
+
+<h3><a name="client_vrfy_server">Server certificate verification depth</a> </h3>
+
+<p> When verifying a remote SMTP server certificate, a verification
+depth of 1 is sufficient if the certificate is directly issued by
+a CA specified with smtp_tls_CAfile or smtp_tls_CApath. The default
+value of 5 should also suffice for longer chains (root CA issues
+special CA which then issues the actual certificate...) </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_scert_verifydepth = 5
+</pre>
+</blockquote>
+
+<h3> <a name="client_cipher">Client-side cipher controls </a> </h3>
+
+<p> To influence the Postfix SMTP client cipher selection scheme,
+you can give cipherlist string. A detailed description would go
+too far here; please refer to the OpenSSL documentation. If you
+don't know what to do with it, simply don't touch it and leave the
+(openssl-)compiled in default! </p>
+
+<p> DO NOT USE " to enclose the string, specify just the string!!! </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_cipherlist = DEFAULT
+</pre>
+</blockquote>
+
+<h3> <a name="client_misc"> Miscellaneous client controls </a> </h3>
+
+<p> The smtp_starttls_timeout parameter limits the time of Postfix
+SMTP client write and read operations during TLS startup and shutdown
+handshake procedures. In case of problems the Postfix SMTP client
+tries the next network address on the mail exchanger list, and
+defers delivery if no alternative server is available. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_starttls_timeout = 300s
+</pre>
+</blockquote>
+
+<h2><a name="tlsmgr_controls"> TLS manager specific settings </a> </h2>
+
+<p> The security of cryptographic software such as TLS depends
+critically on the ability to generate unpredictable numbers for
+keys and other information. To this end, the tlsmgr(8) process
+maintains a Pseudo Random Number Generator (PRNG) pool. This is
+queried by the smtp(8) and smtpd(8) processes when they initialize.
+By default, these daemons request 32 bytes, the equivalent to 256
+bits. This is more than sufficient to generate a 128bit (or 168bit)
+session key. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_daemon_random_bytes = 32
+</pre>
+</blockquote>
+
+<p> In order to feed its in-memory PRNG pool, the tlsmgr(8) reads
+entropy from an external source, both at startup and during run-time.
+Specify a good entropy source, like EGD or /dev/urandom; be sure
+to only use non-blocking sources (on OpenBSD, use /dev/arandom
+when tlsmgr(8) complains about /dev/urandom timeout errors).
+If the entropy source is not a
+regular file, you must prepend the source type to the source name:
+"dev:" for a device special file, or "egd:" for a source with EGD
+compatible socket interface. </p>
+
+<p> Examples (specify only one in main.cf): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_random_source = dev:/dev/urandom
+ tls_random_source = egd:/var/run/egd-pool
+</pre>
+</blockquote>
+
+<p> By default, tlsmgr(8) reads 32 bytes from the external entropy
+source at each seeding event. This amount (256bits) is more than
+sufficient for generating a 128bit symmetric key. With EGD and
+device entropy sources, the tlsmgr(8) limits the amount of data
+read at each step to 255 bytes. If you specify a regular file as
+entropy source, a larger amount of data can be read. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_random_bytes = 32
+</pre>
+</blockquote>
+
+<p> In order to update its in-memory PRNG pool, the tlsmgr(8)
+queries the external entropy source again after a pseudo-random
+amount of time. The time is calculated using the PRNG, and is
+between 0 and the maximal time specified with tls_random_reseed_period.
+The default maximal time interval is 1 hour. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_random_reseed_period = 3600s
+</pre>
+</blockquote>
+
+<p> The tlsmgr(8) process saves the PRNG state to a persistent
+exchange file at regular times and when the process terminates, so
+that it can recover the PRNG state the next time it starts up.
+This file is created when it does not exist. Its default location
+is under the Postfix configuration directory, which is not the
+proper place for information that is modified by Postfix. Instead,
+the file location should probably be on the /var partition (but
+<b>not</b> inside the chroot jail). </p>
+
+<p> Examples: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_random_exchange_name = /etc/postfix/prng_exch
+ tls_random_prng_update_period = 3600s
+</pre>
+</blockquote>
+
+<h2><a name="quick-start">Getting started, quick and dirty</a></h2>
+
+<p> The following steps will get you started quickly. Because you
+sign your own Postfix public key certificate, you get TLS encryption
+but no TLS authentication. This is sufficient for testing, and
+for exchanging email with sites that you have no trust relationship
+with. For real authentication, your Postfix public key certificate
+needs to be signed by a recognized Certification Authority, and
+Postfix needs to be configured with a list of public key certificates
+of Certification Authorities, so that Postfix can verify the public key
+certificates of remote hosts. </p>
+
+<p> In the examples below, user input is shown in <b><tt>bold</tt></b>
+font, and a "<tt>#</tt>" prompt indicates a super-user shell. </p>
+
+<ul>
+
+<li> <p> Become your own Certification Authority, so that you can
+sign your own public keys. This example uses the CA.pl script that
+ships with OpenSSL. By default, OpenSSL installs this as
+<tt>/usr/local/ssl/misc/CA.pl</tt>, but your mileage may vary.
+The script creates a private key in <tt>./demoCA/private/cakey.pem</tt>
+and a public key in <tt>./demoCA/cacert.pem</tt>.</p>
+
+<blockquote>
+<pre>
+% <b>/usr/local/ssl/misc/CA.pl -newca</b>
+CA certificate filename (or enter to create)
+
+Making CA certificate ...
+Using configuration from /etc/ssl/openssl.cnf
+Generating a 1024 bit RSA private key
+....................++++++
+.....++++++
+writing new private key to './demoCA/private/cakey.pem'
+Enter PEM pass phrase:<b>whatever</b>
+</pre>
+</blockquote>
+
+<li> <p> Create an unpassworded private key for host FOO 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>
+Using configuration from /etc/ssl/openssl.cnf
+Generating a 1024 bit RSA private key
+........................................++++++
+....++++++
+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.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:<b>US</b>
+State or Province Name (full name) [Some-State]:<b>New York</b>
+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>
+Email Address []:<b>wietse@porcupine.org</b>
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:<b>whatever</b>
+An optional company name []:
+</pre>
+</blockquote>
+
+<li> <p> Sign the public key certificate for host FOO 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>
+Uing configuration from /etc/ssl/openssl.cnf
+Enter PEM pass phrase:<b>whatever</b>
+Check that the request matches the signature
+Signature ok
+The Subjects Distinguished Name is as follows
+countryName :PRINTABLE:'US'
+stateOrProvinceName :PRINTABLE:'New York'
+localityName :PRINTABLE:'Westchester'
+organizationName :PRINTABLE:'Porcupine'
+commonName :PRINTABLE:'FOO'
+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>
+
+
+1 out of 1 certificate requests certified, commit? [y/n]<b>y</b>
+Write out database with 1 new entries
+Data Base Updated
+</pre>
+</blockquote>
+
+<li> <p> Install the host private key, the host public key certificate,
+and the Certification Authority certificate files. This requires
+super-user privileges. </p>
+
+<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>
+</pre>
+</blockquote>
+
+<li> <p> Configure Postfix, by adding the following to
+<tt>/etc/postfix/main.cf </tt>. </p>
+
+<blockquote>
+<pre>
+smtp_tls_CAfile = /etc/postfix/cacert.pem
+smtp_tls_cert_file = /etc/postfix/FOO-cert.pem
+smtp_tls_key_file = /etc/postfix/FOO-key.pem
+smtp_tls_session_cache_database = btree:/var/run/smtp_tls_session_cache
+smtp_use_tls = yes
+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_received_header = yes
+smtpd_tls_session_cache_database = btree:/var/run/smtpd_tls_session_cache
+smtpd_use_tls = yes
+tls_random_source = dev:/dev/urandom
+</pre>
+</blockquote>
+
+</ul>
+
+
+<h2> <a name="problems"> Reporting problems </a> </h2>
+
+<p> When reporting a problem, please be thorough in the report.
+Patches, when possible, are greatly appreciated too. </p>
+
+<p> Please differentiate when possible between: </p>
+
+<ul>
+
+<li> Problems in the TLS code: &lt;postfix_tls@aet.tu-cottbus.de&gt;
+
+<li> Problems in vanilla Postfix: &lt;postfix-users@postfix.org&gt;
+
+</ul>
+
+<h2><a name="compat">Compatibility with Postfix &lt; 2.2 TLS support</a></h2>
+
+<p> Postfix version 2.2 TLS support is based on the Postfix/TLS
+patch by Lutz J&auml;nicke, but differs in a few minor ways. </p>
+
+<ul>
+
+<li> <p> main.cf: Specify "btree" instead of "sdbm" for TLS
+session cache databases. </p>
+
+<p> TLS session cache databases are now accessed only by the
+tlsmgr(8) process, so there are no more concurrency issues. Although
+Postfix has an sdbm client, the sdbm library (1000
+lines of code) is not included with Postfix. </p>
+
+<p> TLS session caches can use any database that can store objects
+of several kbytes or more, and that implements the sequence operation.
+In most cases, btree databases should be adequate. </p>
+
+<p> NOTE: You cannot use dbm databases. TLS session objects
+are too large. </p>
+
+<li> <p> master.cf: Specify "unix" instead of "fifo" as
+the tlsmgr service type. </p>
+
+<p> The smtp(8) and smtpd(8) processes now use a client-server
+protocol in order to access the tlsmgr(8) pseudo-random number
+generation (PRNG) pool, and in order to access the TLS session
+cache databases. Such a protocol cannot be run across fifos. </p>
+
+<li> <p> smtp_tls_per_site: the MUST_NOPEERMATCH per-site policy
+cannot override the global "smtp_tls_enforce_peername = yes" setting.
+</p>
+
+<li> <p> smtp_tls_per_site: a combined (NONE + MAY) lookup result
+for (hostname and next-hop destination) produces counter-intuitive
+results for different main.cf settings. TLS is enabled with
+"smtp_tls_enforce_peername = no", but it is disabled when both
+"smtp_enforce_tls = yes" and "smtp_tls_enforce_peername = yes".
+</p>
+
+</ul>
+
+<p> The smtp_tls_per_site limitations were removed by the end of
+the Postfix 2.2 support cycle. </p>
+
+<h2><a name="credits">Credits </a> </h2>
+
+<ul>
+
+<li> TLS support for Postfix was originally developed by Lutz
+J&auml;nicke at Cottbus Technical University.
+
+<li> Wietse Venema adopted the code, did some restructuring, and
+compiled this part of the documentation from Lutz's documents.
+
+<li> Victor Duchovni was instrumental with the re-implementation
+of the smtp_tls_per_site code in terms of enforcement levels, which
+simplified the implementation greatly.
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/TLS_README.html b/proto/TLS_README.html
new file mode 100644
index 0000000..b53e71b
--- /dev/null
+++ b/proto/TLS_README.html
@@ -0,0 +1,3252 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix TLS Support </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix TLS Support
+</h1>
+
+<hr>
+
+<h2> What Postfix TLS support does for you </h2>
+
+<p> Transport Layer Security (TLS, formerly called SSL) provides
+certificate-based authentication and encrypted sessions. An
+encrypted session protects the information that is transmitted with
+SMTP mail or with SASL authentication. </p>
+
+<p> NOTE: By turning on TLS support in Postfix, you not only get
+the ability to encrypt mail and to authenticate remote SMTP clients
+or servers. You also turn on hundreds of thousands of lines of
+OpenSSL library code. Assuming that OpenSSL is written as carefully
+as Wietse's own code, every 1000 lines introduces one additional bug
+into Postfix. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li><a href="#how">How Postfix TLS support works</a>
+
+<li><a href="#server_tls">SMTP Server specific settings</a>
+
+<li> <a href="#client_tls">SMTP Client specific settings</a>
+
+<li><a href="#tlsmgr_controls"> TLS manager specific settings </a>
+
+<li><a href="#build_tls">Building Postfix with TLS support</a>
+
+<li><a href="#problems"> Reporting problems </a>
+
+<li><a href="#credits"> Credits </a>
+
+</ul>
+
+<p> And last but not least, for the impatient: </p>
+
+<ul>
+
+<li><a href="#quick-start">Getting started, quick and dirty</a>
+
+</ul>
+
+<h2><a name="how">How Postfix TLS support works</a></h2>
+
+<p> The diagram below shows the main elements of the Postfix TLS
+architecture and their relationships. Colored boxes with numbered
+names represent Postfix daemon programs. Other colored boxes
+represent storage elements. </p>
+
+<ul>
+
+<li> <p> The smtpd(8) server implements the SMTP over TLS server
+side. </p>
+
+<li> <p> The smtp(8) client implements the SMTP (and LMTP) over TLS
+client side. </p>
+
+<li> <p> The tlsmgr(8) server maintains the pseudo-random number
+generator (PRNG) that seeds the TLS engines in the smtpd(8) server
+and smtp(8) client processes, and maintains the TLS session key
+cache files. </p>
+
+</ul>
+
+<p> Not shown in the figure are the tlsproxy(8) server and the
+postscreen(8) server. These use TLS in the same manner as smtpd(8).
+</p>
+
+<table>
+
+<tr> <td>Network<tt>-&gt; </tt> </td> <td align="center"
+bgcolor="#f0f0ff"> <br> <a href="smtpd.8.html">smtpd(8)</a> <br> &nbsp; </td> <td colspan="2">
+
+<tt> &lt;---seed----<br><br>&lt;-key/cert-&gt; </tt> </td> <td
+align="center" bgcolor="#f0f0ff"> <br> <a href="tlsmgr.8.html">tlsmgr(8)</a> <br> &nbsp; </td>
+<td colspan="3"> <tt> ----seed---&gt;<br> <br>&lt;-key/cert-&gt;
+
+</tt> </td> <td align="center" bgcolor="#f0f0ff"> <br> <a href="smtp.8.html">smtp(8)</a> <br>
+&nbsp; </td> <td> <tt> -&gt;</tt>Network </td> </tr>
+
+<tr> <td colspan="3"> </td> <td align="right"> <table> <tr> <td>
+
+</td> <td> / </td> </tr> <tr> <td> / </td> <td> </td> </tr> </table>
+</td> <td align="center"> |<br> |</td> <td align="left"> <table>
+
+<tr> <td> \ </td> <td> </td> </tr> <tr> <td> </td> <td> \ </td>
+</tr> </table> </td> <td colspan="3"> </td> </tr>
+
+<tr> <td colspan="2"> </td> <td align="center" bgcolor="#f0f0ff">
+smtpd<br> session<br> key cache </td> <td> </td> <td align="center"
+bgcolor="#f0f0ff"> PRNG<br> state <br>file </td> <td> </td> <td
+align="center" bgcolor="#f0f0ff"> smtp<br> session<br> key cache
+</td>
+
+<td colspan="2"> </td> </tr>
+
+</table>
+
+<h2><a name="server_tls">SMTP Server specific settings</a></h2>
+
+<p> Topics covered in this section: </p>
+
+<ul>
+
+<li><a href="#server_cert_key">Server-side certificate and private
+key configuration </a>
+
+<li><a href="#server_pfs">Server-side forward-secrecy configuration </a>
+
+<li><a href="#server_logging"> Server-side TLS activity logging
+</a>
+
+<li><a href="#server_enable">Enabling TLS in the Postfix SMTP server </a>
+
+<li><a href="#server_vrfy_client">Client certificate verification</a>
+
+<li><a href="#server_tls_auth">Supporting AUTH over TLS only</a>
+
+<li><a href="#server_tls_cache">Server-side TLS session cache</a>
+
+<li><a href="#server_access">Server access control</a>
+
+<li><a href="#server_cipher">Server-side cipher controls</a>
+
+<li><a href="#server_misc"> Miscellaneous server controls</a>
+
+</ul>
+
+<h3><a name="server_cert_key">Server-side certificate and private
+key configuration </a> </h3>
+
+<p> In order to use TLS, the Postfix SMTP server generally needs
+a certificate and a private key. Both must be in "PEM" format. The
+private key must not be encrypted, meaning: the key must be accessible
+without a password. The certificate and private key may be in the same
+file, in which case the certificate file should be owned by "root" and
+not be readable by any other user. If the key is stored separately,
+this access restriction applies to the key file only, and the
+certificate file may be "world-readable". </p>
+
+<p> Public Internet MX hosts without certificates signed by a
+well-known public CA must still generate, and be prepared to present
+to most clients, a self-signed or private-CA signed certificate.
+The remote SMTP client will generally not be able to verify the
+self-signed certificate, but unless the client is running Postfix
+or similar software, it will only negotiate TLS ciphersuites that
+require a server certificate. </p>
+
+<p> For servers that are <b>not</b> public Internet MX hosts, Postfix
+supports configurations with no certificates. This entails the use of
+just the anonymous TLS ciphers, which are not supported by typical SMTP
+clients. Since some clients may not fall back to plain text after a TLS
+handshake failure, a certificate-less Postfix SMTP server will be unable
+to receive email from some TLS-enabled clients. To avoid accidental
+configurations with no certificates, Postfix enables certificate-less
+operation only when the administrator explicitly sets
+"smtpd_tls_cert_file = none". This ensures that new Postfix SMTP server
+configurations will not accidentally enable TLS without certificates. </p>
+
+<p> Note that server certificates are <b>not</b> optional in TLS 1.3. To
+run without certificates you'd have to disable the TLS 1.3 protocol by
+including "&lt;=TLSv1.2" (or, for Postfix &lt; 3.6, "!TLSv1.3") in
+"smtpd_tls_protocols" and perhaps also "smtpd_tls_mandatory_protocols".
+It is simpler instead to just configure a certificate chain.
+Certificate-less operation is not recommended. <p>
+
+<p> RSA, DSA and ECDSA (Postfix &ge; 2.6) certificates are supported.
+Most sites only have RSA certificates. You can configure all three
+at the same time, in which case the ciphersuite negotiated with the
+remote SMTP client determines which certificate is used. If your
+DNS zone is signed, and you want to publish DANE TLSA (RFC 6698,
+RFC 7671, RFC 7672) records, these must match all of the configured
+certificate chains. Since the best practice is to publish "3 1 1"
+certificate associations, create a separate TLSA record to match
+each public-key certificate digest. </p>
+
+<h4> Creating the server certificate file </h4>
+
+<p> To verify the Postfix SMTP server certificate, the remote SMTP
+client must receive the issuing CA certificates via the TLS handshake
+or via public-key infrastructure. This means that the Postfix server
+public-key certificate file must include the server certificate
+first, then the issuing CA(s) (bottom-up order). The Postfix SMTP
+server certificate must be usable as an SSL server certificate and
+hence pass the "<tt>openssl verify -purpose sslserver ...</tt>" test.
+</p>
+
+<p> The examples that follow show how to create a server certificate
+file. We assume that the certificate for "server.example.com" was
+issued by "intermediate CA" which itself has a certificate issued
+by "root CA". </p>
+
+<ul>
+
+<li> <p> With legacy public CA trust verification, you can omit the
+root certificate from the "server.pem" certificate file. If the
+client trusts the root CA, it will already have a local copy of the
+root CA certificate. Omitting the root CA certificate reduces the
+size of the server TLS handshake. </p>
+
+<blockquote>
+<pre>
+% <b>cat server_cert.pem intermediate_CA.pem &gt; server.pem</b>
+</pre>
+</blockquote>
+
+<li> <p> If you publish DANE TLSA (RFC 6698, RFC 7671, RFC 7672)
+"2 0 1" or "2 1 1" records to specify root CA certificate digests,
+you must include the corresponding root CA certificates in the
+"server.pem" certificate file. </p>
+
+<blockquote>
+<pre>
+% <b>cat server_cert.pem intermediate_CA.pem root.pem &gt; server.pem</b>
+</pre>
+</blockquote>
+
+<p> Remote SMTP clients will be able to use the TLSA record you
+publish (which only contains the certificate digest) only if they
+have access to the corresponding certificate. Failure to verify
+certificates per the server's published TLSA records will typically
+cause the SMTP client to defer mail delivery. The foregoing also
+applies to "2 0 2" and "2 1 2" TLSA records or any other digest of
+a CA certificate, but it is expected that SHA256 will be by far the
+most common digest for TLSA. </p>
+
+<p> As a best practice, publish "3 1 1" TLSA associations that specify
+the SHA256 digest of the server's public key. These continue to work
+unmodified when a certificate is renewed with the same public/private
+key pair. </p>
+
+</ul>
+
+<p> For instructions on how to compute the digest of a certificate
+or its public key for use in TLSA records, see the documentation of
+the smtpd_tls_fingerprint_digest main.cf parameter. </p>
+
+<p> When a new key or certificate is generated, an additional TLSA
+record with the new digest must be published in advance of the
+actual deployment of the new key or certificate on the server. You
+must allow sufficient time for any TLSA RRsets with only the old
+digest to expire from DNS caches. The safest practice is to wait
+until the DNSSEC signature on the previous TLSA RRset expires, and
+only then switch the server to use new keys published in the updated
+TLSA RRset. Once the new certificate trust chain and private key
+are in effect, the DNS should be updated once again to remove the
+old digest from the TLSA RRset. </p>
+
+<p> If you want the Postfix SMTP server to accept remote SMTP client
+certificates issued by one or more root CAs, append the root
+certificate to $smtpd_tls_CAfile or install it in the $smtpd_tls_CApath
+directory. </p>
+
+<h4> Configuring the server certificate and key files </h4>
+
+<p> Example: Postfix &ge; 3.4 all-in-one chain file(s). One or more
+chain files that start with a key that is immediately followed by the
+corresponding certificate and any additional issuer certificates. A
+single file can hold multiple <i>(key, cert, [chain])</i> sequences, one
+per algorithm. It is typically simpler to keep the chain for each
+algorithm in its own file. Most users are likely to deploy just a
+single RSA chain, but with OpenSSL 1.1.1, it is possible to deploy up to
+five chains, one each for RSA, ECDSA, ED25519, ED448, and even the
+obsolete DSA. </p>
+
+<blockquote>
+<pre>
+ # Postfix &ge; 3.4. Preferred configuration interface. Each file
+ # starts with the private key, followed by the corresponding
+ # certificate, and any intermediate issuer certificates. The root CA
+ # cert may also be needed when published as a DANE trust anchor.
+ #
+ smtpd_tls_chain_files =
+ /etc/postfix/rsa.pem,
+ /etc/postfix/ecdsa.pem,
+ /etc/postfix/ed25519.pem,
+ /etc/postfix/ed448.pem
+</pre>
+</blockquote>
+
+<p> You can also store the keys separately from their certificates, again
+provided each is listed before the corresponding certificate chain. Storing a
+key and its associated certificate chain in separate files is not recommended,
+because this is prone to race conditions during key rollover, as there is no
+way to update multiple files atomically. </p>
+
+<blockquote>
+<pre>
+ # Postfix &ge; 3.4.
+ # Storing keys separately from the associated certificates is not
+ # recommended.
+ smtpd_tls_chain_files =
+ /etc/postfix/rsakey.pem,
+ /etc/postfix/rsacerts.pem,
+ /etc/postfix/ecdsakey.pem,
+ /etc/postfix/ecdsacerts.pem
+</pre>
+</blockquote>
+
+<p> The below examples show the legacy algorithm-specific configurations
+for Postfix 3.3 and older. With Postfix &le; 3.3, even if the key is
+stored in the same file as the certificate, the file is read twice and a
+(brief) race condition still exists during key rollover. While Postfix
+&ge; 3.4 avoids the race when the key and certificate are in the same
+file, you should use the new "smtpd_tls_chain_files" interface shown
+above. <p>
+
+<p> RSA key and certificate examples: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_cert_file = /etc/postfix/server.pem
+ smtpd_tls_key_file = $smtpd_tls_cert_file
+</pre>
+</blockquote>
+
+<p> Their DSA counterparts: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem
+ smtpd_tls_dkey_file = $smtpd_tls_dcert_file
+</pre>
+</blockquote>
+
+<p> Their ECDSA counterparts (Postfix &ge; 2.6 + OpenSSL &ge; 1.0.0): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Some clients will not be ECDSA capable, so you will likely still need
+ # an RSA certificate and private key.
+ #
+ smtpd_tls_eccert_file = /etc/postfix/server-ecdsa.pem
+ smtpd_tls_eckey_file = $smtpd_tls_eccert_file
+</pre>
+</blockquote>
+
+<p> TLS without certificates for servers serving exclusively
+anonymous-cipher capable clients: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Not recommended: breaks TLS 1.3 and clients that don't support
+ # anonymous cipher suites.
+ smtpd_tls_cert_file = none
+</pre>
+</blockquote>
+
+<p> To verify a remote SMTP client certificate, the Postfix SMTP
+server needs to trust the certificates of the issuing Certification
+Authorities. These certificates in "PEM" format can be stored in a
+single $smtpd_tls_CAfile or in multiple files, one CA per file in
+the $smtpd_tls_CApath directory. If you use a directory, don't forget
+to create the necessary "hash" links with: </p>
+
+<blockquote>
+<pre>
+# <b>$OPENSSL_HOME/bin/c_rehash <i>/path/to/directory</i> </b>
+</pre>
+</blockquote>
+
+<p> The $smtpd_tls_CAfile contains the CA certificates of one or
+more trusted CAs. The file is opened (with root privileges) before
+Postfix enters the optional chroot jail and so need not be accessible
+from inside the chroot jail. </p>
+
+<p> Additional trusted CAs can be specified via the $smtpd_tls_CApath
+directory, in which case the certificates are read (with $mail_owner
+privileges) from the files in the directory when the information
+is needed. Thus, the $smtpd_tls_CApath directory needs to be
+accessible inside the optional chroot jail. </p>
+
+<p> When you configure the Postfix SMTP server to request <a
+href="#server_vrfy_client">client certificates</a>, the DNs of Certification
+Authorities in $smtpd_tls_CAfile are sent to the client, in order to allow
+it to choose an identity signed by a CA you trust. If no $smtpd_tls_CAfile
+is specified, no preferred CA list is sent, and the client is free to
+choose an identity signed by any CA. Many clients use a fixed identity
+regardless of the preferred CA list and you may be able to reduce TLS
+negotiation overhead by installing client CA certificates mostly or
+only in $smtpd_tls_CApath. In the latter case you need not specify a
+$smtpd_tls_CAfile. </p>
+
+<p> Note, that unless client certificates are used to allow greater
+access to TLS authenticated clients, it is best to not ask for
+client certificates at all, as in addition to increased overhead
+some clients (notably in some cases qmail) are unable to complete
+the TLS handshake when client certificates are requested. </p>
+
+<p> Example: </p>
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_CAfile = /etc/postfix/CAcert.pem
+ smtpd_tls_CApath = /etc/postfix/certs
+</pre>
+</blockquote>
+
+<h3><a name="server_pfs"> Server-side forward-secrecy configuration </a> </h3>
+
+<p> If you want to take maximal advantage of ciphers that offer <a
+href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see
+the <a href="FORWARD_SECRECY_README.html#quick-start">Getting
+started</a> section of <a
+href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The
+full document conveniently presents all information about Postfix
+forward secrecy support in one place: what forward secrecy is, how
+to tweak settings, and what you can expect to see when Postfix uses
+ciphers with forward secrecy. </p>
+
+<h3><a name="server_logging"> Server-side TLS activity logging </a> </h3>
+
+<p> To get additional information about Postfix SMTP server TLS
+activity you can increase the log level from 0..4. Each logging
+level also includes the information that is logged at a lower
+logging level. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Level </th> <th> Postfix 2.9 and later</th> <th> Earlier
+releases. </th> </tr>
+
+<tr> <td valign="top"> 0 </td> <td valign="top" colspan="2"> Disable
+logging of TLS activity. </td> </tr>
+
+<tr> <td valign="top"> 1 </td> <td valign="top"> Log only a summary
+message on TLS handshake completion &mdash; no logging of client
+certificate trust-chain verification errors if client certificate
+verification is not required. </td> <td valign="top"> Log the summary
+message, peer certificate summary information and unconditionally log
+trust-chain verification errors. </td> </tr>
+
+<tr> <td valign="top"> 2 </td> <td valign="top" colspan="2"> Also
+log levels during TLS negotiation. </td> </tr>
+
+<tr> <td valign="top"> 3 </td> <td valign="top" colspan="2"> Also
+log hexadecimal and ASCII dump of TLS negotiation process. </td>
+</tr>
+
+<tr> <td valign="top"> 4 </td> <td valign="top" colspan="2"> Also
+log hexadecimal and ASCII dump of complete transmission after
+STARTTLS. </td></tr>
+
+</table>
+
+</blockquote>
+
+<p> Use log level 3 only in case of problems. Use of log level 4 is
+strongly discouraged. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_loglevel = 0
+</pre>
+</blockquote>
+
+<p> To include information about the protocol and cipher used as
+well as the client and issuer CommonName into the "Received:"
+message header, set the smtpd_tls_received_header variable to true.
+The default is no, as the information is not necessarily authentic.
+Only information recorded at the final destination is reliable,
+since the headers may be changed by intermediate servers. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_received_header = yes
+</pre>
+</blockquote>
+
+<h3><a name="server_enable">Enabling TLS in the Postfix SMTP server </a> </h3>
+
+<p> By default, TLS is disabled in the Postfix SMTP server, so no
+difference to plain Postfix is visible. Explicitly switch it on
+with "smtpd_tls_security_level = may". </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_security_level = may
+</pre>
+</blockquote>
+
+<p> With this, the Postfix SMTP server announces STARTTLS support to
+remote SMTP clients, but does not require that clients use TLS encryption.
+</p>
+
+<p> Note: when an unprivileged user invokes "sendmail -bs", STARTTLS
+is never offered due to insufficient privileges to access the Postfix
+SMTP server
+private key. This is intended behavior. </p>
+
+<p> <a name="server_enforce">You can ENFORCE the use of TLS</a>,
+so that the Postfix SMTP server announces STARTTLS and accepts no
+mail without TLS encryption, by setting
+"smtpd_tls_security_level = encrypt". According to RFC 2487 this
+MUST NOT be applied in case
+of a publicly-referenced Postfix SMTP server. This option is off
+by default and should only seldom be used. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_security_level = encrypt
+</pre>
+</blockquote>
+
+<p> TLS is also used in the "wrapper" mode where
+a server always uses TLS, instead of announcing STARTTLS support
+and waiting for remote SMTP clients to request TLS service. Some
+clients, namely
+Outlook [Express] prefer the "wrapper" mode. This is true for OE
+(Win32 &lt; 5.0 and Win32 &gt;=5.0 when run on a port&lt;&gt;25
+and OE (5.01 Mac on all ports). </p>
+
+<p> It is strictly discouraged to use this mode from main.cf. If
+you want to support this service, enable a special port in master.cf
+and specify "-o smtpd_tls_wrappermode=yes" (note: no space around
+the "=") as an smtpd(8) command line option. Port 465 (smtps) was
+once chosen for this feature.
+</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtps inet n - n - - smtpd
+ -o smtpd_tls_wrappermode=yes -o smtpd_sasl_auth_enable=yes
+</pre>
+</blockquote>
+
+<h3><a name="server_vrfy_client">Client certificate verification</a> </h3>
+
+<p> To receive a remote SMTP client certificate, the Postfix SMTP
+server must explicitly ask for one (any contents of $smtpd_tls_CAfile
+are also sent to the client as a hint for choosing a certificate from
+a suitable CA). Unfortunately, Netscape clients will either complain
+if no matching client certificate is available or will offer the user
+client a list of certificates to choose from. Additionally some MTAs
+(notably some versions of qmail) are unable to complete TLS negotiation
+when client certificates are requested, and abort the SMTP session. So
+this option is "off" by default. You will however need the certificate
+if you want to use certificate based relaying with, for example, the
+permit_tls_clientcerts feature. A server that wants client certificates
+must first present its own certificate. While Postfix by default
+offers anonymous ciphers to remote SMTP clients, these are automatically
+suppressed
+when the Postfix SMTP server is configured to ask for client
+certificates. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_ask_ccert = yes
+ smtpd_tls_security_level = may
+</pre>
+</blockquote>
+
+<p> When TLS is <a href="#server_enforce">enforced</a> you may also decide
+to REQUIRE a remote SMTP client certificate for all TLS connections,
+by setting "smtpd_tls_req_ccert = yes". This feature implies
+"smtpd_tls_ask_ccert = yes". When TLS is not enforced,
+"smtpd_tls_req_ccert = yes" is ignored and a warning is
+logged. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_req_ccert = yes
+ smtpd_tls_security_level = encrypt
+</pre>
+</blockquote>
+
+<p> The client certificate verification depth is specified with the
+main.cf smtpd_tls_ccert_verifydepth parameter. The default verification
+depth is 9 (the OpenSSL default), for compatibility with Postfix
+versions before 2.5 where smtpd_tls_ccert_verifydepth was ignored.
+When you configure trust in a
+root CA, it is not necessary to explicitly trust intermediary CAs signed
+by the root CA, unless $smtpd_tls_ccert_verifydepth is less than the
+number of CAs in the certificate chain for the clients of interest. With
+a verify depth of 1 you can only verify certificates directly signed
+by a trusted CA, and all trusted intermediary CAs need to be configured
+explicitly. With a verify depth of 2 you can verify clients signed by a
+root CA or a direct intermediary CA (so long as the client is correctly
+configured to supply its intermediate CA certificate). </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_ccert_verifydepth = 2
+</pre>
+</blockquote>
+
+<h3><a name="server_tls_auth">Supporting AUTH over TLS only</a></h3>
+
+<p> Sending AUTH data over an unencrypted channel poses a security
+risk. When TLS layer encryption is required
+("smtpd_tls_security_level = encrypt"), the Postfix SMTP server will
+announce and accept AUTH only after the TLS layer has been activated
+with STARTTLS. When TLS layer encryption is optional
+("smtpd_tls_security_level = may"), it may however still be useful
+to only offer AUTH when TLS is active. To maintain compatibility
+with non-TLS clients, the default is to accept AUTH without encryption.
+In order to change this behavior, set
+"smtpd_tls_auth_only = yes". </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_auth_only = no
+</pre>
+</blockquote>
+
+<h3><a name="server_tls_cache">Server-side TLS session cache</a> </h3>
+
+<p> The Postfix SMTP server and the remote SMTP client negotiate a
+session, which takes some computer time and network bandwidth. SSL
+protocol versions other than SSLv2 support resumption of cached
+sessions. Not only is this more CPU and bandwidth efficient, it
+also reduces latency as only one network round-trip is used to
+resume a session while it takes two round-trips to create a session
+from scratch. </p>
+
+<p> Since Postfix uses multiple smtpd(8) service processes, an
+in-memory cache is not sufficient for session re-use. Clients store
+at most one cached session per server and are very unlikely to
+repeatedly connect to the same server process. Thus session caching
+in the Postfix SMTP server generally requires a shared cache (an
+alternative available with Postfix &ge; 2.11 is described below).
+</p>
+
+<p> To share the session information between multiple
+smtpd(8) processes, a session cache database is used. You
+can specify any database type that can store objects of several
+kbytes and that supports the sequence operator. DBM databases are
+not suitable because they can only store small objects. The cache
+is maintained by the tlsmgr(8) process, so there is no problem with
+concurrent access. Session caching is highly recommended, because
+the cost of repeatedly negotiating TLS session keys is high.</p>
+
+<p> Starting with Postfix 2.11, linked with a compatible OpenSSL
+library (at least 0.9.8h, preferably 1.0.0 or later) the Postfix
+SMTP server supports RFC 5077 TLS session resumption without
+server-side state when the remote SMTP client also supports RFC
+5077. The session is encrypted by the server in a <i>session
+ticket</i> returned to client for storage. When a client sends a
+valid session ticket, the server decrypts it and resumes the session,
+provided neither the ticket nor the session have expired. This
+makes it possible to resume cached sessions without allocating space
+for a shared database on the server. Consequently, for Postfix
+&ge; 2.11 the smtpd_tls_session_cache_database parameter should
+generally be left empty. Session caching can be disabled by setting
+the session cache timeout to zero, otherwise the timeout must be
+at least 2 minutes and at most 100 days. </p>
+
+<p> Note, session tickets can only be negotiated if the client
+disables SSLv2 and does not use the legacy SSLv2 compatible HELLO
+message. This is true by default with the Postfix &ge; 2.6 SMTP
+client. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
+</pre>
+</blockquote>
+
+<p> Note: as of version 2.5, Postfix no longer uses root privileges
+when opening this file. The file should now be stored under the
+Postfix-owned data_directory. As a migration aid, an attempt to
+open the file under a non-Postfix directory is redirected to the
+Postfix-owned data_directory, and a warning is logged. </p>
+
+<p> Cached Postfix SMTP server session information expires after
+a certain amount of time. Postfix/TLS does not use the OpenSSL
+default of 300s, but a longer time of 3600sec (=1 hour). RFC 2246
+recommends a maximum of 24 hours. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_session_cache_timeout = 3600s
+</pre>
+</blockquote>
+
+<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set
+&le; 0, session caching is disabled. If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead. </p>
+
+<p> When the Postfix SMTP server does not save TLS sessions to an
+external cache database, client-side session caching is unlikely
+to be useful. To reduce waste of client resources, the Postfix SMTP server can
+be configured to not issue TLS session ids. By default the Postfix
+SMTP server always issues TLS session ids. This works around known
+interoperability issues with some MUAs, and prevents possible
+interoperability issues with other MTAs. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+ smtpd_tls_always_issue_session_ids = no
+</pre>
+</blockquote>
+
+<h3><a name="server_access">Server access control</a> </h3>
+
+<p> Postfix TLS support introduces three additional features for
+Postfix SMTP server access control: </p>
+
+<blockquote>
+
+<dl>
+
+<dt> permit_tls_clientcerts </dt> <dd> <p> Allow the remote SMTP
+client request if the client certificate fingerprint or certificate
+public key fingerprint (Postfix 2.9 and later) is listed in the
+client certificate table (see relay_clientcerts discussion below).
+</p> </dd>
+
+<dt> permit_tls_all_clientcerts </dt> <dd> <p> Allow the remote SMTP
+client request if the client certificate passes trust chain verification.
+Useful with private-label CAs that only issue certificates to trusted
+clients (and not otherwise). </p> </dd>
+
+<dt> check_ccert_access type:table</dt> <dd> <p> Use the remote
+SMTP client certificate fingerprint or public key fingerprint
+(Postfix 2.9 and later) as the lookup key for the specified access(5)
+table. </p> </dd>
+
+</dl>
+
+</blockquote>
+
+<p> The digest algorithm used to compute the client certificate
+fingerprints is specified with the main.cf smtpd_tls_fingerprint_digest
+parameter. The default algorithm is <b>sha256</b> with Postfix &ge;
+3.6 and the <b>compatibility_level</b> set to 3.6 or higher. With
+Postfix &le; 3.5, the default algorithm is <b>md5</b>. The
+best-practice algorithm is now <b>sha256</b>. Recent advances in hash
+function cryptanalysis have led to md5 and sha1 being deprecated in
+favor of sha256. However, as long as there are no known "second
+pre-image" attacks against the older algorithms, their use in this
+context, though not recommended, is still likely safe. </p>
+
+<p> The permit_tls_all_clientcerts feature must be used with caution,
+because it can result in too many access permissions. Use this
+feature only if a special CA issues the client certificates, and
+only if this CA is listed as a trusted CA. If other CAs are trusted,
+any owner of a valid client certificate would be authorized.
+The permit_tls_all_clientcerts feature can be practical for a
+specially created email relay server. </p>
+
+<p> It is however recommended to stay with the permit_tls_clientcerts
+feature and list all certificates via $relay_clientcerts, as
+permit_tls_all_clientcerts does not permit any control when a
+certificate must no longer be used (e.g. an employee leaving). </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+# With Postfix 2.10 and later, the mail relay policy is
+# preferably specified under smtpd_relay_restrictions.
+/etc/postfix/main.cf:
+ smtpd_relay_restrictions =
+ permit_mynetworks
+ permit_tls_clientcerts
+ reject_unauth_destination
+</pre>
+
+<pre>
+# Older configurations combine relay control and spam control under
+# smtpd_recipient_restrictions. To use this example with Postfix &ge;
+# 2.10 specify "smtpd_relay_restrictions=".
+/etc/postfix/main.cf:
+ smtpd_recipient_restrictions =
+ permit_mynetworks
+ permit_tls_clientcerts
+ reject_unauth_destination
+ ...other rules...
+</pre>
+</blockquote>
+
+<p> Example: Postfix lookup tables are in the form of (key, value)
+pairs. Since we only need the key, the value can be chosen freely, e.g.
+the name of the user or host:</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relay_clientcerts = hash:/etc/postfix/relay_clientcerts
+
+/etc/postfix/relay_clientcerts:
+ D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home
+</pre>
+</blockquote>
+
+<p> To extract the public key fingerprint from an X.509 certificate,
+you need to extract the public key from the certificate and compute
+the appropriate digest of its DER (ASN.1) encoding. With OpenSSL
+the "-pubkey" option of the "x509" command extracts the public
+key always in "PEM" format. We pipe the result to another OpenSSL
+command that converts the key to DER and then to the "dgst" command
+to compute the fingerprint. </p>
+
+<p> Example: </p>
+<blockquote>
+<pre>
+$ openssl x509 -in cert.pem -noout -pubkey |
+ openssl pkey -pubin -outform DER |
+ openssl dgst -sha256 -c
+(stdin)= 64:3f:1f:f6:e5:1e:d4:2a:...:8b:fc:09:1a:61:98:b5:bc:7c:60:58
+</pre>
+</blockquote>
+
+<h3><a name="server_cipher">Server-side cipher controls</a> </h3>
+
+<p> The Postfix SMTP server supports 5 distinct cipher grades as
+specified by the smtpd_tls_mandatory_ciphers configuration parameter,
+which determines the minimum cipher grade with mandatory TLS
+encryption. The default minimum cipher grade for mandatory TLS is
+"medium" which is essentially 128-bit encryption or better. The
+smtpd_tls_ciphers parameter (Postfix &ge; 2.6) controls the minimum
+cipher grade used with opportunistic TLS. Here, the default minimum
+cipher grade is "medium" for Postfix releases after the middle of
+2015, "export" for older Postfix releases. With Postfix &lt; 2.6,
+the minimum opportunistic TLS cipher grade is always "export". </p>
+
+<p> By default anonymous ciphers are enabled. They are automatically
+disabled when remote SMTP client certificates are requested. If
+clients are expected to always verify the Postfix SMTP
+server certificate you may want to disable anonymous ciphers
+by setting "smtpd_tls_mandatory_exclude_ciphers = aNULL" or
+"smtpd_tls_exclude_ciphers = aNULL", as appropriate. One can't force
+a remote SMTP client to check the server certificate, so excluding
+anonymous ciphers is generally unnecessary. </p>
+
+<p> With mandatory and opportunistic TLS encryption, the Postfix
+SMTP server by default disables SSLv2 and SSLv3 with Postfix releases
+after the middle of 2015; older releases only disable SSLv2 for
+mandatory TLS. The mandatory TLS protocol list is specified via the
+smtpd_tls_mandatory_protocols configuration parameter. The
+smtpd_tls_protocols parameter (Postfix &ge; 2.6)
+controls the TLS protocols used with opportunistic TLS. </p>
+
+<p> Note that the OpenSSL library only supports protocol exclusion
+(not inclusion). For this reason, Postfix can exclude only protocols
+that are known at the time the Postfix software is written. If new
+protocols are added to the OpenSSL library, they cannot be excluded
+without corresponding changes to the Postfix source code. </p>
+
+<p> For a server that is not a public Internet MX host, Postfix
+supports configurations with no <a href="#server_cert_key">server
+certificates</a> that use <b>only</b> the anonymous ciphers. This is
+enabled by explicitly setting "smtpd_tls_cert_file = none"
+and not specifying an smtpd_tls_dcert_file or smtpd_tls_eccert_file.
+Such configurations may not interoperate with some clients, and require
+that TLSv1.3 be explicitly disabled. Therefore, they are not
+recommended, it is better and simpler to just configure a suitable
+certificate. </p>
+
+<p> Example, MSA that requires TLSv1.2 or higher, with high grade
+ciphers: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_cert_file = /etc/postfix/cert.pem
+ smtpd_tls_key_file = /etc/postfix/key.pem
+ smtpd_tls_mandatory_ciphers = high
+ smtpd_tls_mandatory_exclude_ciphers = aNULL, MD5
+ smtpd_tls_security_level = encrypt
+ # Preferred syntax with Postfix &ge; 3.6:
+ smtpd_tls_mandatory_protocols = &gt;=TLSv1.2
+ # Legacy syntax:
+ smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+</pre>
+</blockquote>
+
+<p> With Postfix &ge; 3.4, specify instead a single file that holds the
+key followed by the corresponding certificate and any associated issuing
+certificates, leaving the "smtpd_tls_cert_file" and "smtpd_tls_key_file"
+and related DSA and ECDSA parameters empty. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_chain_files = /etc/postfix/rsachain.pem
+ smtpd_tls_cert_file =
+ smtpd_tls_key_file =
+ ...
+</pre>
+</blockquote>
+
+<p> If you want to take maximal advantage of ciphers that offer <a
+href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see
+the <a href="FORWARD_SECRECY_README.html#quick-start">Getting
+started</a> section of <a
+href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The
+full document conveniently presents all information about Postfix
+forward secrecy support in one place: what forward secrecy is, how
+to tweak settings, and what you can expect to see when Postfix uses
+ciphers with forward secrecy. </p>
+
+<p> Postfix 2.8 and later, in combination with OpenSSL 0.9.7 and later
+allows TLS servers to preempt the TLS client's cipher-suite preference list.
+This is possible only with SSLv3 and later, as in SSLv2 the client
+chooses the cipher-suite from a list supplied by the server. </p>
+
+<p> By default, the OpenSSL server selects the client's most preferred
+cipher-suite that the server supports. With SSLv3 and later, the server
+may choose its own most preferred cipher-suite that is supported (offered)
+by the client. Setting "tls_preempt_cipherlist = yes" enables server
+cipher-suite preferences. The default OpenSSL behavior applies with
+"tls_preempt_cipherlist = no". </p>
+
+<p> While server cipher-suite selection may in some cases lead to
+a more secure or performant cipher-suite choice, there is some risk
+of interoperability issues. In the past, some SSL clients have
+listed lower priority ciphers that they did not implement correctly.
+If the server chooses a cipher that the client prefers less, it may
+select a cipher whose client implementation is flawed. Most notably
+Windows 2003 Microsoft Exchange servers have flawed implementations
+of DES-CBC3-SHA, which OpenSSL considers stronger than RC4-SHA.
+Enabling server cipher-suite selection may create interoperability
+issues with Windows 2003 Microsoft Exchange clients. </p>
+
+<h3><a name="server_misc"> Miscellaneous server controls</a> </h3>
+
+<p> The smtpd_starttls_timeout parameter limits the time of Postfix
+SMTP server write and read operations during TLS startup and shutdown
+handshake procedures. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_starttls_timeout = 300s
+</pre>
+</blockquote>
+
+<p> With Postfix 2.8 and later, the tls_disable_workarounds parameter
+specifies a list or bit-mask of default-enabled OpenSSL bug
+work-arounds to disable. This may be necessary if one of the
+work-arounds enabled by default in OpenSSL proves to pose a security
+risk, or introduces an unexpected interoperability issue. The list
+of enabled bug work-arounds is OpenSSL-release-specific. See the
+tls_disable_workarounds parameter documentation for the list of
+supported values.</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_disable_workarounds = 0xFFFFFFFF
+ tls_disable_workarounds = CVE-2010-4180
+</pre>
+</blockquote>
+
+<p> With Postfix &ge; 2.11, the tls_ssl_options parameter specifies
+a list or bit-mask of OpenSSL options to enable. Specify one or
+more of the named options below, or a hexadecimal bitmask of options
+found in the ssl.h file corresponding to the run-time OpenSSL
+library. While it may be reasonable to turn off all bug workarounds
+(see above), it is not a good idea to attempt to turn on all features.
+See the tls_ssl_options parameter documentation for the list of
+supported values. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_ssl_options = no_ticket, no_compression
+</pre>
+</blockquote>
+
+<p> You should only enable features via the hexadecimal mask when
+the need to control the feature is critical (to deal with a new
+vulnerability or a serious interoperability problem). Postfix DOES
+NOT promise backwards compatible behavior with respect to the mask
+bits. A feature enabled via the mask in one release may be enabled
+by other means in a later release, and the mask bit will then be
+ignored. Therefore, use of the hexadecimal mask is only a temporary
+measure until a new Postfix or OpenSSL release provides a better
+solution. </p>
+
+<h2> <a name="client_tls">SMTP Client specific settings</a> </h2>
+
+<p> Topics covered in this section: </p>
+
+<ul>
+
+<li><a href="#client_tls_levels"> Configuring TLS in the SMTP/LMTP client </a>
+
+<li><a href="#client_logging"> Client-side TLS activity logging </a>
+
+<li><a href="#client_cert_key">Client-side certificate and private
+key configuration </a>
+
+<li><a href="#client_tls_reuse">Client-side TLS connection reuse</a>
+
+<li><a href="#client_tls_cache">Client-side TLS session cache</a>
+
+<li><a href="#client_tls_limits"> Client TLS limitations </a>
+
+<li><a href="#client_tls_policy"> Per-destination TLS policy </a>
+
+<li><a href="#client_tls_discover"> Discovering servers that support TLS </a>
+
+<li><a href="#client_vrfy_server">Server certificate verification depth</a>
+
+<li> <a href="#client_cipher">Client-side cipher controls </a>
+
+<li> <a href="#client_smtps">Client-side SMTPS support </a>
+
+<li> <a href="#client_misc"> Miscellaneous client controls </a>
+
+</ul>
+
+<h3><a name="client_tls_levels"> Configuring TLS in the SMTP/LMTP client </a>
+</h3>
+
+<p> Similar to the Postfix SMTP server, the Postfix SMTP/LMTP client
+implements multiple TLS security levels. These levels are described
+in more detail in the sections that follow.</p>
+
+<dl>
+<dt><b>none</b></dt>
+<dd><a href="#client_tls_none">No TLS.</a></dd>
+<dt><b>may</b></dt>
+<dd><a href="#client_tls_may">Opportunistic TLS.</a></dd>
+<dt><b>encrypt</b></dt>
+<dd><a href="#client_tls_encrypt">Mandatory TLS encryption.</a>
+<dt><b>dane</b></dt>
+<dd><a href="#client_tls_dane">Opportunistic DANE TLS.</a>
+<dt><b>dane-only</b></dt>
+<dd><a href="#client_tls_dane">Mandatory DANE TLS.</a>
+<dt><b>fingerprint</b></dt>
+<dd><a href="#client_tls_fprint">Certificate fingerprint verification.</a>
+<dt><b>verify</b></dt>
+<dd><a href="#client_tls_verify">Mandatory server certificate verification.</a>
+<dt><b>secure</b></dt>
+<dd><a href="#client_tls_secure">Secure-channel TLS.</a>
+</dl>
+
+<h4><a name="client_lmtp_tls"> TLS support in the LMTP delivery agent </a> </h4>
+
+<p> The smtp(8) and lmtp(8) delivery agents are implemented by a
+single dual-purpose program. Specifically, all the TLS features
+described below apply
+equally to SMTP and LMTP, after replacing the "smtp_" prefix of the each
+parameter name with "lmtp_".
+
+<p> The Postfix LMTP delivery agent can communicate with LMTP servers
+listening
+on UNIX-domain sockets. When server certificate verification is enabled
+and the server is listening on a UNIX-domain socket, the $myhostname
+parameter is used to set the TLS verification <i>nexthop</i> and
+<i>hostname</i>. </p>
+
+<p> NOTE: Opportunistic encryption of LMTP traffic over UNIX-domain
+sockets or loopback TCP connections is futile. TLS is only useful
+in this context when
+it is mandatory, typically to allow at least one of the server or the
+client to authenticate the other. The "null" cipher grade may be
+appropriate in this context, when available on both client and server.
+The "null" ciphers provide authentication without encryption. </p>
+
+<h4><a name="client_tls_none"> No TLS encryption </a> </h4>
+
+<p> At the "none" TLS security level, TLS encryption is
+disabled. This is the default security level, and
+can be configured explicitly by setting "smtp_tls_security_level = none".
+For LMTP, use the corresponding "lmtp_" parameter. </p>
+
+<p> Per-destination settings may override this default setting, in which case
+TLS is used selectively, only with destinations explicitly configured
+for TLS. </p>
+
+<p> You can disable TLS for a subset of destinations, while leaving
+it enabled for the rest. With the Postfix TLS <a
+href="#client_tls_policy">policy table</a>, specify the "none"
+security level.
+
+<h4><a name="client_tls_may"> Opportunistic TLS </a> </h4>
+
+<p> At the "may" TLS security level, TLS encryption is <i>opportunistic</i>.
+The SMTP transaction is encrypted if the STARTTLS ESMTP feature
+is supported by the server. Otherwise, messages are sent in the clear.
+Opportunistic TLS can be configured by setting "smtp_tls_security_level = may".
+For LMTP, use the corresponding "lmtp_" parameter. </p>
+
+<p> The "smtp_tls_ciphers" and "smtp_tls_protocols" configuration
+parameters (Postfix &ge; 2.6) provide control over the cipher grade
+and protocols used with opportunistic TLS. With earlier Postfix
+releases, opportunistic TLS always uses the cipher grade "export"
+and enables all protocols. </p>
+
+<p> With opportunistic TLS, mail delivery continues even if the
+server certificate is untrusted or bears the wrong name.
+When the TLS handshake fails for an opportunistic
+TLS session, rather than give up on mail delivery, the Postfix SMTP
+client retries the transaction
+with TLS disabled. Trying an unencrypted connection makes
+it possible to deliver mail to sites with non-interoperable server
+TLS implementations. </p>
+
+<p> Opportunistic encryption is never used for LMTP over UNIX-domain
+sockets. The communications channel is already confidential without
+TLS, so the only potential benefit of TLS is authentication. Do not
+configure opportunistic TLS for LMTP deliveries over UNIX-domain sockets.
+Only configure TLS for LMTP over UNIX-domain sockets at the
+<a href="#client_tls_encrypt">encrypt</a> security level or higher.
+Attempts to configure opportunistic encryption of LMTP sessions will
+be ignored with a warning written to the mail logs. </p>
+
+<p> You can enable opportunistic TLS just for selected destinations. With
+the Postfix TLS <a href="#client_tls_policy">policy table</a>,
+specify the "may" security level. </p>
+
+<p> This is the most common security level for TLS protected SMTP
+sessions, stronger security is not generally available and, if needed,
+is typically only configured on a per-destination basis. See the section
+on TLS <a href="#client_tls_limits">limitations</a> above. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_security_level = may
+</pre>
+</blockquote>
+
+<h4><a name="client_tls_encrypt"> Mandatory TLS encryption </a> </h4>
+
+<p> At the "encrypt" TLS security level, messages are sent only
+over TLS encrypted sessions. The SMTP transaction is aborted unless
+the STARTTLS ESMTP feature is supported by the remote SMTP server.
+If no suitable
+servers are found, the message will be deferred.
+Mandatory TLS encryption can be configured by setting
+"smtp_tls_security_level = encrypt". Even though TLS
+encryption is always used, mail delivery continues even if the server
+certificate is untrusted or bears the wrong name.
+For LMTP, use the corresponding "lmtp_" parameter. </p>
+
+<p> At this security level and higher, the smtp_tls_mandatory_protocols
+and smtp_tls_mandatory_ciphers configuration parameters determine
+the list of sufficiently secure SSL protocol versions and the minimum
+cipher strength. If the protocol or cipher requirements are not
+met, the mail transaction is aborted. The documentation for these
+parameters includes useful interoperability and security guidelines.
+</p>
+
+<p> Despite the potential for eliminating passive eavesdropping attacks,
+mandatory TLS encryption is not viable as a default security level for
+mail delivery to the public Internet. Some MX hosts do not support TLS at
+all, and some of those that do have broken implementations. On a host
+that delivers mail to the Internet, you should not configure mandatory
+TLS encryption as the default security level. </p>
+
+<p> You can enable mandatory TLS encryption just for specific destinations.
+With the Postfix TLS <a href="#client_tls_policy">policy
+table</a>, specify the "encrypt" security level.
+</p>
+
+<p> Examples: </p>
+
+<p> In the example below, traffic to <i>example.com</i> and its sub-domains
+via the corresponding MX hosts always uses TLS. The SSLv2 protocol
+will be disabled (the default setting of smtp_tls_mandatory_protocols
+excludes SSLv2+3). Only high- or medium-strength (i.e. 128 bit or
+better) ciphers will be used by default for all "encrypt" security
+level sessions. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+
+/etc/postfix/tls_policy:
+ example.com encrypt
+ .example.com encrypt
+</pre>
+</blockquote>
+
+<p> In the next example, secure message submission is configured
+via the MSA "<tt>[example.net]:587</tt>". TLS sessions are encrypted
+without authentication, because this MSA does not possess an acceptable
+certificate. This MSA is known to be capable of "TLSv1" and "high" grade
+ciphers, so these are selected via the <a href="#client_tls_policy">policy
+table</a>. </p>
+
+<p><b>Note:</b> the policy table lookup key is the verbatim next-hop
+specification from the recipient domain, transport(5) table or relayhost
+parameter, with any enclosing square brackets and optional port. Take
+care to be consistent: the suffixes ":smtp" or ":25" or no port suffix
+result in different policy table lookup keys, even though they are
+functionally equivalent nexthop specifications. Use at most one of these
+forms for all destinations. Below, the policy table has multiple keys,
+just in case the transport table entries are not specified consistently. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+
+/etc/services:
+ submission 587/tcp msa # mail message submission
+
+/etc/postfix/tls_policy:
+ # Postfix &ge; 3.6 "protocols" syntax
+ [example.net]:587 encrypt protocols=&gt;=TLSv1.2 ciphers=high
+ # Legacy "protocols" syntax
+ [example.net]:msa encrypt protocols=!SSLv2:!SSLv3 ciphers=high
+</pre>
+</blockquote>
+
+<h4><a name="client_tls_dane">DANE TLS authentication.</a> </h4>
+
+<p> The Postfix SMTP client supports two TLS security levels based
+on DANE TLSA (RFC 6698, RFC 7671, RFC 7672) records. The opportunistic
+"dane" level and the mandatory "dane-only" level. </p>
+
+<p> The "dane" level is a stronger form of <a
+href="#client_tls_may">opportunistic</a> TLS that is resistant to
+man in the middle and downgrade attacks when the destination domain
+uses DNSSEC to publish DANE TLSA records for its MX hosts. If a
+remote SMTP server has "usable" (see section 3 of RFC 7672) DANE
+TLSA records, the server connection will be authenticated. When
+DANE authentication fails, there is no fallback to unauthenticated
+or plaintext delivery. </p>
+
+<p> If TLSA records are published for a given remote SMTP server
+(implying TLS support), but are all "unusable" due to unsupported
+parameters or malformed data, the Postfix SMTP client will use <a
+href="#client_tls_encrypt">mandatory</a> unauthenticated TLS.
+Otherwise, when no TLSA records are published, the Postfix SMTP
+client behavior is the same as with <a href="#client_tls_may">may</a>. </p>
+
+<p> TLSA records must be published in DNSSEC validated DNS zones.
+Any TLSA records in DNS zones not protected via DNSSEC are ignored.
+The Postfix SMTP client will not look for TLSA records associated
+with MX hosts whose "A" or "AAAA" records lie in an "insecure" DNS
+zone. Such lookups have been observed to cause interoperability
+issues with poorly implemented DNS servers, and are in any case not
+expected to ever yield "secure" results, since that would require
+a very unlikely DLV DNS trust anchor configured between the host
+record and the associated "_25._tcp" child TLSA record. </p>
+
+<p> The "dane-only" level is a form of <a
+href="#client_tls_secure">secure-channel</a> TLS based on the DANE PKI.
+If "usable" TLSA records are present these are used to authenticate the
+remote SMTP server. Otherwise, or when server certificate verification
+fails, delivery via the server in question tempfails. </p>
+
+<p> At both security levels, the TLS policy for the destination is
+obtained via TLSA records validated with DNSSEC. For TLSA policy
+to be in effect, the destination domain's containing DNS zone must
+be signed and the Postfix SMTP client's operating system must be
+configured to send its DNS queries to a recursive DNS nameserver
+that is able to validate the signed records. Each MX host's DNS
+zone needs to also be signed, and needs to publish DANE TLSA (see
+section 3 of RFC 7672) records that specify how that MX host's TLS
+certificate is to be verified. </p>
+
+<p> TLSA records do not preempt the normal SMTP MX host
+selection algorithm, if some MX hosts support TLSA and others do
+not, TLS security will vary from delivery to delivery. It is up
+to the domain owner to configure their MX hosts and their DNS
+sensibly. To configure the Postfix SMTP client for DNSSEC lookups
+see the documentation for the smtp_dns_support_level main.cf
+parameter. The tls_dane_digests parameter controls the list of
+supported digests. </p>
+
+<p> As explained in section 3 of RFC 7672, certificate usages "0"
+and "1", which are intended to "constrain" existing Web-PKI trust,
+are not supported with MTA-to-MTA SMTP. Rather, TLSA records with
+usages "0" and "1" are treated as "unusable". </p>
+
+<p> The Postfix SMTP client supports only certificate usages "2"
+and "3". Experimental support for silently mapping certificate
+usage "1" to "3" has been withdrawn starting with Postfix 3.2. </p>
+
+<p> When usable TLSA records are obtained for the remote SMTP server
+the Postfix SMTP client sends the SNI TLS extension in its SSL
+client hello message. This may help the remote SMTP server live
+up to its promise to provide a certificate that matches its TLSA
+records. </p>
+
+<p> For purposes of protocol and cipher selection, the "dane"
+security level is treated like a "mandatory" TLS security level,
+and weak ciphers and protocols are disabled. Since DANE authenticates
+server certificates the "aNULL" cipher-suites are transparently
+excluded at this level, no need to configure this manually. RFC
+7672 (DANE) TLS authentication is available with Postfix 2.11 and
+later. </p>
+
+<p> When a DANE TLSA record specifies a trust-anchor (TA) certificate
+(that is an issuing CA), the strategy used to verify the peername
+of the server certificate is unconditionally "nexthop, hostname".
+Both the nexthop domain and the hostname obtained from the
+DNSSEC-validated MX lookup are safe from forgery and the server
+certificate must contain at least one of these names. </p>
+
+<p> When a DANE TLSA record specifies an end-entity (EE) certificate,
+(that is the actual server certificate), as with the fingerprint
+security level below, no name checks or certificate expiration checks
+are applied. The server certificate (or its public key) either matches
+the DANE record or not. Server administrators should publish such
+EE records in preference to all other types. </p>
+
+<p> The pre-requisites for DANE support in the Postfix SMTP client are: </p>
+<ul>
+<li> A <i>compile-time</i> OpenSSL library that supports the TLS SNI
+extension and "SHA-2" message digests.
+<li> A <i>compile-time</i> DNS resolver library that supports DNSSEC.
+Postfix binaries built on an older system will not support DNSSEC even
+if deployed on a system with an updated resolver library.
+<li> The "smtp_dns_support_level" must be set to "dnssec".
+<li> The "smtp_host_lookup" parameter must include "dns".
+<li> A DNSSEC-validating recursive resolver (see note below).
+</ul>
+<p> The above client pre-requisites do not apply to the Postfix SMTP server.
+It will support DANE provided it supports TLSv1 and its TLSA records are
+published in a DNSSEC signed zone. To receive DANE secured mail for multiple
+domains, use the same hostname to add the server to each domain's MX
+records. The Postfix SMTP server supports SNI (Postfix 3.4 and later),
+configured with tls_server_sni_maps. </p>
+
+<p> Note: The Postfix SMTP client's internal stub DNS resolver is
+DNSSEC-aware, but it does not itself validate DNSSEC records, rather
+it delegates DNSSEC validation to the operating system's configured
+recursive DNS nameserver. The Postfix DNS client relies on a secure
+channel to the resolver's cache for DNSSEC integrity, but does not
+support TSIG to protect the transmission channel between itself and
+the nameserver. Therefore, it is strongly recommended (DANE security
+guarantee void otherwise) that each MTA run a local DNSSEC-validating
+recursive resolver ("unbound" from nlnetlabs.nl is a reasonable
+choice) listening on the loopback interface, and that the system
+be configured to use <i>only</i> this local nameserver. The local
+nameserver may forward queries to an upstream recursive resolver
+on another host if desired. </p>
+
+<p> Note: When the operating system's recursive nameserver is not
+local, enabling EDNS0 expanded DNS packet sizes and turning on the
+DNSSEC "DO" bit in the DNS request and/or the new DNSSEC-specific
+records returned in the nameserver's replies may cause problems
+with older or buggy firewall and DNS server implementations.
+Therefore, Postfix does not enable DNSSEC by default. Since MX
+lookups happen before the security level is determined, DANE support
+is disabled for all destinations unless you set "smtp_dns_support_level
+= dnssec". To enable DNSSEC lookups selectively, define a new
+dedicated transport with a "-o smtp_dns_support_level=dnssec"
+override in master.cf and route selected domains to that transport.
+If DNSSEC proves to be sufficiently reliable for these domains, you
+can enable it for all destinations by changing the global
+smtp_dns_support_level in main.cf. </p>
+
+<p><b>Example</b>: "dane" security for selected destinations, with
+opportunistic TLS by default. This is the recommended configuration
+for early adopters. <p>
+<ul>
+<li> <p> The "example.com" destination uses DANE, but if TLSA records
+are not present or are unusable, mail is deferred. </p>
+
+<li> <p> The "example.org" destination uses DANE if possible, but if no TLSA
+records are found opportunistic TLS is used. </p>
+</ul>
+
+<blockquote>
+<pre>
+main.cf:
+ indexed = ${default_database_type}:${config_directory}/
+ #
+ # default: Opportunistic TLS with no DNSSEC lookups.
+ #
+ smtp_tls_security_level = may
+ smtp_dns_support_level = enabled
+ #
+ # Per-destination TLS policy
+ #
+ smtp_tls_policy_maps = ${indexed}tls_policy
+ #
+ # default_transport = smtp, but some destinations are special:
+ #
+ transport_maps = ${indexed}transport
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+transport:
+ example.com dane
+ example.org dane
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+tls_policy:
+ example.com dane-only
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+master.cf:
+ dane unix - - n - - smtp
+ -o smtp_dns_support_level=dnssec
+ -o smtp_tls_security_level=dane
+</pre>
+</blockquote>
+
+<h4><a name="client_tls_fprint"> Certificate fingerprint verification </a> </h4>
+
+<p> At the <i>fingerprint</i> security level, no trusted Certification
+Authorities are used or required. The certificate trust chain,
+expiration date, etc., are not checked. Instead, the
+smtp_tls_fingerprint_cert_match parameter or the "match" attribute
+in the <a href="#client_tls_policy">policy</a> table lists the
+remote SMTP server certificate fingerprint or public key fingerprint.
+Certificate fingerprint verification is available with Postfix 2.5
+and later, public-key fingerprint support is available with Postfix
+2.9 and later. </p>
+
+<p> If certificate fingerprints are exchanged securely, this is the
+strongest, and least scalable security level. The administrator needs
+to securely collect the fingerprints of the X.509 certificates of each
+peer server, store them into a local file, and update this local file
+whenever the peer server's public certificate changes. If public key
+fingerprints are used in place of fingerprints of the entire certificate,
+the fingerprints remain valid even after the certificate is renewed,
+<b>provided</b> that the same public/private keys are used to obtain
+the new certificate. </p>
+
+<p> Fingerprint verification may be feasible for an SMTP "VPN" connecting
+a small number of branch offices over the Internet, or for secure
+connections to a central mail hub. It works poorly if the remote SMTP
+server is managed by a third party, and its public certificate changes
+periodically without prior coordination with the verifying site. </p>
+
+<p> The digest algorithm used to calculate the fingerprint is
+selected by the <b>smtp_tls_fingerprint_digest</b> parameter. In the <a
+href="#client_tls_policy">policy</a> table multiple fingerprints can be
+combined with a "|" delimiter in a single match attribute, or multiple
+match attributes can be employed. The ":" character is not used as a
+delimiter as it occurs between each pair of fingerprint (hexadecimal)
+digits. </p>
+
+<p> The default algorithm is <b>sha256</b> with Postfix &ge; 3.6
+and the <b>compatibility_level</b> set to 3.6 or higher; with Postfix
+&le; 3.5, the default algorithm is <b>md5</b>. The
+best-practice algorithm is now <b>sha256</b>. Recent advances in hash
+function cryptanalysis have led to md5 and sha1 being deprecated in
+favor of sha256. However, as long as there are no known "second
+pre-image" attacks against the older algorithms, their use in this
+context, though not recommended, is still likely safe. </p>
+
+<p> Example: fingerprint TLS security with an internal mailhub.
+Two matching fingerprints are listed. The relayhost may be multiple
+physical hosts behind a load-balancer, each with its own private/public
+key and self-signed certificate. Alternatively, a single relayhost may
+be in the process of switching from one set of private/public keys to
+another, and both keys are trusted just prior to the transition. </p>
+
+<blockquote>
+<pre>
+ relayhost = [mailhub.example.com]
+ smtp_tls_security_level = fingerprint
+ smtp_tls_fingerprint_digest = sha256
+ smtp_tls_fingerprint_cert_match =
+ 51:e9:af:2e:1e:40:1f:de:64:...:30:35:2d:09:16:31:5a:eb:82:76
+ b6:b4:72:34:e2:59:cd:fb:c2:...:63:0d:4d:cc:2c:7d:84:de:e6:2f
+</pre>
+</blockquote>
+
+<p> Example: Certificate fingerprint verification with selected destinations.
+As in the example above, we show two matching fingerprints: </p>
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+ smtp_tls_fingerprint_digest = sha256
+</pre>
+</blockquote>
+<blockquote>
+<pre>
+/etc/postfix/tls_policy:
+ example.com fingerprint
+ match=51:e9:af:2e:1e:40:1f:de:...:35:2d:09:16:31:5a:eb:82:76
+ match=b6:b4:72:34:e2:59:cd:fb:...:0d:4d:cc:2c:7d:84:de:e6:2f
+</pre>
+</blockquote>
+
+<p> To extract the public key fingerprint from an X.509 certificate,
+you need to extract the public key from the certificate and compute
+the appropriate digest of its DER (ASN.1) encoding. With OpenSSL
+the "-pubkey" option of the "x509" command extracts the public
+key always in "PEM" format. We pipe the result to another OpenSSL
+command that converts the key to DER and then to the "dgst" command
+to compute the fingerprint. </p>
+
+<p> Example: </p>
+<blockquote>
+<pre>
+$ openssl x509 -in cert.pem -noout -pubkey |
+ openssl pkey -pubin -outform DER |
+ openssl dgst -sha256 -c
+(stdin)= 64:3f:1f:f6:e5:1e:d4:2a:56:...:09:1a:61:98:b5:bc:7c:60:58
+</pre>
+</blockquote>
+
+<h4><a name="client_tls_verify"> Mandatory server certificate verification </a> </h4>
+
+<p> At the <i>verify</i> TLS security level, messages are sent only over
+TLS encrypted sessions if the remote SMTP server certificate is
+valid (not
+expired or revoked, and signed by a trusted Certification Authority)
+and where the server certificate name matches a known pattern.
+Mandatory
+server certificate verification can be configured by setting
+"smtp_tls_security_level = verify". The
+smtp_tls_verify_cert_match parameter can override the default
+"hostname" certificate name matching strategy. Fine-tuning the
+matching strategy is generally only appropriate for <a
+href="#client_tls_secure">secure-channel</a> destinations.
+For LMTP use the corresponding "lmtp_" parameters. </p>
+
+<p> If the server certificate chain is trusted (see smtp_tls_CAfile
+and smtp_tls_CApath), any DNS names in the SubjectAlternativeName
+certificate extension are used to verify the remote SMTP server name.
+If no
+DNS names are specified, the certificate CommonName is checked.
+If you want mandatory encryption without server certificate
+verification, see <a href="#client_tls_encrypt">above</a>. </p>
+
+<p> With Postfix &ge; 2.11 the "smtp_tls_trust_anchor_file" parameter
+or more typically the corresponding per-destination "tafile" attribute
+optionally modifies trust chain verification. If the parameter is
+not empty the root CAs in CAfile and CApath are no longer trusted.
+Rather, the Postfix SMTP client will only trust certificate-chains
+signed by one of the trust-anchors contained in the chosen files.
+The specified trust-anchor certificates and public keys are not
+subject to expiration, and need not be (self-signed) root CAs. They
+may, if desired, be intermediate certificates. Therefore, these
+certificates also may be found "in the middle" of the trust chain
+presented by the remote SMTP server, and any untrusted issuing
+parent certificates will be ignored. </p>
+
+<p> Despite the potential for eliminating "man-in-the-middle" and other
+attacks, mandatory certificate trust chain and subject name verification
+is not viable as a default Internet mail delivery policy. Some MX hosts
+do not support TLS at all, and a significant portion of TLS-enabled
+MTAs use self-signed certificates, or certificates that are signed by
+a private Certification Authority. On a machine that delivers mail to
+the Internet, you should not configure mandatory server certificate
+verification as a default policy. </p>
+
+<p> Mandatory server certificate verification as a default security
+level may be appropriate if you know that you will only connect to
+servers that support RFC 2487 <i>and</i> that present verifiable
+server certificates. An example would be a client that sends all
+email to a central mailhub that offers the necessary STARTTLS
+support. In such cases, you can often use a <a
+href="#client_tls_secure">secure-channel</a> configuration instead.
+</p>
+
+<p> You can enable mandatory server certificate verification just
+for specific destinations. With the Postfix TLS <a
+href="#client_tls_policy">policy table</a>, specify the "verify"
+security level. </p>
+
+<p> Example: </p>
+
+<p> In this example, the Postfix SMTP client encrypts all traffic to the
+<i>example.com</i> domain. The peer hostname is verified, but
+verification is vulnerable to DNS response forgery. Mail transmission
+to <i>example.com</i> recipients uses "high" grade ciphers. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ indexed = ${default_database_type}:${config_directory}/
+ smtp_tls_CAfile = ${config_directory}/CAfile.pem
+ smtp_tls_policy_maps = ${indexed}tls_policy
+
+/etc/postfix/tls_policy:
+ example.com verify ciphers=high
+</pre>
+</blockquote>
+
+<h4><a name="client_tls_secure"> Secure server certificate verification </a> </h4>
+
+<p> At the <i>secure</i> TLS security level, messages are sent only over
+<i>secure-channel</i> TLS sessions where DNS forgery resistant server
+certificate verification succeeds. If no suitable servers are found, the
+message will be deferred. Postfix secure-channels
+can be configured by setting "smtp_tls_security_level = secure".
+The smtp_tls_secure_cert_match parameter can override the default
+"nexthop, dot-nexthop" certificate match strategy.
+For LMTP, use the corresponding "lmtp_" parameters. </p>
+
+<p> If the server certificate chain is trusted (see smtp_tls_CAfile and
+smtp_tls_CApath), any DNS names in the SubjectAlternativeName certificate
+extension are used to verify the remote SMTP server name. If no DNS names
+are
+specified, the CommonName is checked. If you want mandatory encryption
+without server certificate verification, see <a
+href="#client_tls_encrypt">above</a>. </p>
+
+<p> With Postfix &ge; 2.11 the "smtp_tls_trust_anchor_file" parameter
+or more typically the corresponding per-destination "tafile" attribute
+optionally modifies trust chain verification. If the parameter is
+not empty the root CAs in CAfile and CApath are no longer trusted.
+Rather, the Postfix SMTP client will only trust certificate-chains
+signed by one of the trust-anchors contained in the chosen files.
+The specified trust-anchor certificates and public keys are not
+subject to expiration, and need not be (self-signed) root CAs. They
+may, if desired, be intermediate certificates. Therefore, these
+certificates also may be found "in the middle" of the trust chain
+presented by the remote SMTP server, and any untrusted issuing
+parent certificates will be ignored. </p>
+
+<p> Despite the potential for eliminating "man-in-the-middle" and other
+attacks, mandatory secure server certificate verification is not
+viable as a default Internet mail delivery policy. Some MX hosts
+do not support TLS at all, and a significant portion of TLS-enabled
+MTAs use self-signed certificates, or certificates that are signed
+by a private Certification Authority. On a machine that delivers mail
+to the Internet, you should not configure secure TLS verification
+as a default policy. </p>
+
+<p> Mandatory secure server certificate verification as a default
+security level may be appropriate if you know that you will only
+connect to servers that support RFC 2487 <i>and</i> that present
+verifiable server certificates. An example would be a client that
+sends all email to a central mailhub that offers the necessary
+STARTTLS support. </p>
+
+<p> You can enable secure TLS verification just for specific destinations.
+With the Postfix TLS <a href="#client_tls_policy">policy table</a>,
+specify the "secure" security level. </p>
+
+<p> Examples: </p>
+
+<ul>
+
+<li> <p> Secure-channel TLS without transport(5) table overrides: </p>
+
+<p> The Postfix SMTP client will encrypt all traffic and verify the
+destination name
+immune from forged DNS responses. MX lookups are still used to find
+the hostnames of the SMTP servers for <i>example.com</i>, but these
+hostnames are not used when
+checking the names in the server certificate(s). Rather, the requirement
+is that the MX hosts for <i>example.com</i> have trusted certificates
+with a subject name of <i>example.com</i> or a sub-domain, see the
+documentation for the smtp_tls_secure_cert_match parameter. </p>
+
+<p> The related domains <i>example.co.uk</i> and <i>example.co.jp</i> are
+hosted on the same MX hosts as the primary <i>example.com</i> domain, and
+traffic to these is secured by verifying the primary <i>example.com</i>
+domain in the server certificates. This frees the server administrator
+from needing the CA to sign certificates that list all the secondary
+domains. The downside is that clients that want secure channels to the
+secondary domains need explicit TLS <a href="#client_tls_policy">policy
+table</a> entries. </p>
+
+<p> Note, there are two ways to handle related domains. The first is to
+use the default routing for each domain, but add policy table entries
+to override the expected certificate subject name. The second is to
+override the next-hop in the transport table, and use a single policy
+table entry for the common nexthop. We choose the first approach,
+because it works better when domain ownership changes. With the second
+approach we securely deliver mail to the wrong destination, with the
+first approach, authentication fails and mail stays in the local queue,
+the first approach is more appropriate in most cases. <p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_CAfile = /etc/postfix/CAfile.pem
+ smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+
+/etc/postfix/transport:
+
+/etc/postfix/tls_policy:
+ example.com secure
+ example.co.uk secure match=example.com:.example.com
+ example.co.jp secure match=example.com:.example.com
+</pre>
+</blockquote>
+
+<li> <p> Secure-channel TLS with transport(5) table overrides: <p>
+
+<p> In this case traffic to <i>example.com</i> and its related domains
+is sent to a single logical gateway (to avoid a single point of failure,
+its name may resolve to one or more load-balancer addresses, or to the
+combined addresses of multiple physical hosts). All the physical hosts
+reachable via the gateway's IP addresses have the logical gateway name
+listed in their certificates. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_CAfile = /etc/postfix/CAfile.pem
+ transport_maps = hash:/etc/postfix/transport
+ smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+
+/etc/postfix/transport:
+ example.com smtp:[tls.example.com]
+ example.co.uk smtp:[tls.example.com]
+ example.co.jp smtp:[tls.example.com]
+
+/etc/postfix/tls_policy:
+ [tls.example.com] secure match=tls.example.com
+</pre>
+</blockquote>
+
+</ul>
+
+<h3><a name="client_logging"> Client-side TLS activity logging </a> </h3>
+
+<p> To get additional information about Postfix SMTP client TLS
+activity you can increase the loglevel from 0..4. Each logging
+level also includes the information that is logged at a lower
+logging level. </p>
+
+<blockquote>
+
+<table border="1">
+
+<tr> <th> Level </th> <th> Postfix 2.9 and later</th> <th> Earlier
+releases. </th> </tr>
+
+<tr> <td valign="top"> 0 </td> <td valign="top" colspan="2"> Disable
+logging of TLS activity. </td> </tr>
+
+<tr> <td valign="top"> 1 </td> <td valign="top"> Log only a summary
+message on TLS handshake completion &mdash; no logging of remote SMTP
+server certificate trust-chain verification errors if server certificate
+verification is not required. </td> <td valign="top"> Log the summary
+message and unconditionally log trust-chain verification errors.
+</td> </tr>
+
+<tr> <td valign="top"> 2 </td> <td valign="top" colspan="2"> Also
+log levels during TLS negotiation. </td> </tr>
+
+<tr> <td valign="top"> 3 </td> <td valign="top" colspan="2"> Also
+log hexadecimal and ASCII dump of TLS negotiation process. </td>
+</tr>
+
+<tr> <td valign="top"> 4 </td> <td valign="top" colspan="2"> Also
+log hexadecimal and ASCII dump of complete transmission after
+STARTTLS. </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_loglevel = 0
+</pre>
+</blockquote>
+
+<h3><a name="client_cert_key">Client-side certificate and private
+key configuration </a> </h3>
+
+<p> Do not configure Postfix SMTP client certificates unless you <b>must</b>
+present
+client TLS certificates to one or more servers. Client certificates are
+not usually needed, and can cause problems in configurations that work
+well without them. The recommended setting is to let the defaults stand: </p>
+
+<blockquote>
+<pre>
+ smtp_tls_cert_file =
+ smtp_tls_dcert_file =
+ smtp_tls_key_file =
+ smtp_tls_dkey_file =
+ # Postfix &ge; 2.6
+ smtp_tls_eccert_file =
+ smtp_tls_eckey_file =
+ # Postfix &ge; 3.4
+ smtp_tls_chain_files =
+</pre>
+</blockquote>
+
+<p> The best way to use the default settings is to comment out the above
+parameters in main.cf if present. </p>
+
+<p> During TLS startup negotiation the Postfix SMTP client may present a
+certificate to the remote SMTP server. Browsers typically let the user
+select among the certificates that match the CA names indicated by the
+remote SMTP server. The Postfix SMTP client does not yet have a mechanism
+to select from multiple candidate certificates on the fly, and supports a
+single set of certificates (at most one per public key algorithm). </p>
+
+<p> RSA, DSA and ECDSA (Postfix &ge; 2.6) certificates are supported.
+You can configure all three at the same time, in which case the
+cipher used determines which certificate is presented. </p>
+
+<p> It is possible for the Postfix SMTP client to use the same
+key/certificate pair as the Postfix SMTP server. If a certificate
+is to be presented, it must be in "PEM" format. The private key
+must not be encrypted, meaning: it must be accessible without
+a password. Both parts (certificate and private key) may be in the
+same file. </p>
+
+<p> With OpenSSL 1.1.1 and Postfix &ge; 3.4 it is also possible to
+configure Ed25519 and Ed448 certificates. Rather than add two more
+pairs of key and certificate parameters, Postfix 3.4 introduces a new
+"smtp_tls_chain_files" parameter which specifies all the configured
+certificates at once, and handles files that hold both the key and the
+associated certificates in one pass, thereby avoiding potential race
+conditions during key rollover. </p>
+
+<p> To enable remote SMTP servers to verify the Postfix SMTP client
+certificate, the issuing CA certificates must be made available to the
+server. You should include the required certificates in the client
+certificate file, the client certificate first, then the issuing
+CA(s) (bottom-up order). </p>
+
+<p> Example: the certificate for "client.example.com" was issued by
+"intermediate CA" which itself has a certificate issued by "root CA".
+As the "root" super-user create the client.pem file with: </p>
+
+<blockquote>
+<pre>
+# <b>umask 077</b>
+# <b>cat client_key.pem client_cert.pem intermediate_CA.pem &gt; chain.pem </b>
+</pre>
+</blockquote>
+
+<p> A Postfix SMTP client certificate supplied here must be usable
+as an SSL client certificate and hence pass the "openssl verify -purpose
+sslclient ..." test. </p>
+
+<p> A server that trusts the root CA has a local copy of the root
+CA certificate, so it is not necessary to include the root CA
+certificate here. Leaving it out of the "chain.pem" file reduces
+the overhead of the TLS exchange. </p>
+
+<p> If you want the Postfix SMTP client to accept remote SMTP server
+certificates issued by these CAs, append the root certificate to
+$smtp_tls_CAfile or install it in the $smtp_tls_CApath directory. </p>
+
+<p> Example: Postfix &ge; 3.4 all-in-one chain file(s). One or more
+chain files that start with a key that is immediately followed by the
+corresponding certificate and any additional issuer certificates. A
+single file can hold multiple <i>(key, cert, [chain])</i> sequences, one
+per algorithm. It is typically simpler to keep the chain for each
+algorithm in its own file. Most users are likely to deploy at most a
+single RSA chain, but with OpenSSL 1.1.1, it is possible to deploy up
+five chains, one each for RSA, ECDSA, ED25519, ED448, and even the
+obsolete DSA. </p>
+
+<blockquote>
+<pre>
+ # Postfix &ge; 3.4. Preferred configuration interface. Each file
+ # starts with the private key, followed by the corresponding
+ # certificate, and any intermediate issuer certificates.
+ #
+ smtp_tls_chain_files =
+ /etc/postfix/rsa.pem,
+ /etc/postfix/ecdsa.pem,
+ /etc/postfix/ed25519.pem,
+ /etc/postfix/ed448.pem
+</pre>
+</blockquote>
+
+<p> You can also store the keys separately from their certificates, again
+provided each is listed before the corresponding certificate chain. Storing a
+key and its associated certificate chain in separate files is not recommended,
+because this is prone to race conditions during key rollover, as there is no
+way to update multiple files atomically. </p>
+
+<blockquote>
+<pre>
+ # Postfix &ge; 3.4.
+ # Storing keys separately from the associated certificates is not
+ # recommended.
+ smtp_tls_chain_files =
+ /etc/postfix/rsakey.pem,
+ /etc/postfix/rsacerts.pem,
+ /etc/postfix/ecdsakey.pem,
+ /etc/postfix/ecdsacerts.pem
+</pre>
+</blockquote>
+
+<p> The below examples show the legacy algorithm-specific configurations
+for Postfix 3.3 and older. With Postfix &le; 3.3, even if the key is
+stored in the same file as the certificate, the file is read twice and a
+(brief) race condition still exists during key rollover. While Postfix
+&ge; 3.4 avoids the race when the key and certificate are in the same
+file, you should use the new "smtp_tls_chain_files" interface shown
+above. <p>
+
+<p> RSA key and certificate examples: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_cert_file = /etc/postfix/client.pem
+ smtp_tls_key_file = $smtp_tls_cert_file
+</pre>
+</blockquote>
+
+<p> Their DSA counterparts: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_dcert_file = /etc/postfix/client-dsa.pem
+ smtp_tls_dkey_file = $smtp_tls_dcert_file
+</pre>
+</blockquote>
+
+<p> Their ECDSA counterparts (Postfix &ge; 2.6 + OpenSSL &ge; 1.0.0): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_eccert_file = /etc/postfix/client-ecdsa.pem
+ smtp_tls_eckey_file = $smtp_tls_eccert_file
+</pre>
+</blockquote>
+
+<p> To verify a remote SMTP server certificate, the Postfix SMTP
+client needs to trust the certificates of the issuing Certification
+Authorities. These certificates in "pem" format can be stored in a
+single $smtp_tls_CAfile or in multiple files, one CA per file in
+the $smtp_tls_CApath directory. If you use a directory, don't forget
+to create the necessary "hash" links with: </p>
+
+<blockquote>
+<pre>
+# <b>$OPENSSL_HOME/bin/c_rehash <i>/path/to/directory</i> </b>
+</pre>
+</blockquote>
+
+<p> The $smtp_tls_CAfile contains the CA certificates of one or more
+trusted CAs. The file is opened (with root privileges) before Postfix
+enters the optional chroot jail and so need not be accessible from inside the
+chroot jail. </p>
+
+<p> Additional trusted CAs can be specified via the $smtp_tls_CApath
+directory, in which case the certificates are read (with $mail_owner
+privileges) from the files in the directory when the information
+is needed. Thus, the $smtp_tls_CApath directory needs to be accessible
+inside the optional chroot jail. </p>
+
+<p> The choice between $smtp_tls_CAfile and $smtp_tls_CApath is
+a space/time tradeoff. If there are many trusted CAs, the cost of
+preloading them all into memory may not pay off in reduced access time
+when the certificate is needed. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_CAfile = /etc/postfix/CAcert.pem
+ smtp_tls_CApath = /etc/postfix/certs
+</pre>
+</blockquote>
+
+<h3><a name="client_tls_reuse">Client-side TLS connection reuse</a> </h3>
+
+<p> Historically, the Postfix SMTP client has supported multiple
+deliveries per plaintext connection. Postfix 3.4 introduces support
+for multiple deliveries per TLS-encrypted connection. Multiple
+deliveries per connection improve mail delivery performance,
+especially for destinations that throttle clients that don't combine
+deliveries. </p>
+
+<p> To enable multiple deliveries per TLS connection, specify:</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_connection_reuse = yes
+</pre>
+</blockquote>
+
+<p> Alternatively, specify the attribute "connection_reuse=yes" in
+an smtp_tls_policy_maps entry. </p>
+
+<p> The implementation of TLS connection reuse relies on the same
+scache(8) service as used for delivering plaintext SMTP mail, the
+same tlsproxy(8) daemon as used by the postscreen(8) service, and
+relies on the same hints from the qmgr(8) daemon.
+
+See "<a href="CONNECTION_CACHE_README.html">Postfix Connection
+Cache</a>" for a description of the underlying connection reuse
+infrastructure. </p>
+
+<p> Initial SMTP handshake:</p>
+<pre> smtp(8) -&gt; remote SMTP server</pre>
+
+<p> Reused SMTP/TLS connection, or new SMTP/TLS connection: </p>
+<pre> smtp(8) -&gt; tlsproxy(8) -&gt; remote SMTP server </pre>
+
+<p> Cached SMTP/TLS connection:</p>
+<pre> scache(8) -&gt; tlsproxy(8) -&gt; remote SMTP server</pre>
+
+<p> As of Postfix 3.4, TLS connection reuse is disabled by default.
+This may change once the impact on over-all performance is understood.
+</p>
+
+<h3><a name="client_tls_cache">Client-side TLS session cache</a> </h3>
+
+<p> The remote SMTP server and the Postfix SMTP client negotiate a
+session, which takes some computer time and network bandwidth. By
+default, this session information is cached only in the smtp(8)
+process actually using this session and is lost when the process
+terminates. To share the session information between multiple
+smtp(8) processes, a persistent session cache can be used. You
+can specify any database type that can store objects of several
+kbytes and that supports the sequence operator. DBM databases are
+not suitable because they can only store small objects. The cache
+is maintained by the tlsmgr(8) process, so there is no problem with
+concurrent access. Session caching is highly recommended, because
+the cost of repeatedly negotiating TLS session keys is high. Future
+Postfix SMTP servers may limit the number of sessions that a client
+is allowed to negotiate per unit time.</p>
+
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache
+</pre>
+</blockquote>
+
+<p> Note: as of version 2.5, Postfix no longer uses root privileges
+when opening this file. The file should now be stored under the
+Postfix-owned data_directory. As a migration aid, an attempt to
+open the file under a non-Postfix directory is redirected to the
+Postfix-owned data_directory, and a warning is logged. </p>
+
+<p> Cached Postfix SMTP client session information expires after
+a certain amount of time. Postfix/TLS does not use the OpenSSL
+default of 300s, but a longer time of 3600s (=1 hour). RFC 2246
+recommends a maximum of 24 hours. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_session_cache_timeout = 3600s
+</pre>
+</blockquote>
+
+<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set
+&le; 0, session caching is disabled. If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead. </p>
+
+<h3><a name="client_tls_limits"> Client TLS limitations </a>
+</h3>
+
+<p> The security properties of TLS communication channels are
+application specific. While the TLS protocol can provide a confidential,
+tamper-resistant, mutually authenticated channel between client
+and server, not all of these security features are applicable to every
+communication. </p>
+
+<p> For example, while mutual TLS authentication between browsers and web
+servers is possible, it is not practical, or even useful, for web-servers
+that serve the public to verify the identity of every potential user. In
+practice, most HTTPS transactions are asymmetric: the browser verifies
+the HTTPS server's identity, but the user remains anonymous. Much of
+the security policy is up to the client. If the client chooses to not
+verify the server's name, the server is not aware of this. There are many
+interesting browser security topics, but we shall not dwell
+on them here. Rather, our goal is to understand the security features
+of TLS in conjunction with SMTP. </p>
+
+<p> An important SMTP-specific observation is that a public MX host is
+even more at the mercy of the SMTP client than is an HTTPS server. Not only
+can it not enforce due care in the client's use of TLS, but it cannot even
+enforce the use of TLS, because TLS support in SMTP clients is still the
+exception rather than the rule. One cannot, in practice, limit access to
+one's MX hosts to just TLS-enabled clients. Such a policy would result
+in a vast reduction in one's ability to communicate by email with the
+world at large. </p>
+
+<p> One may be tempted to try enforcing TLS for mail from specific
+sending organizations, but this, too, runs into obstacles. One such
+obstacle is that we don't know who is (allegedly) sending mail until
+we see the "MAIL FROM:" SMTP command, and at that point, if TLS
+is not already in use, a potentially sensitive sender address (and
+with SMTP PIPELINING one or more of the recipients) has (have) already been
+leaked in the clear. Another obstacle is that mail from the sender to
+the recipient may be forwarded, and the forwarding organization may not
+have any security arrangements with the final destination. Bounces also
+need to be protected. These can only be identified by the IP address and
+HELO name of the connecting client, and it is difficult to keep track
+of all the potential IP addresses or HELO names of the outbound email
+servers of the sending organization. </p>
+
+<p> Consequently, TLS security for mail delivery to public MX hosts is
+almost entirely the client's responsibility. The server is largely a
+passive enabler of TLS security, the rest is up to the client. While the
+server has a greater opportunity to mandate client security policy when
+it is a dedicated MSA that only handles outbound mail from trusted clients,
+below we focus on the client security policy. </p>
+
+<p> On the SMTP client, there are further complications. When
+delivering mail to a given domain, in contrast to HTTPS, one rarely
+uses the domain name directly as the target host of the SMTP session.
+More typically, one uses MX lookups &mdash; these are usually
+unauthenticated &mdash; to obtain the domain's SMTP server hostname(s).
+When, as is current practice, the client verifies the insecurely
+obtained MX hostname, it is subject to a DNS man-in-the-middle
+attack. </p>
+
+<p> Adoption of DNSSEC and RFC6698 (DANE) may gradually (as domains
+implement DNSSEC and publish TLSA records for their MX hosts) address
+the DNS man-in-the-middle risk and provide scalable key management
+for SMTP with TLS. Postfix &ge; 2.11 supports the new <a
+href="#client_tls_dane">dane</a> and <a href="#client_tls_dane">dane-only</a>
+security levels that take advantage of these standards. </p>
+
+<p> If clients instead attempted to verify the recipient domain name,
+an SMTP server for multiple domains would need to
+list all its email domain names in its certificate, and generate a
+new certificate each time a new domain were added. At least some CAs set
+fairly low limits (20 for one prominent CA) on the number of names that
+server certificates can contain. This approach is not consistent with
+current practice and does not scale. </p>
+
+<p> It is regrettably the case that TLS <i>secure-channels</i>
+(fully authenticated and immune to man-in-the-middle attacks) impose
+constraints on the sending and receiving sites that preclude ubiquitous
+deployment. One needs to manually configure this type of security for
+each destination domain, and in many cases implement non-default TLS
+<a href="#client_tls_policy">policy table</a> entries for additional
+domains hosted at a common secured destination. For these reasons
+secure-channel configurations
+will never be the norm. For the generic domain with which you
+have made no specific security arrangements, this security level is not
+a good fit. </p>
+
+<p> Given that strong authentication is not generally possible, and that
+verifiable certificates cost time and money, many servers that implement
+TLS use self-signed certificates or private CAs. This further limits
+the applicability of verified TLS on the public Internet. </p>
+
+<p> Historical note: while the documentation of these issues and many of the
+related features were new with Postfix 2.3, the issue was well
+understood before Postfix 1.0, when Lutz J&auml;nicke was designing
+the first unofficial Postfix TLS patch. See his original post <a
+href="http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html">http://www.imc.org/ietf-apps-tls/mail-archive/msg00304.html</a>
+and the first response <a
+href="http://www.imc.org/ietf-apps-tls/mail-archive/msg00305.html">http://www.imc.org/ietf-apps-tls/mail-archive/msg00305.html</a>.
+The problem is not even unique to SMTP or even TLS, similar issues exist
+for secure connections via aliases for HTTPS and Kerberos. SMTP merely
+uses indirect naming (via MX records) more frequently. </p>
+
+<h3> <a name="client_tls_policy"> TLS policy table </a>
+</h3>
+
+<p> A small fraction of servers offer STARTTLS but the negotiation
+consistently fails. As long as encryption is not mandatory, the
+Postfix SMTP client retries the delivery immediately with TLS
+disabled, without any need to explicitly disable TLS for the problem
+destinations. </p>
+
+<p> The policy table is specified via the smtp_tls_policy_maps
+parameter. This lists optional lookup tables with the Postfix SMTP client
+TLS security policy by next-hop destination. </p>
+
+<p> The TLS policy table is indexed by the full next-hop destination,
+which is either the recipient domain, or the verbatim next-hop
+specified in the transport table, $local_transport, $virtual_transport,
+$relay_transport or $default_transport. This includes any enclosing
+square brackets and any non-default destination server port suffix. The
+<a href="#client_lmtp_tls">LMTP</a> socket type prefix (inet: or unix:)
+is not included in the lookup key. </p>
+
+<p> Only the next-hop domain, or $myhostname with LMTP over UNIX-domain
+sockets, is used as the nexthop name for certificate verification. The
+port and any enclosing square brackets are used in the table lookup key,
+but are not used for server name verification. </p>
+
+<p> When the lookup key is a domain name without enclosing square brackets
+or any <i>:port</i> suffix (typically the recipient domain), and the full
+domain is not found in the table, just as with the transport(5) table,
+the parent domain starting with a leading "." is matched recursively. This
+allows one to specify a security policy for a recipient domain and all
+its sub-domains. </p>
+
+<p> The lookup result is a security level, followed by an optional
+list of whitespace and/or comma separated name=value attributes
+that override related main.cf settings. The TLS security <a
+href="#client_tls_levels">levels</a> are described above. Below, we
+describe the corresponding table syntax: </p>
+
+<dl>
+
+<dt><b>none</b></dt> <dd><a href="#client_tls_none">No TLS</a>. No
+additional attributes are supported at this level. </dd>
+
+<dt><b>may</b></dt> <dd><a href="#client_tls_may">Opportunistic TLS</a>.
+The optional "ciphers", "exclude" and "protocols" attributes
+(available for opportunistic TLS with Postfix &ge; 2.6) override the
+"smtp_tls_ciphers", "smtp_tls_exclude_ciphers" and "smtp_tls_protocols"
+configuration parameters. At this level and higher, the optional
+"servername" attribute (available with Postfix &ge; 3.4) overrides the
+global "smtp_tls_servername" parameter, enabling per-destination
+configuration of the SNI extension sent to the remote SMTP server. </dd>
+
+<dt><b>encrypt</b></dt> <dd><a href="#client_tls_encrypt"> Mandatory encryption</a>.
+Mail is delivered only if the remote SMTP server offers STARTTLS
+and the TLS handshake succeeds. At this level and higher, the optional
+"protocols" attribute overrides the main.cf smtp_tls_mandatory_protocols
+parameter, the optional "ciphers" attribute overrides the
+main.cf smtp_tls_mandatory_ciphers parameter, and the optional
+"exclude" attribute (Postfix &ge; 2.6) overrides the main.cf
+smtp_tls_mandatory_exclude_ciphers parameter. </dd>
+
+<dt><b>dane</b></dt> <dd><a href="#client_tls_dane">Opportunistic DANE TLS</a>.
+The TLS policy for the destination is obtained via TLSA records in
+DNSSEC. If no TLSA records are found, the effective security level
+used is <a href="#client_tls_may">may</a>. If TLSA records are
+found, but none are usable, the effective security level is <a
+href="#client_tls_encrypt">encrypt</a>. When usable TLSA records
+are obtained for the remote SMTP server, SSLv2+3 are automatically
+disabled (see smtp_tls_mandatory_protocols), and the server certificate
+must match the TLSA records. RFC 7672 (DANE) TLS authentication
+and DNSSEC support is available with Postfix 2.11 and later. </dd>
+
+<dt><b>dane-only</b></dt> <dd><a href="#client_tls_dane">Mandatory DANE TLS</a>.
+The TLS policy for the destination is obtained via TLSA records in
+DNSSEC. If no TLSA records are found, or none are usable, no
+connection is made to the server. When usable TLSA records are
+obtained for the remote SMTP server, SSLv2+3 are automatically disabled
+(see smtp_tls_mandatory_protocols), and the server certificate must
+match the TLSA records. RFC 7672 (DANE) TLS authentication and
+DNSSEC support is available with Postfix 2.11 and later. </dd>
+
+<dt><b>fingerprint</b></dt> <dd><a href="#client_tls_fprint">Certificate
+fingerprint verification.</a> Available with Postfix 2.5 and
+later. At this security level, there are no trusted Certification
+Authorities. The certificate trust chain, expiration date, ... are
+not checked. Instead, the optional <b>match</b> attribute, or else
+the main.cf <b>smtp_tls_fingerprint_cert_match</b> parameter, lists
+the server certificate fingerprints or public key fingerprints
+(Postfix 2.9 and later). The
+digest algorithm used to calculate fingerprints is selected by the
+<b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can
+be combined with a "|" delimiter in a single match attribute, or multiple
+match attributes can be employed. The ":" character is not used as a
+delimiter as it occurs between each pair of fingerprint (hexadecimal)
+digits. </dd>
+
+<dt><b>verify</b></dt> <dd><a href="#client_tls_verify">Mandatory
+server certificate verification</a>. Mail is delivered only if the
+TLS handshake succeeds, if the remote SMTP server certificate can
+be validated (not expired or revoked, and signed by a trusted
+Certification Authority), and if the server certificate name matches
+the optional "match" attribute (or the main.cf smtp_tls_verify_cert_match
+parameter value when no optional "match" attribute is specified).
+With Postfix &ge; 2.11 the "tafile" attribute optionally modifies
+trust chain verification in the same manner as the
+"smtp_tls_trust_anchor_file" parameter. The "tafile" attribute
+may be specified multiple times to load multiple trust-anchor
+files. </dd>
+
+<dt><b>secure</b></dt> <dd><a href="#client_tls_secure">Secure certificate
+verification.</a> Mail is delivered only if the TLS handshake succeeds,
+and DNS forgery resistant remote SMTP certificate verification succeeds
+(not expired or revoked, and signed by a trusted Certification Authority),
+and if the server certificate name matches the optional "match" attribute
+(or the main.cf smtp_tls_secure_cert_match parameter value when no optional
+"match" attribute is specified). With Postfix &ge; 2.11 the "tafile"
+attribute optionally modifies trust chain verification in the same manner
+as the "smtp_tls_trust_anchor_file" parameter. The "tafile" attribute
+may be specified multiple times to load multiple trust-anchor
+files. </dd>
+
+</dl>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> The "match" attribute is especially useful to verify TLS
+certificates for domains that are hosted on a shared server. In
+that case, specify "match" rules for the shared server's name.
+While secure verification can also be achieved with manual routing
+overrides in Postfix transport(5) tables, that approach can deliver
+mail to the wrong host when domains are assigned to new gateway
+hosts. The "match" attribute approach avoids the problems of manual
+routing overrides; mail is deferred if verification of a new MX
+host fails. </p>
+
+<li> <p> When a policy table entry specifies multiple match patterns,
+multiple match strategies, or multiple protocols, these must be
+separated by colons. </p>
+
+<li> <p> The "exclude" attribute (Postfix &ge; 2.6) is used to disable
+ciphers that cause handshake failures with a specific mandatory TLS
+destination, without disabling the ciphers for all mandatory destinations.
+Alternatively, you can exclude ciphers that cause issues with multiple
+remote servers in main.cf, and selectively enable them on a per-destination
+basis in the policy table by setting a shorter or empty exclusion list. The
+per-destination "exclude" list preempts both the opportunistic and
+mandatory security level exclusions, so that all excluded ciphers
+can be enabled for known-good destinations. For non-mandatory TLS
+destinations that exhibit cipher-specific problems, Postfix will fall
+back to plain-text delivery. If plain-text is not acceptable make TLS
+mandatory and exclude the problem ciphers. </p>
+
+</ul>
+
+<p>
+Example:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+ # Postfix 2.5 and later
+ smtp_tls_fingerprint_digest = sha256
+/etc/postfix/tls_policy:
+ example.edu none
+ example.mil may
+ example.gov encrypt ciphers=high
+ example.com verify match=hostname:dot-nexthop ciphers=high
+ example.net secure
+ .example.net secure match=.example.net:example.net
+ [mail.example.org]:587 secure match=nexthop
+ # Postfix 2.5 and later
+ [thumb.example.org] fingerprint
+ match=b6:b4:72:34:e2:59:cd:fb:...:0d:4d:cc:2c:7d:84:de:e6:2f
+ match=51:e9:af:2e:1e:40:1f:de:...:35:2d:09:16:31:5a:eb:82:76
+ # Postfix &ge; 3.6 "protocols" syntax
+ example.info may protocols=&gt;=TLSv1 ciphers=medium exclude=3DES
+ # Legacy protocols syntax
+ example.info may protocols=!SSLv2:!SSLv3 ciphers=medium exclude=3DES
+</pre>
+</blockquote>
+
+<p> <b>Note:</b> The "hostname" strategy if listed in a non-default setting
+of smtp_tls_secure_cert_match or in the "match" attribute in the policy
+table can render the "secure" level vulnerable to DNS forgery. Do not use
+the "hostname" strategy for <a href="#client_tls_secure">secure-channel</a>
+configurations in environments where DNS security is not assured. </p>
+
+<h3> <a name="client_tls_discover"> Discovering servers that support
+TLS </a> </h3>
+
+<p> As we decide on a "per site" basis whether or not to use TLS,
+it would be good to have a list of sites that offered "STARTTLS".
+We can collect it ourselves with this option. </p>
+
+<p> If the smtp_tls_note_starttls_offer feature is enabled and a
+server offers STARTTLS while TLS is not already enabled for that
+server, the Postfix SMTP client logs a line as follows: </p>
+
+<blockquote>
+<pre>
+postfix/smtp[pid]: Host offered STARTTLS: [hostname.example.com]
+</pre>
+</blockquote>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_note_starttls_offer = yes
+</pre>
+</blockquote>
+
+<h3><a name="client_vrfy_server">Server certificate verification depth</a> </h3>
+
+<p> The server certificate verification depth is specified with the
+main.cf smtp_tls_scert_verifydepth parameter. The default verification
+depth is 9 (the OpenSSL default), for compatibility with Postfix
+versions before 2.5 where smtp_tls_scert_verifydepth was ignored.
+When you configure trust
+in a root CA, it is not necessary to explicitly trust intermediary CAs
+signed by the root CA, unless $smtp_tls_scert_verifydepth is less than the
+number of CAs in the certificate chain for the servers of interest. With
+a verify depth of 1 you can only verify certificates directly signed
+by a trusted CA, and all trusted intermediary CAs need to be configured
+explicitly. With a verify depth of 2 you can verify servers signed by a
+root CA or a direct intermediary CA (so long as the server is correctly
+configured to supply its intermediate CA certificate). </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_scert_verifydepth = 2
+</pre>
+</blockquote>
+
+<h3> <a name="client_cipher">Client-side cipher controls </a> </h3>
+
+<p> The Postfix SMTP client supports 5 distinct cipher grades
+as specified by the smtp_tls_mandatory_ciphers configuration
+parameter. This setting controls the minimum acceptable SMTP client
+TLS cipher grade for use with mandatory TLS encryption. The default
+value "medium" is suitable for most destinations with which you may
+want to enforce TLS, and is beyond the reach of today's cryptanalytic
+methods. See smtp_tls_policy_maps for information on how to configure
+ciphers on a per-destination basis. </p>
+
+<p> By default anonymous ciphers are allowed, and automatically
+disabled when remote SMTP server certificates are verified. If you
+want to
+disable anonymous ciphers even at the "encrypt" security level, set
+"smtp_tls_mandatory_exclude_ciphers = aNULL"; and to
+disable anonymous ciphers even with opportunistic TLS, set
+"smtp_tls_exclude_ciphers = aNULL". There is generally
+no need to take these measures. Anonymous ciphers save bandwidth
+and TLS session cache space, if certificates are ignored, there is
+little point in requesting them. </p>
+
+<p> The "smtp_tls_ciphers" configuration parameter (Postfix &ge; 2.6)
+provides control over the minimum cipher grade for opportunistic TLS.
+The default minimum cipher grade for opportunistic TLS is "medium"
+for Postfix releases after the middle of 2015, and "export" for
+older releases. With Postfix &lt; 2.6, the minimum opportunistic
+TLS cipher grade is always "export". </p>
+
+<p> With mandatory and opportunistic TLS encryption, the Postfix
+SMTP client will by default disable SSLv2 and SSLv3. The mandatory
+TLS protocol list is specified via the
+smtp_tls_mandatory_protocols configuration parameter. The corresponding
+smtp_tls_protocols parameter (Postfix &ge; 2.6) controls
+the TLS protocols used with opportunistic TLS. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_mandatory_ciphers = medium
+ smtp_tls_mandatory_exclude_ciphers = RC4, MD5
+ smtp_tls_exclude_ciphers = aNULL
+ smtp_tls_ciphers = medium
+ # Preferred form with Postfix &ge; 3.6:
+ smtp_tls_mandatory_protocols = &gt;=TLSv1.2
+ smtp_tls_protocols = &gt;=TLSv1
+ # Legacy form for Postfix &lt; 3.6:
+ smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+ smtp_tls_protocols = !SSLv2,!SSLv3
+</pre>
+</blockquote>
+
+<h3> <a name="client_smtps">Client-side SMTPS support </a> </h3>
+
+<p> These sections show how to send mail to a server that does not
+support STARTTLS, but that provides the SMTPS service
+on TCP port 465. Depending on the Postfix version, some additional
+tooling may be required. </p>
+
+<h4> Postfix &ge; 3.0 </h4>
+
+<p> The Postfix SMTP client has SMTPS support built-in as of version
+3.0. Use one of the following examples, to send all remote mail,
+or to send only some remote mail, to an SMTPS server. </p>
+
+<h5> Postfix &ge; 3.0: Sending all remote mail to an SMTPS server </h5>
+
+<p> The first example will send all remote mail over SMTPS through
+a provider's server called "mail.example.com": </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Client-side SMTPS requires "encrypt" or stronger.
+ smtp_tls_security_level = encrypt
+ smtp_tls_wrappermode = yes
+ # The [] suppress MX lookups.
+ relayhost = [mail.example.com]:465
+</pre>
+</blockquote>
+
+<p> Use "postfix reload" to make the change effective. </p>
+
+<p> See SOHO_README for additional information about SASL authentication.
+</p>
+
+<h5> Postfix &ge; 3.0: Sending only mail for a specific destination
+via SMTPS </h5>
+
+<p> The second example will send only mail for "example.com" via
+SMTPS. This time, Postfix uses a transport map to deliver only
+mail for "example.com" via SMTPS: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+
+/etc/postfix/transport:
+ example.com relay-smtps:example.com:465
+
+/etc/postfix/master.cf:
+ relay-smtps unix - - n - - smtp
+ # Client-side SMTPS requires "encrypt" or stronger.
+ -o smtp_tls_security_level=encrypt
+ -o smtp_tls_wrappermode=yes
+</pre>
+</blockquote>
+
+<p> Use "postmap hash:/etc/postfix/transport" and "postfix reload"
+to make the change effective. </p>
+
+<p> See SOHO_README for additional information about SASL
+authentication. </p>
+
+<h4> Postfix &lt; 3.0 </h4>
+
+<p> Although older Postfix SMTP client versions do not support TLS
+wrapper mode, it is relatively easy to forward a connection through
+the stunnel program if Postfix needs to deliver mail to some legacy
+system that doesn't support STARTTLS. </p>
+
+<h5> Postfix &lt; 3.0: Sending all remote mail to an SMTPS server </h5>
+
+<p> The first example uses SMTPS to send all remote mail to a
+provider's mail server called "mail.example.com". </p>
+
+<p> A minimal stunnel.conf file is sufficient to set up a tunnel
+from local port 11125 to the remote destination "mail.example.com"
+and port "smtps". Postfix will later use this tunnel to connect to
+the remote server. </p>
+
+<blockquote>
+<pre>
+/path/to/stunnel.conf:
+ [smtp-tls-wrapper]
+ accept = 11125
+ client = yes
+ connect = mail.example.com:smtps
+</pre>
+</blockquote>
+
+<p> To test this tunnel, use: </p>
+
+<blockquote>
+<pre>
+$ telnet localhost 11125
+</pre>
+</blockquote>
+
+<p> This should produce the greeting from the remote SMTP server
+at mail.example.com. </p>
+
+<p> On the Postfix side, the relayhost feature sends all remote
+mail through the local stunnel listener on port 11125: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ relayhost = [127.0.0.1]:11125
+</pre>
+</blockquote>
+
+<p> Use "postfix reload" to make the change effective. </p>
+
+<p> See SOHO_README for additional information about SASL
+authentication. </p>
+
+<h4> Postfix &lt; 3.0: Sending only mail for a specific destination via SMTPS </h4>
+
+<p> The second example will use SMTPS to send only mail for
+"example.com" via SMTPS. It uses the same stunnel configuration
+file as the first example, so it won't be repeated here. </p>
+
+<p> This time, the Postfix side uses a transport map to direct only
+mail for "example.com" through the tunnel: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+
+/etc/postfix/transport:
+ example.com relay:[127.0.0.1]:11125
+</pre>
+</blockquote>
+
+<p> Use "postmap hash:/etc/postfix/transport" and "postfix reload"
+to make the change effective. </p>
+
+<p> See SOHO_README for additional information about SASL authentication.
+</p>
+
+<h3> <a name="client_misc"> Miscellaneous client controls </a> </h3>
+
+<p> The smtp_starttls_timeout parameter limits the time of Postfix
+SMTP client write and read operations during TLS startup and shutdown
+handshake procedures. In case of problems the Postfix SMTP client
+tries the next network address on the mail exchanger list, and
+defers delivery if no alternative server is available. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_starttls_timeout = 300s
+</pre>
+</blockquote>
+
+<p> With Postfix 2.8 and later, the tls_disable_workarounds parameter
+specifies a list or bit-mask of OpenSSL bug work-arounds to disable. This
+may be necessary if one of the work-arounds enabled by default in
+OpenSSL proves to pose a security risk, or introduces an unexpected
+interoperability issue. Some bug work-arounds known to be problematic
+are disabled in the default value of the parameter when linked with
+an OpenSSL library that could be vulnerable. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_disable_workarounds = 0xFFFFFFFF
+ tls_disable_workarounds = CVE-2010-4180, LEGACY_SERVER_CONNECT
+</pre>
+</blockquote>
+
+<p> Note: Disabling LEGACY_SERVER_CONNECT is not wise at this
+time, lots of servers are still unpatched and Postfix is <a
+href="http://www.postfix.org/wip.html#tls-renegotiation">not
+significantly vulnerable</a> to the renegotiation issue in the TLS
+protocol. </p>
+
+<p> With Postfix &ge; 2.11, the tls_ssl_options parameter specifies
+a list or bit-mask of OpenSSL options to enable. Specify one or
+more of the named options below, or a hexadecimal bitmask of options
+found in the ssl.h file corresponding to the run-time OpenSSL
+library. While it may be reasonable to turn off all bug workarounds
+(see above), it is not a good idea to attempt to turn on all features.
+</p>
+
+<p> A future version of OpenSSL may by default no longer allow
+connections to servers that don't support secure renegotiation.
+Since the exposure for SMTP is minimal, and some SMTP servers may
+remain unpatched, you can add LEGACY_SERVER_CONNECT to the
+options to restore the more permissive default of current OpenSSL
+releases. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_ssl_options = NO_TICKET, NO_COMPRESSION, LEGACY_SERVER_CONNECT
+</pre>
+</blockquote>
+
+<p> You should only enable features via the hexadecimal mask when
+the need to control the feature is critical (to deal with a new
+vulnerability or a serious interoperability problem). Postfix DOES
+NOT promise backwards compatible behavior with respect to the mask
+bits. A feature enabled via the mask in one release may be enabled
+by other means in a later release, and the mask bit will then be
+ignored. Therefore, use of the hexadecimal mask is only a temporary
+measure until a new Postfix or OpenSSL release provides a better
+solution. </p>
+
+<h2><a name="tlsmgr_controls"> TLS manager specific settings </a> </h2>
+
+<p> The security of cryptographic software such as TLS depends
+critically on the ability to generate unpredictable numbers for
+keys and other information. To this end, the tlsmgr(8) process
+maintains a Pseudo Random Number Generator (PRNG) pool. This is
+queried by the smtp(8) and smtpd(8) processes when they initialize.
+By default, these daemons request 32 bytes, the equivalent to 256
+bits. This is more than sufficient to generate a 128bit (or 168bit)
+session key. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_daemon_random_bytes = 32
+</pre>
+</blockquote>
+
+<p> In order to feed its in-memory PRNG pool, the tlsmgr(8) reads
+entropy from an external source, both at startup and during run-time.
+Specify a good entropy source, like EGD or /dev/urandom; be sure
+to only use non-blocking sources (on OpenBSD, use /dev/arandom
+when tlsmgr(8) complains about /dev/urandom timeout errors).
+If the entropy source is not a
+regular file, you must prepend the source type to the source name:
+"dev:" for a device special file, or "egd:" for a source with EGD
+compatible socket interface. </p>
+
+<p> Examples (specify only one in main.cf): </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_random_source = dev:/dev/urandom
+ tls_random_source = egd:/var/run/egd-pool
+</pre>
+</blockquote>
+
+<p> By default, tlsmgr(8) reads 32 bytes from the external entropy
+source at each seeding event. This amount (256bits) is more than
+sufficient for generating a 128bit symmetric key. With EGD and
+device entropy sources, the tlsmgr(8) limits the amount of data
+read at each step to 255 bytes. If you specify a regular file as
+entropy source, a larger amount of data can be read. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_random_bytes = 32
+</pre>
+</blockquote>
+
+<p> In order to update its in-memory PRNG pool, the tlsmgr(8)
+queries the external entropy source again after a pseudo-random
+amount of time. The time is calculated using the PRNG, and is
+between 0 and the maximal time specified with tls_random_reseed_period.
+The default maximal time interval is 1 hour. </p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_random_reseed_period = 3600s
+</pre>
+</blockquote>
+
+<p> The tlsmgr(8) process saves the PRNG state to a persistent
+exchange file at regular times and when the process terminates, so
+that it can recover the PRNG state the next time it starts up.
+This file is created when it does not exist. </p>
+
+<p> Examples: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ tls_random_exchange_name = /var/lib/postfix/prng_exch
+ tls_random_prng_update_period = 3600s
+</pre>
+</blockquote>
+
+<p> As of version 2.5, Postfix no longer uses root privileges when
+opening this file. The file should now be stored under the Postfix-owned
+data_directory. As a migration aid, an attempt to open the file
+under a non-Postfix directory is redirected to the Postfix-owned
+data_directory, and a warning is logged. If you wish to continue
+using a pre-existing PRNG state file, move it to the data_directory
+and change the ownership to the account specified with the mail_owner
+parameter. </p>
+
+<p> With earlier Postfix versions the default file location
+is under the Postfix configuration directory, which is not the
+proper place for information that is modified by Postfix. </p>
+
+<h2><a name="quick-start">Getting started, quick and dirty</a></h2>
+
+<p> The following steps will get you started quickly. Because you
+sign your own Postfix public key certificate, you get TLS encryption
+but no TLS authentication. This is sufficient for testing, and
+for exchanging email with sites that you have no trust relationship
+with. For real authentication you need also enable DNSSEC record
+signing for your domain and publish TLSA records and/or your Postfix
+public key certificate needs to be signed by a recognized Certification
+Authority. To authenticate the certificates of a remote host you
+need a DNSSEC-validating local resolver and to enable <a
+href="#client_tls_dane">DANE</a> authentication and/or configure
+the Postfix SMTP client with a list of public key certificates of
+Certification Authorities, but make sure to read about the <a
+href="#client_tls_limits">limitations</a> of the latter approach.
+</p>
+
+<p> In the examples below, user input is shown in <b><tt>bold</tt></b>
+font, and a "<tt>#</tt>" prompt indicates a super-user shell. </p>
+
+<ul>
+
+<li> <p> <a href="#built-in">Quick-start TLS with Postfix &ge; 3.1</a>.</p>
+
+<li> <p> <a href="#self-signed">Self-signed server certificate</a>.</p>
+
+<li> <p> <a href="#private-ca">Private Certification Authority</a>. </p>
+
+</ul>
+
+<h3><a name="built-in">Quick-start TLS with Postfix &ge; 3.1</a></h3>
+
+<p> Postfix 3.1 provides built-in support for enabling TLS in the
+SMTP client and server and for ongoing certificate and DANE TLSA
+record management.
+
+<ul>
+<li> <p> <a href="#quick-client">Quick-start TLS in the Postfix &ge; 3.1 SMTP client</a>. </p>
+<li> <p> <a href="#quick-server">Quick-start TLS in the Postfix &ge; 3.1 SMTP server</a>. </p>
+</ul>
+
+<h4> <a name="quick-client">Quick-start TLS in the Postfix &ge; 3.1 SMTP client</a>. </h4>
+
+<p> If you are using Postfix 3.1 or later, and your SMTP client TLS
+settings are in their default state, you can enable <a
+href="#client_tls_may">opportunistic</a> TLS in the SMTP client as
+follows: </p>
+
+<blockquote>
+<pre>
+# postfix tls enable-client
+# postfix reload
+</pre>
+</blockquote>
+
+<p> If some of the Postfix SMTP client TLS settings are not in their
+default state, this will not make any changes, but will instead
+suggest the minimal required settings for SMTP client TLS. The
+"postfix reload" command is optional, it is only needed if you want
+the settings to take effect right away. Note, this does not enable
+trust in any public certification authorities, and does not configure
+client TLS certificates as these are largely pointless with <a
+href="#client_tls_may">opportunistic</a> TLS. </p>
+
+<p> There is not yet a turn-key command for enabling <a
+href="#client_tls_dane">DANE</a> authentication. This is because
+DANE requires changes to your <b>resolv.conf</b> file and a
+corresponding DNSSEC-validating resolver local to the Postfix host,
+these changes are difficult to automate in a portable way. </p>
+
+<p> If you're willing to revert your settings to the defaults and
+switch to a "stock" opportunistic TLS configuration, then you can:
+erase all the SMTP client TLS settings and then enable client TLS: </p>
+
+<blockquote>
+<pre>
+# postconf -X `postconf -nH | egrep '^smtp(_|_enforce_|_use_)tls'`
+# postfix tls enable-client
+# postfix reload
+</pre>
+</blockquote>
+
+<h4><a name="quick-server">Quick-start TLS in the Postfix &ge; 3.1 SMTP server</a>.</h4>
+
+<p> If you are using Postfix 3.1 or later, and your SMTP server TLS
+settings are in their default state, you can enable
+opportunistic TLS in the SMTP server as follows: </p>
+
+<blockquote>
+<pre>
+# postfix tls enable-server
+# postfix reload
+</pre>
+</blockquote>
+
+<p> If some of the Postfix SMTP client TLS settings are not in their
+default state, this will not make any changes, but will instead
+suggest the minimal required settings for SMTP client TLS. The
+"postfix reload" command is optional, it is only needed if you want
+the settings to take effect right away. This will generate a
+self-signed private key and certificate and enable TLS in the Postfix
+SMTP server. </p>
+
+<p> If you're willing to revert your settings to the defaults and
+switch to a "stock" server TLS configuration, then you can: erase
+all the SMTP server TLS settings and then enable server TLS: </p>
+
+<blockquote>
+<pre>
+# postconf -X `postconf -nH | egrep '^smtpd(_|_enforce_|_use_)tls'`
+# postfix tls enable-server
+# postfix reload
+</pre>
+</blockquote>
+
+<p> Postfix &ge; 3.1 provides additional built-in support for ongoing
+management of TLS in the SMTP server, via additional "postfix tls"
+sub-commands. These make it easy to generate certificate signing
+requests, create and deploy new keys and certificates, and generate
+DANE TLSA records. See the postfix-tls(1) documentation for details.
+</p>
+
+<h3><a name="self-signed">Self-signed server certificate</a></h3>
+
+<p> The following commands (credits: Viktor Dukhovni) generate and
+install a 2048-bit RSA private key and 10-year self-signed certificate
+for the local Postfix system. This requires super-user privileges.
+(By using date-specific filenames for the certificate and key files,
+and updating main.cf with new filenames, a potential race condition
+in which the key and certificate might not match is avoided).
+</p>
+
+<blockquote>
+<pre>
+# dir="$(postconf -h config_directory)"
+# fqdn=$(postconf -h myhostname)
+# case $fqdn in /*) fqdn=$(cat "$fqdn");; esac
+# ymd=$(date +%Y-%m-%d)
+# key="${dir}/key-${ymd}.pem"; rm -f "${key}"
+# cert="${dir}/cert-${ymd}.pem"; rm -f "${cert}"
+# (umask 077; openssl genrsa -out "${key}" 2048) &&
+ openssl req -new -key "${key}" \
+ -x509 -subj "/CN=${fqdn}" -days 3650 -out "${cert}" &&
+ postconf -e \
+ "smtpd_tls_cert_file = ${cert}" \
+ "smtpd_tls_key_file = ${key}" \
+ 'smtpd_tls_security_level = may' \
+ 'smtpd_tls_received_header = yes' \
+ 'smtpd_tls_loglevel = 1' \
+ 'smtp_tls_security_level = may' \
+ 'smtp_tls_loglevel = 1' \
+ 'smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache' \
+ 'tls_random_source = dev:/dev/urandom'
+</pre>
+</blockquote>
+
+<p> Note: the last command requires both single (') and double (")
+quotes. </p>
+
+<p> The postconf(1) command above enables opportunistic TLS for
+receiving and sending mail. It also enables logging of TLS connections
+and recording of TLS use in the "Received" header. TLS session
+caching is also enabled in the Postfix SMTP client. With Postfix
+&ge; 2.10, the SMTP server does not need an explicit session cache
+since session reuse is better handled via RFC 5077 TLS session
+tickets. </p>
+
+<h3><a name="private-ca">Private Certification Authority</a></h3>
+
+<ul>
+
+<li> <p> Become your own Certification Authority, so that you can
+sign your own certificates, and so that your own systems can
+authenticate certificates from your own CA. This example uses the
+CA.pl script that ships with OpenSSL. On some systems, OpenSSL
+installs this as <tt>/usr/local/openssl/misc/CA.pl</tt>. Some systems
+install this as
+part of a package named <tt>openssl-perl</tt> or something similar.
+The script creates a private key in <tt>./demoCA/private/cakey.pem</tt>
+and a public key in <tt>./demoCA/cacert.pem</tt>.</p>
+
+<blockquote>
+<pre>
+% <b>/usr/local/ssl/misc/CA.pl -newca</b>
+CA certificate filename (or enter to create)
+
+Making CA certificate ...
+Using configuration from /etc/ssl/openssl.cnf
+Generating a 1024 bit RSA private key
+....................++++++
+.....++++++
+writing new private key to './demoCA/private/cakey.pem'
+Enter PEM pass phrase:<b>whatever</b>
+</pre>
+</blockquote>
+
+<li> <p> Create an unpassworded private key for host foo.porcupine.org and create
+an unsigned public key certificate. </p>
+
+<blockquote>
+<pre>
+% <b>(umask 077; openssl req -new -newkey rsa:2048 -nodes -keyout foo-key.pem -out foo-req.pem)</b>
+Using configuration from /etc/ssl/openssl.cnf
+Generating a 2048 bit RSA private key
+........................................++++++
+....++++++
+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.
+What you are about to enter is what is called a Distinguished Name or a DN.
+There are quite a few fields but you can leave some blank
+For some fields there will be a default value,
+If you enter '.', the field will be left blank.
+-----
+Country Name (2 letter code) [AU]:<b>US</b>
+State or Province Name (full name) [Some-State]:<b>New York</b>
+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.porcupine.org</b>
+Email Address []:<b>wietse@porcupine.org</b>
+
+Please enter the following 'extra' attributes
+to be sent with your certificate request
+A challenge password []:<b>whatever</b>
+An optional company name []:
+</pre>
+</blockquote>
+
+<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 -days 365 -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
+Signature ok
+The Subjects Distinguished Name is as follows
+countryName :PRINTABLE:'US'
+stateOrProvinceName :PRINTABLE:'New York'
+localityName :PRINTABLE:'Westchester'
+organizationName :PRINTABLE:'Porcupine'
+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>
+
+
+1 out of 1 certificate requests certified, commit? [y/n]<b>y</b>
+Write out database with 1 new entries
+Data Base Updated
+</pre>
+</blockquote>
+
+<li> <p> Install the host private key, the host public key certificate,
+and the Certification Authority certificate files. This requires
+super-user privileges. </p>
+
+<p> The following commands assume that the key and certificate will
+be installed for the local Postfix MTA. You will need to adjust the
+commands if the Postfix MTA is on a different host. </p>
+
+<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>
+</pre>
+</blockquote>
+
+<li> <p> Configure Postfix, by adding the following to
+<tt>/etc/postfix/main.cf </tt>. It is generally best to not configure
+client certificates, unless there are servers which authenticate your mail
+submission via client certificates. Often servers that perform TLS client
+authentication will issue the required certificates signed by their own
+CA. If you configure the client certificate and key incorrectly, you
+will be unable to send mail to sites that request a client certificate,
+but don't require them from all clients. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_CAfile = /etc/postfix/cacert.pem
+ smtp_tls_session_cache_database =
+ btree:/var/lib/postfix/smtp_tls_session_cache
+ smtp_tls_security_level = may
+ smtp_tls_loglevel = 1
+ 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_received_header = yes
+ smtpd_tls_session_cache_database =
+ btree:/var/lib/postfix/smtpd_tls_session_cache
+ tls_random_source = dev:/dev/urandom
+ smtpd_tls_security_level = may
+ smtpd_tls_loglevel = 1
+</pre>
+</blockquote>
+
+</ul>
+
+
+<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
+top-level directory and with arguments as shown next. </p>
+
+<p> <b> NOTE: Do not use Gnu TLS. It will spontaneously terminate
+a Postfix daemon process with exit status code 2, instead of allowing
+Postfix to 1) report the error to the maillog file, and to 2) provide
+plaintext service where this is appropriate. </b> </p>
+
+<ul>
+
+<li> <p> If the OpenSSL include files (such as <tt>ssl.h</tt>) are
+in directory <tt>/usr/include/openssl</tt>, and the OpenSSL libraries
+(such as <tt>libssl.so</tt> and <tt>libcrypto.so</tt>) are in
+directory <tt>/usr/lib</tt>: </p>
+
+<blockquote>
+<pre>
+% <b>make tidy</b> # if you have left-over files from a previous build
+% <b>make makefiles CCARGS="-DUSE_TLS" AUXLIBS="-lssl -lcrypto"</b>
+</pre>
+</blockquote>
+
+<li> <p> If the OpenSSL include files (such as <tt>ssl.h</tt>) are
+in directory <tt>/usr/local/include/openssl</tt>, and the OpenSSL
+libraries (such as <tt>libssl.so</tt> and <tt>libcrypto.so</tt>)
+are in directory <tt>/usr/local/lib</tt>: </p>
+
+<blockquote>
+<pre>
+% <b>make tidy</b> # if you have left-over files from a previous build
+% <b>make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \
+ AUXLIBS="-L/usr/local/lib -lssl -lcrypto" </b>
+</pre>
+</blockquote>
+
+<p> If your OpenSSL shared library is in a directory that the RUN-TIME
+linker does not know about, add a "-Wl,-R,/path/to/directory" option after
+"-lcrypto". </p>
+
+<p> On Solaris, specify the <tt>-R</tt> option as shown below:
+
+<blockquote>
+<pre>
+% <b>make tidy</b> # if you have left-over files from a previous build
+% <b>make makefiles CCARGS="-DUSE_TLS -I/usr/local/include" \
+ AUXLIBS="-R/usr/local/lib -L/usr/local/lib -lssl -lcrypto" </b>
+</pre>
+</blockquote>
+
+</ul>
+
+<p> If you need to apply other customizations (such as Berkeley DB
+databases, MySQL, PostgreSQL, LDAP or SASL), see the respective
+Postfix README documents, and combine their "<tt>make makefiles</tt>"
+instructions with the instructions above: </p>
+
+<blockquote>
+<pre>
+% <b>make tidy</b> # if you have left-over files from a previous build
+% <b>make makefiles CCARGS="-DUSE_TLS \
+ <i>(other -D or -I options)</i>" \
+ AUXLIBS="-lssl -lcrypto \
+ <i>(other -l options for libraries in /usr/lib)</i> \
+ <i>(-L/path/name + -l options for other libraries)</i>"</b>
+</pre>
+</blockquote>
+
+<p> To complete the build process, see the Postfix INSTALL
+instructions. Postfix has TLS support turned off by default, so
+you can start using Postfix as soon as it is installed. </p>
+
+<h2> <a name="problems"> Reporting problems </a> </h2>
+
+<p> Problems are preferably reported via &lt;postfix-users@postfix.org&gt;.
+See http://www.postfix.org/lists.html for subscription information.
+When reporting a problem, please be thorough in the report. Patches,
+when possible, are greatly appreciated too. </p>
+
+<h2><a name="credits">Credits </a> </h2>
+
+<ul>
+
+<li> TLS support for Postfix was originally developed by Lutz
+J&auml;nicke at Cottbus Technical University.
+
+<li> Wietse Venema adopted the code, did some restructuring, and
+compiled this part of the documentation from Lutz's documents.
+
+<li> Victor Duchovni was instrumental with the re-implementation
+of the smtp_tls_per_site code in terms of enforcement levels, which
+simplified the implementation greatly.
+
+<li> Victor Duchovni implemented the fingerprint security level,
+added more sanity checks, and separated TLS connection management
+from security policy enforcement. The latter change simplified the
+code that verifies certificate signatures, certificate names, and
+certificate fingerprints.
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/TUNING_README.html b/proto/TUNING_README.html
new file mode 100644
index 0000000..61b37bd
--- /dev/null
+++ b/proto/TUNING_README.html
@@ -0,0 +1,704 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Performance Tuning</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" alt="">
+Postfix Performance Tuning</h1>
+
+<hr>
+
+<h2>Purpose of Postfix performance tuning </h2>
+
+<p> The hints and tips in this document help you improve the
+performance of Postfix systems that already work. If your Postfix
+system is unable to receive or deliver mail, then you need to solve
+those problems first, using the DEBUG_README document as guidance.
+
+<p> For tuning external content filter performance, first read the
+respective information in the FILTER_README and SMTPD_PROXY_README
+documents. Then make sure to avoid latency in the content filter
+code. As much as possible avoid performing queries against external
+data sources with a high or highly variable delay. Your content
+filter will run with a small concurrency to avoid CPU/memory
+starvation, and if any latency creeps in, content filter throughput
+will suffer. High volume environments should avoid RBL lookups,
+complex database queries and so on. </p>
+
+<p>Topics on mail receiving performance: </p>
+
+<ul>
+
+<li> <a href="#server_tips">General mail receiving performance tips</a>
+
+<li> <a href="#speedup">Doing more work with your SMTP server processes</a>
+
+<li> <a href="#slowdown">Slowing down SMTP clients that make many errors</a>
+
+<li> <a href="#conn_limit">Measures against clients that make too many connections</a>
+
+</ul>
+
+<p>Topics on mail delivery performance: </p>
+
+<ul>
+
+<li> <a href="#mailing_tips">General mail delivery performance tips</a>
+
+<li> <a href="#hammer">Tuning the frequency of deferred mail delivery attempts</a>
+
+<li> <a href="#rope">Tuning the number of simultaneous deliveries</a>
+
+<li> <a href="#rcpts">Tuning the number of recipients per delivery</a>
+
+</ul>
+
+<p>Other Postfix performance tuning topics: </p>
+
+<ul>
+
+<li> <a href="#proc_limit">Tuning the number of Postfix processes</a>
+
+<li> <a href="#proc_sys">Tuning the number of processes on the system</a>
+
+<li> <a href="#file_limit">Tuning the number of open files or
+sockets</a>
+
+</ul>
+
+<p> The following tools can be used to measure mail system performance
+under artificial loads. They are normally not installed with Postfix.
+</p>
+
+<ul>
+
+<li> <a href="smtp-source.1.html">smtp-source, SMTP/LMTP message
+generator</a>
+
+<li> <a href="smtp-sink.1.html">smtp-sink, SMTP/LMTP message dump
+</a>
+
+<li> <a href="qmqp-source.1.html">qmqp-source, QMQP message generator
+</a>
+
+<li> <a href="qmqp-sink.1.html">qmqp-sink, QMQP message dump </a>
+
+</ul>
+
+<h2><a name="server_tips">General mail receiving performance
+tips</a></h2>
+
+<ul>
+
+<li> <p> Read and understand the maildrop queue, incoming queue,
+and active queue discussions in the QSHAPE_README document. </p>
+
+<li> <p> Run a local name server to reduce slow-down due to DNS
+lookups. If you run multiple Postfix systems, point each local name
+server to a shared forwarding server to reduce the number of lookups
+across the upstream network link. </p>
+
+<li> <p> Eliminate unnecessary LDAP lookups, by specifying a domain
+filter. This eliminates lookups for addresses in remote domains,
+and eliminates lookups of partial addresses. See ldap_table(5) for
+details. </p>
+
+</ul>
+
+<p> When Postfix responds slowly to SMTP clients: </p>
+
+<ul>
+
+<li> <p> <a href="DEBUG_README.html#logging">Look for obvious signs
+of trouble</a> as described in the DEBUG_README document, and
+eliminate those problems first. </p>
+
+<li> <p> Turn off your header_checks and body_checks patterns and
+see if the problem goes away. </p>
+
+<li> <p> <a href="DEBUG_README.html#no_chroot">Turn off chroot
+operation</a> as described in the DEBUG_README document and see
+if the problem goes away. </p>
+
+<li> <p> If Postfix logs the SMTP client as "unknown" then you have
+a name service problem: the name server is bad, or the resolv.conf
+file contains bad information, or some packet filter is blocking
+the DNS requests or replies. </p>
+
+<li> <p> If the number of smtpd(8) processes has reached the process
+limit as specified in master.cf, new SMTP clients must wait until
+a process becomes available. See the STRESS_README and POSTSCREEN_README
+documents for measures that help to prevent SMTP server overload. </p>
+
+</ul>
+
+<h2><a name="speedup">Doing more work with your SMTP server
+processes</a></h2>
+
+<p> With Postfix versions 2.0 and earlier, the smtpd(8) server
+pauses before reporting an error to an SMTP client. The idea is
+called tar pitting. However, these delays also slow down Postfix.
+When the smtpd(8) server replies slowly, sessions take more time,
+so that more smtpd(8) server processes are needed to handle the
+load. When your Postfix smtpd(8) server process limit is reached,
+new clients must wait until a server process becomes available.
+This means that all clients experience poor performance. </p>
+
+<p> You can speed up the handling of smtpd(8) server error replies
+by turning off the delay: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # Not needed with Postfix 2.1
+ smtpd_error_sleep_time = 0
+</pre>
+</blockquote>
+
+<p> With the above setting, Postfix 2.0 and earlier can serve more
+SMTP clients with the same number SMTP server processes. The next
+section describes how Postfix deals with clients that make a large
+number of errors. </p>
+
+<h2><a name="slowdown"> Slowing down SMTP clients that make many errors</a></h2>
+
+<p> The Postfix smtpd(8) server maintains a per-session error count.
+The error count is reset when a message is transferred successfully,
+and is incremented when a client request is unrecognized or
+unimplemented, when a client request violates <a
+href="SMTPD_ACCESS_README.html">access restrictions</a>, or when
+some other error happens. </p>
+
+<p> As the per-session error count increases, the smtpd(8) server
+changes behavior and begins to insert delays into the responses.
+The idea is to slow down a run-away client in order to limit resource
+usage. The behavior is Postfix version dependent. </p>
+
+<p> IMPORTANT: These delays slow down Postfix, too. When too much
+delay is configured, the number of simultaneous SMTP sessions will
+increase until it reaches the smtpd(8) server process limit, and new
+SMTP clients must wait until an smtpd(8) server process becomes available.
+</p>
+
+<p> Postfix version 2.1 and later:</p>
+
+<ul>
+
+<li> <p> When the error count reaches $smtpd_soft_error_limit
+(default: 10), the Postfix smtpd(8) server delays all non-error and
+error responses by $smtpd_error_sleep_time seconds (default: 1
+second). </p>
+
+<li><p>When the error count reaches $smtpd_hard_error_limit
+(default: 20) the Postfix smtpd(8) server breaks the connection. </p>
+
+</ul>
+
+<p> Postfix version 2.0 and earlier:</p>
+
+<ul>
+
+<li> <p> When the error count is less than $smtpd_soft_error_limit
+(default: 10) the Postfix smtpd(8) server delays all error replies by
+$smtpd_error_sleep_time (1 second with Postfix 2.0, 5 seconds with
+Postfix 1.1 and earlier). </p>
+
+<li> <p> When the error count reaches $smtpd_soft_error_limit,
+the Postfix smtpd(8) server delays all responses by "error count"
+seconds or $smtpd_error_sleep_time, whichever is more. </p>
+
+<li><p>When the error count reaches $smtpd_hard_error_limit
+(default: 20) the Postfix smtpd(8) server breaks the connection. </p>
+
+</ul>
+
+<h2><a name="conn_limit">Measures against clients that make too many connections</a></h2>
+
+<p> Note: these features use the Postfix anvil(8) service, introduced
+with Postfix version 2.2. </p>
+
+<p> The Postfix smtpd(8) server can limit the number of simultaneous
+connections from the same SMTP client, as well as the connection
+rate and the rate of certain SMTP commands from the same client.
+These statistics are maintained by the anvil(8) server (translation:
+if anvil(8) breaks, then connection limits stop working). </p>
+
+<p> IMPORTANT: These limits must not be used to regulate legitimate
+traffic: mail will suffer grotesque delays if you do so. The limits
+are designed to protect the smtpd(8) server against abuse by
+out-of-control clients. </p>
+
+<blockquote>
+
+<dl>
+
+<dt> smtpd_client_connection_count_limit (default: 50) </dt> <dd>
+The maximum number of connections that an SMTP client may make
+simultaneously. </dd>
+
+<dt> smtpd_client_connection_rate_limit (default: no limit) </dt>
+<dd> The maximum number of connections that an SMTP client may make
+in the time interval specified with anvil_rate_time_unit (default:
+60s). </dd>
+
+<dt> smtpd_client_message_rate_limit (default: no limit) </dt> <dd>
+The maximum number of message delivery requests that an SMTP client
+may make in the time interval specified with anvil_rate_time_unit
+(default: 60s). </dd>
+
+<dt> smtpd_client_recipient_rate_limit (default: no limit) </dt>
+<dd> The maximum number of recipient addresses that an SMTP client
+may specify in the time interval specified with anvil_rate_time_unit
+(default: 60s). </dd>
+
+<dt> smtpd_client_new_tls_session_rate_limit (default: no limit)
+</dt> <dd> The maximum number of new TLS sessions (without using
+the TLS session cache) that an SMTP client may negotiate in the
+time interval specified with anvil_rate_time_unit (default: 60s).
+</dd>
+
+<dt> smtpd_client_auth_rate_limit (default: no limit) </dt> <dd>
+The maximum number of AUTH commands that an SMTP client may send
+in the time interval specified with anvil_rate_time_unit (default:
+60s). Available in Postfix 3.1 and later. </dd>
+
+<dt> smtpd_client_event_limit_exceptions (default: $mynetworks)
+</dt> <dd> SMTP clients that are excluded from connection and rate
+limits specified above. </dd>
+
+</dl>
+
+</blockquote>
+
+<h2><a name="mailing_tips">General mail delivery performance tips</a></h2>
+
+<ul>
+
+<li> <p> Read and understand the maildrop queue, incoming queue,
+active queue and deferred queue discussions in the QSHAPE_README
+document. </p>
+
+<li> <p> In case of slow delivery, run the qshape tool as described
+in the QSHAPE_README document. </p>
+
+<li> <p> Submit multiple recipients per message instead of submitting
+messages with only a few recipients. </p>
+
+<li> <p> Submit mail via SMTP instead of /usr/sbin/sendmail. You
+may have to adjust the smtpd_recipient_limit parameter setting.
+</p>
+
+<li> <p> Don't overwhelm the disk with mail submissions. Optimize
+the mail submission rate by tuning the number of parallel submissions
+and/or by tuning the Postfix in_flow_delay parameter setting. </p>
+
+<li> <p> Run a local name server to reduce slow-down due to DNS
+lookups. If you run multiple Postfix systems, point each local name
+server to a shared forwarding server to reduce the number of lookups
+across the upstream network link. </p>
+
+<li> <p> Reduce the smtp_connect_timeout and smtp_helo_timeout
+values so that Postfix does not waste lots of time connecting
+to non-responding remote SMTP servers. </p>
+
+<li> <p> Use a dedicated mail delivery transport for problematic
+destinations, with reduced timeouts and with adjusted concurrency.
+See "<a href="#rope">Tuning the number of simultaneous deliveries</a>"
+below.
+</p>
+
+<li> <p> Use a fallback_relay host for mail that cannot be delivered
+upon the first attempt. This "graveyard" machine can use shorter
+retry times for difficult to reach destinations. See "<a
+href="#hammer">Tuning the frequency of deferred mail delivery
+attempts</a>" below. </p>
+
+<li> <p> Speed up disk updates with a large (64MB) persistent write
+cache. This allows disk updates to be sorted for optimal access
+speed without compromising file system integrity when the system
+crashes. </p>
+
+<li> <p> Use a solid-state disk (a persistent RAM disk). This
+is an expensive solution that should be used in combination
+with short SMTP timeouts and a fallback_relay "graveyard"
+machine that delivers mail for problem destinations. </p>
+
+</ul>
+
+<h2><a name="rope">Tuning the number of simultaneous deliveries</a></h2>
+
+<p> Although Postfix can be configured to run 1000 SMTP client
+processes at the same time, it is rarely desirable that it makes
+1000 simultaneous connections to the same remote system. For this
+reason, Postfix has safety mechanisms in place to avoid this
+so-called "thundering herd" problem. </p>
+
+<p> The Postfix queue manager implements the analog of the TCP slow
+start flow control strategy: when delivering to a site, send a
+small number of messages first, then increase the concurrency as
+long as all goes well; reduce concurrency in the face of congestion.
+</p>
+
+<ul>
+
+<li> <p> The initial_destination_concurrency parameter (default: 5)
+controls how many messages are initially sent to the same destination
+before adapting delivery concurrency. Of course, this setting is
+effective only as long as it does not exceed the process limit and
+the destination concurrency limit for the specific mail transport
+channel. </p>
+
+<li> <p> The default_destination_concurrency_limit parameter (default:
+20) controls how many messages may be sent to the same destination
+simultaneously. You can override this setting for specific message
+delivery transports by taking the name of the master.cf entry
+and appending "_destination_concurrency_limit". </p>
+
+</ul>
+
+<p> Examples of transport specific concurrency limits are: </p>
+
+<ul>
+
+<li> <p> The local_destination_concurrency_limit parameter (default:
+2) controls how many messages are delivered simultaneously to the
+same local recipient. The recommended limit is low because delivery
+to the same mailbox must happen sequentially, so massive parallelism
+is not useful. Another good reason to limit delivery concurrency
+to the same recipient: if the recipient has an expensive shell
+command in her .forward file, or if the recipient is a mailing list
+manager, you don't want to run too many instances of those processes
+at the same time. </p>
+
+<li> <p> The default smtp_destination_concurrency_limit of 20 seems
+enough to noticeably load a system without bringing it to its knees.
+Be careful when changing this to a much larger number. </p>
+
+</ul>
+
+<p> The above default values of the concurrency limits work well
+in a broad range of situations. Knee-jerk changes to these parameters
+in the face of congestion can actually make problems worse.
+Specifically, large destination concurrencies should never be the
+default. They should be used only for transports that deliver mail
+to a small number of high volume domains. </p>
+
+<p> A common situation where high concurrency is called for is on
+gateways relaying a high volume of mail between the Internet
+and an intranet mail environment. Approximately half the mail
+(assuming equal volumes inbound and outbound) will be destined
+for the internal mail hubs. Since the internal mail hubs will be
+receiving all external mail exclusively from the gateway, it is
+reasonable to configure the gateway to make greater demands on the
+capacity of the internal SMTP servers. </p>
+
+<p> The tuning of the inbound concurrency limits need not be trial
+and error. A high volume capable mailhub should be able to easily
+handle 50 or 100 (rather than the default 20) simultaneous connections,
+especially if the gateway forwards to multiple MX hosts. When all
+MX hosts are up and accepting connections in a timely fashion,
+throughput will be high. If any MX host is down and completely
+unresponsive, the average connection latency rises to at least 1/N
+* $smtp_connect_timeout, if there are N MX hosts. This limits
+throughput to at most the destination concurrency * N /
+$smtp_connect_timeout. </p>
+
+<p> For example, with a destination concurrency of 100 and 2 MX
+hosts, each host will handle up to 50 simultaneous connections. If
+one MX host is down and the default SMTP connection timeout is 30s,
+the throughput limit is 100 * 2 / 30 ~= 6 messages per second. This
+suggests that high volume destinations with good connectivity and
+multiple MX hosts need a lower connection timeout, values as low
+as 5s or even 1s can be used to prevent congestion when one or
+more, but not all MX hosts are down. </p>
+
+<p> If necessary, set a higher <i>transport</i>_destination_concurrency_limit
+(in main.cf since this is a queue manager parameter) and a lower
+smtp_connect_timeout (with a "-o" override in master.cf since
+this parameter has no per-transport name) for the relay transport
+and any transports dedicated for specific high volume destinations.
+</p>
+
+<h2><a name="rcpts">Tuning the number of recipients per delivery</a></h2>
+
+<p> The default_destination_recipient_limit parameter (default:
+50) controls how many recipients a Postfix delivery agent will send
+with each copy of an email message. You can override this setting
+for specific Postfix delivery agents. For example,
+"uucp_destination_recipient_limit = 100" would limit the number of
+recipients per UUCP delivery to 100. </p>
+
+<p> If an email message exceeds the recipient limit for some
+destination, the Postfix queue manager breaks up the list of
+recipients into smaller lists. Postfix will attempt to send multiple
+copies of the message in parallel. </p>
+
+<p> IMPORTANT: Be careful when increasing the recipient limit per
+message delivery; some SMTP servers abort the connection when they
+run out of memory or when a hard recipient limit is reached, so
+that the message will never be delivered. </p>
+
+<p> The smtpd_recipient_limit parameter (default: 1000) controls
+how many recipients the Postfix smtpd(8) server will take per
+delivery. The default limit is more than any reasonable SMTP client
+would send. The limit exists to protect the local mail system
+against a run-away client. </p>
+
+<h2><a name="hammer">Tuning the frequency of deferred mail delivery attempts</a></h2>
+
+<p> When a Postfix delivery agent (smtp(8), local(8), etc.) is
+unable to deliver a message it may blame the message itself, or it
+may blame the receiving party. </p>
+
+<ul>
+
+<li> <p> When the delivery agent blames the message, the queue
+manager gives the queue file a time stamp into the future, so it
+won't be looked at for a while. By default, the amount of time to
+cool down is the amount of time that has passed since the message
+arrived. This results in so-called exponential backoff behavior.
+</p>
+
+<li> <p> When the delivery agent blames the receiving party (for
+example a local recipient user, or a remote host), the queue manager
+not only advances the queue file time stamp, but also puts the
+receiving party on a "dead" list so that it will be skipped for
+some amount of time. </p>
+
+</ul>
+
+<p> This process is governed by a bunch of little parameters. </p>
+
+<blockquote>
+
+<dl>
+
+<dt> queue_run_delay (default: 300 seconds; before Postfix 2.4:
+1000s) </dt> <dd> How often
+the queue manager scans the queue for deferred mail. </dd>
+
+<dt> minimal_backoff_time (default: 300 seconds; before Postfix
+2.4: 1000s) </dt> <dd> The
+minimal amount of time a message won't be looked at, and the minimal
+amount of time to stay away from a "dead" destination. </dd>
+
+<dt> maximal_backoff_time (default: 4000 seconds) </dt> <dd> The
+maximal amount of time a message won't be looked at after a delivery
+failure. </dd>
+
+<dt> maximal_queue_lifetime (default: 5 days) </dt> <dd> How long
+a message stays in the queue before it is sent back as undeliverable.
+Specify 0 for mail that should be returned immediately after the
+first unsuccessful delivery attempt. </dd>
+
+<dt> bounce_queue_lifetime (default: 5 days, available with Postfix
+version 2.1 and later) </dt> <dd> How long a MAILER-DAEMON message
+stays in the queue before it is considered undeliverable. Specify
+0 for mail that should be tried only once. </dd>
+
+<dt> qmgr_message_recipient_limit (default: 20000) </dt> <dd> The
+size of many in-memory queue manager data structures. Among others,
+this parameter limits the size of the short-term, in-memory list
+of "dead" destinations. Destinations that don't fit the list are
+not added. </dd>
+
+<dt> <i>transport</i>_destination_concurrency_failed_cohort_limit
+</dt> <dd> Controls when a destination is considered "dead". This
+parameter is critical with a non-zero
+<i>transport</i>_destination_rate_delay, with a reduced
+<i>transport</i>_destination_concurrency_limit, or with
+a reduced initial_destination_concurrency. </dd>
+
+</dl>
+
+</blockquote>
+
+<p> IMPORTANT: If you increase the frequency of deferred mail
+delivery attempts, or if you flush the deferred mail queue frequently,
+then you may find that Postfix mail delivery performance actually
+becomes worse. The symptoms are as follows: </p>
+
+<ul>
+
+<li> <p> The active queue becomes saturated with mail that has
+delivery problems. New mail enters the active queue only when
+an old message is deferred. This is a slow process that usually
+requires timing out one or more SMTP connections. </p>
+
+<li> <p> All available Postfix delivery agents become occupied
+trying to connect to unreachable sites etc. New mail has to wait
+until a delivery agent becomes available. This is a slow process
+that usually requires timing out one or more SMTP connections. </p>
+
+</ul>
+
+<p> When mail is being deferred frequently, fixing the problem is
+always better than increasing the frequency of delivery attempts.
+However, if you can control only the delivery attempt frequency,
+consider using a dedicated fallback_relay "graveyard" machine for
+bad destinations, so that these destinations do not ruin the
+performance of normal
+mail deliveries. </p>
+
+<h2><a name="proc_limit">Tuning the number of Postfix processes</a></h2>
+
+<p> The default_process_limit configuration parameter gives direct
+control over how many daemon processes Postfix will run. As of
+Postfix 2.0 the default limit is 100 SMTP client processes, 100
+SMTP server processes, and so on. This may overwhelm systems with
+little memory, as well as networks with low bandwidth. </p>
+
+<p> You can change the global process limit by specifying a
+non-default default_process_limit in the main.cf file. For example,
+to run up to 10 SMTP client processes, 10 SMTP server processes,
+and so on: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ default_process_limit = 10
+</pre>
+</blockquote>
+
+<p> You need to execute "postfix reload" to make the change effective.
+This limit is enforced by the Postfix master(8) daemon which does
+not automatically read main.cf when it changes. </p>
+
+<p> You can override the process limit for specific Postfix daemons
+by editing the master.cf file. For example, if you do not wish to
+receive 100 SMTP messages at the same time, but do not want to
+change the process limits for other Postfix daemons, you could
+specify: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ # ====================================================================
+ # service type private unpriv chroot wakeup maxproc command + args
+ # (yes) (yes) (yes) (never) (100)
+ # ====================================================================
+ . . .
+ smtp inet n - - - 10 smtpd
+ . . .
+</pre>
+</blockquote>
+
+<h2><a name="proc_sys">Tuning the number of processes on the system</a></h2>
+
+<ul>
+
+<li> <p> MacOS X will run out of process slots when you increase
+Postfix process limits. The following works with OSX 10.4 and OSX
+10.5. </p>
+
+<p> MacOS X kernel parameters can be specified in /etc/sysctl.conf.
+</p>
+
+<pre>
+/etc/sysctl.conf:
+ kern.maxproc=2048
+ kern.maxprocperuid=2048
+</pre>
+
+<p> Unfortunately these can't simply be set on the fly with "sysctl
+-w". You also have to set the following in /etc/launchd.conf so
+that the root user after boot will have the right process limit
+(2048). Otherwise you have to always run ulimit -u 2048 as root,
+then start a user shell, and then start processes for things to
+take effect. </p>
+
+<pre>
+/etc/launchd.conf:
+ limit maxproc 2048
+</pre>
+
+<p> Once these are in place, reboot the system. After that, the limits will
+stay in place. </p>
+
+</ul>
+
+<h2><a name="file_limit">Tuning the number of open files or sockets</a></h2>
+
+<p> When Postfix opens too many files or sockets, processes will
+abort with fatal errors, and the system may log "file table full"
+errors. </p>
+
+<ul>
+
+<li> <p> Depending on your Postfix and operating system versions
+you may need to recompile Postfix if you need more than 1024 file
+descriptors per process: </p>
+
+<ul> <li> <p> No recompilation is needed for Postfix version 2.4
+and later, when it was compiled for systems that support BSD kqueue(2)
+(FreeBSD 4.1, NetBSD 2.0, OpenBSD 2.9), Solaris 8 /dev/poll, or
+Linux 2.6 epoll(4). </p>
+
+<li> <p> Otherwise, Postfix needs to be recompiled to override the
+default FD_SETSIZE value. </p>
+
+</ul>
+
+<li> <p> Reduce the number of processes as described under "<a
+href="#proc_limit">Tuning the number of Postfix processes</a>" above.
+Fewer processes need fewer open files and sockets. </p>
+
+<li> <p> Configure the kernel for more open files and sockets.
+The details are extremely system dependent and change with the
+operating system version. Be sure to verify the following information
+with your system tuning guide: </p>
+
+<ul>
+
+<li> <p> Some FreeBSD kernel parameters can be specified in
+/boot/loader.conf, and some can be specified in /etc/sysctl.conf
+or changed with sysctl commands.
+Which is which depends on the version.
+</p>
+
+<pre>
+kern.ipc.maxsockets="5000"
+kern.ipc.nmbclusters="65536"
+kern.maxproc="2048"
+kern.maxfiles="16384"
+kern.maxfilesperproc="16384"
+</pre>
+
+<li> <p> Linux kernel parameters can be specified in /etc/sysctl.conf
+or changed with sysctl commands: </p>
+
+<pre>
+fs.file-max=16384
+kernel.threads-max=2048
+</pre>
+
+<li> <p> Solaris kernel parameters can be specified in /etc/system,
+as described in the <a
+href="http://www.science.uva.nl/pub/solaris/solaris2.html#q3.48">Solaris
+FAQ</a> entry titled "How can I increase the number of file
+descriptors per process?" </p>
+
+<pre>
+* set hard limit on file descriptors
+set rlim_fd_max = 4096
+* set soft limit on file descriptors
+set rlim_fd_cur = 1024
+</pre>
+
+</ul>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/UUCP_README.html b/proto/UUCP_README.html
new file mode 100644
index 0000000..e677a77
--- /dev/null
+++ b/proto/UUCP_README.html
@@ -0,0 +1,200 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix and UUCP </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix and UUCP </h1>
+
+<hr>
+
+<h2><a name="uucp-tcp">Using UUCP over TCP</a></h2>
+
+<p> Despite a serious lack of sex-appeal, email via UUCP over TCP
+is a practical option for sites without permanent Internet connections,
+and for sites without a fixed IP address. For first-hand information,
+see the following guides: </p>
+
+<ul>
+
+<li> Jim Seymour's guide for using UUCP over TCP at
+http://jimsun.LinxNet.com/jdp/uucp_over_tcp/index.html,
+
+<li> Craig Sanders's guide for SSL-encrypted UUCP over TCP
+using stunnel at http://taz.net.au/postfix/uucp/.
+
+</ul>
+
+Here's a graphical description of what this document is about:
+
+<blockquote>
+
+<table>
+
+<tr> <td> Local network <tt> &lt;---&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center"><a href="#lan-uucp">LAN to<br>
+UUCP<br> Gateway</a></td>
+
+<td> <tt> &lt;--- </tt> UUCP <tt> ---&gt; </tt> </td>
+
+<td bgcolor="#f0f0ff" align="center"><a href="#internet-uucp">Internet<br>
+to UUCP<br> Gateway</a></td>
+
+<td> <tt> &lt;---&gt; </tt> Internet </td> </tr>
+
+</table>
+
+</blockquote>
+
+<p> And here's the table of contents of this document: </p>
+
+<ul>
+
+<li><a href="#internet-uucp">Setting up a Postfix Internet to UUCP
+gateway</a>
+
+<li><a href="#lan-uucp">Setting up a Postfix LAN to UUCP
+gateway</a>
+
+</ul>
+
+<h2><a name="internet-uucp">Setting up a Postfix Internet to UUCP
+gateway</a></h2>
+
+<p> Here is how to set up a machine that sits on the Internet and
+that forwards mail to a LAN that is connected via UUCP. See
+the <a href="#lan-uucp">LAN to UUCP gateway</a> section for
+the other side of the story. </p>
+
+<ul>
+
+<li> <p> You need an <b>rmail</b> program that extracts the sender
+address from mail that arrives via UUCP, and that feeds the mail
+into the Postfix <b>sendmail</b> command. Most UNIX systems come
+with an <b>rmail</b> utility. If you're in a pinch, try the one
+bundled with the Postfix source code in the <b>auxiliary/rmail</b>
+directory. </p>
+
+<li> <p> Define a pipe(8) based mail delivery transport for delivery
+via UUCP: </p>
+
+<pre>
+/etc/postfix/master.cf:
+ uucp unix - n n - - pipe
+ flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
+</pre>
+
+<p> This runs the <b>uux</b> command to place outgoing mail into
+the UUCP queue after replacing $nexthop by the next-hop hostname
+(the receiving UUCP host) and after replacing $recipient by the
+recipients. The pipe(8) delivery agent executes the <b>uux</b>
+command without assistance from the shell, so there are no problems
+with shell meta characters in command-line parameters. </p>
+
+<li> <p> Specify that mail for <i>example.com</i>, should be
+delivered via UUCP, to a host named <i>uucp-host</i>: </p>
+
+<pre>
+/etc/postfix/transport:
+ example.com uucp:uucp-host
+ .example.com uucp:uucp-host
+</pre>
+
+<p> See the transport(5) manual page for more details. </p>
+
+<li> <p> Execute the command "<b>postmap /etc/postfix/transport</b>"
+whenever you change the <b>transport</b> file. </p>
+
+<li> <p> Enable <b>transport</b> table lookups: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+</pre>
+
+<p> Specify <b>dbm</b> instead of <b>hash</b> if your system uses
+<b>dbm</b> files instead of <b>db</b> files. To find out what map
+types Postfix supports, use the command "<b>postconf -m</b>". </p>
+
+<li> <p> Add <i>example.com</i> to the list of domains that your site
+is willing to relay mail for. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ relay_domains = example.com ...<i>other relay domains</i>...
+</pre>
+
+<p> See the relay_domains configuration parameter description for
+details. </p>
+
+<li> <p> Execute the command "<b>postfix reload</b>" to make the
+changes effective. </p>
+
+</ul>
+
+<h2><a name="lan-uucp">Setting up a Postfix LAN to UUCP
+gateway</a></h2>
+
+<p> Here is how to relay mail from a LAN via UUCP to the
+Internet. See the <a href="#internet-uucp">Internet to UUCP
+gateway</a> section for the other side of the story. </p>
+
+<ul>
+
+<li> <p> You need an <b>rmail</b> program that extracts the sender
+address from mail that arrives via UUCP, and that feeds the mail
+into the Postfix <b>sendmail</b> command. Most UNIX systems come
+with an <b>rmail</b> utility. If you're in a pinch, try the one
+bundled with the Postfix source code in the <b>auxiliary/rmail</b>
+directory. </p>
+
+<li> <p> Specify that all remote mail must be sent via the <b>uucp</b>
+mail transport to your UUCP gateway host, say, <i>uucp-gateway</i>: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ relayhost = uucp-gateway
+ default_transport = uucp
+</pre>
+
+<p> Postfix 2.0 and later also allows the following more succinct form: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ default_transport = uucp:uucp-gateway
+</pre>
+
+<li> <p> Define a pipe(8) based message delivery transport for mail
+delivery via UUCP: </p>
+
+<pre>
+/etc/postfix/master.cf:
+ uucp unix - n n - - pipe
+ flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
+</pre>
+
+<p> This runs the <b>uux</b> command to place outgoing mail into
+the UUCP queue. It substitutes the next-hop hostname (<i>uucp-gateway</i>,
+or whatever you specified) and the recipients before executing the
+command. The <b>uux</b> command is executed without assistance
+from the shell, so there are no problems with shell meta characters.
+</p>
+
+<li> <p> Execute the command "<b>postfix reload</b>" to make the
+changes effective. </p>
+
+</ul>
+
+</body>
+
+</html>
diff --git a/proto/VERP_README.html b/proto/VERP_README.html
new file mode 100644
index 0000000..e442c89
--- /dev/null
+++ b/proto/VERP_README.html
@@ -0,0 +1,289 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix VERP Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix VERP Howto</h1>
+
+<hr>
+
+<h2>Postfix VERP support</h2>
+
+<p> Postfix versions 1.1 and later support variable envelope return
+path addresses on request. When VERP style delivery is requested,
+each recipient of a message receives a customized copy of the
+message, with his/her own recipient address encoded in the envelope
+sender address. </p>
+
+<p> For example, when VERP style delivery is requested, Postfix
+delivers mail from "<tt>owner-listname@origin</tt>" for a recipient
+"<tt>user@domain</tt>", with a sender address that encodes the
+recipient as follows: </p>
+
+<blockquote>
+<pre>
+owner-listname+user=domain@origin
+</pre>
+</blockquote>
+
+<p> Thus, undeliverable mail can reveal the undeliverable recipient
+address without requiring the list owner to parse bounce messages.
+</p>
+
+<p> The VERP concept was popularized by the qmail MTA and by the ezmlm
+mailing list manager. See http://cr.yp.to/proto/verp.txt for the
+ideas behind this concept. </p>
+
+<p> Topics covered in this document: </p>
+
+<ul>
+
+<li> <a href="#config"> Postfix VERP configuration parameters </a>
+
+<li> <a href="#majordomo"> Using VERP with majordomo etc. mailing lists </a>
+
+<li> <a href="#smtp"> VERP support in the Postfix SMTP server</a>
+
+<li> <a href="#sendmail"> VERP support in the Postfix sendmail command </a>
+
+<li> <a href="#qmqp"> VERP support in the Postfix QMQP server </a>
+
+</ul>
+
+<h2> <a name="config"> Postfix VERP configuration parameters </a> </h2>
+
+With Postfix, the whole process is controlled by four configuration
+parameters.
+
+<dl>
+
+<dt> default_verp_delimiters (default value: +=)
+
+ <dd> <p> What VERP delimiter characters Postfix uses when VERP
+ style delivery is requested but no explicit delimiters are
+ specified. </p>
+
+<dt> verp_delimiter_filter (default: -+=)
+
+ <dd> <p> What characters Postfix accepts as VERP delimiter
+ characters on the sendmail command line and in SMTP commands.
+ Many characters must not be used as VERP delimiter characters,
+ either because they already have a special meaning in email
+ addresses (such as the @ or the %), because they are used as
+ part of a username or domain name (such as alphanumerics), or
+ because they are non-ASCII or control characters. And who
+ knows, some characters may tickle bugs in vulnerable software,
+ and we would not want that to happen. </p> </dd>
+
+<dt> smtpd_authorized_verp_clients (default value: none)
+
+ <dd> <p> What SMTP clients are allowed to request VERP style
+ delivery. The Postfix QMQP server uses its own access control
+ mechanism, and local submission (via /usr/sbin/sendmail etc.)
+ is always authorized. To authorize a host, list its name, IP
+ address, subnet (net/mask) or parent .domain. </p>
+
+ <p> With Postfix versions 1.1 and 2.0, this parameter is called
+ authorized_verp_clients (default: $mynetworks). </p> </dd>
+
+<dt> disable_verp_bounces (default: no)
+
+ <dd> <p> Send one bounce report for multi-recipient VERP mail,
+ instead of one bounce report per recipient. The default,
+ one per recipient, is what ezmlm needs. </p> </dd>
+
+</dl>
+
+<h2> <a name="majordomo"> Using VERP with majordomo etc. mailing lists </a> </h2>
+
+<p> In order to make VERP useful with majordomo etc. mailing lists,
+you would configure the list manager to submit mail according
+to one of the following two forms: </p>
+
+<p> Postfix 2.3 and later: </p>
+
+<blockquote>
+<pre>
+% sendmail -XV -f owner-listname other-arguments...
+
+% sendmail -XV+= -f owner-listname other-arguments...
+</pre>
+</blockquote>
+
+<p> Postfix 2.2 and earlier (Postfix 2.3 understands the old syntax
+for backwards compatibility, but will log a warning that reminds
+you of the new syntax): </p>
+
+<blockquote>
+<pre>
+% sendmail -V -f owner-listname other-arguments...
+
+% sendmail -V+= -f owner-listname other-arguments...
+</pre>
+</blockquote>
+
+<p> The first form uses the default main.cf VERP delimiter characters.
+The second form allows you to explicitly specify the VERP delimiter
+characters. The example shows the recommended values. </p>
+
+<p> This text assumes that you have set up an owner-listname alias
+that routes undeliverable mail to a real person: </p>
+
+<blockquote>
+<pre>
+/etc/aliases:
+ owner-listname: yourname+listname
+</pre>
+</blockquote>
+
+<p> In order to process bounces we are going to make extensive use
+of address extension tricks. </p>
+
+<p> You need to tell Postfix that + is the separator between an
+address and its optional address extension, that address extensions
+are appended to .forward file names, and that address extensions
+are to be discarded when doing alias expansions: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ recipient_delimiter = +
+ forward_path = $home/.forward${recipient_delimiter}${extension},
+ $home/.forward
+ propagate_unmatched_extensions = canonical, virtual
+</pre>
+</blockquote>
+
+<p> (the last two parameter settings are default settings). </p>
+
+<p> You need to set up a file named .forward+listname with the
+commands that process all the mail that is sent to the owner-listname
+address: </p>
+
+<blockquote>
+<pre>
+~/.forward+listname:
+ "|/some/where/command ..."
+</pre>
+</blockquote>
+
+<p> With this set up, undeliverable mail for user@domain will be returned
+to the following address: </p>
+
+<blockquote>
+<pre>
+owner-listname+user=domain@your.domain
+</pre>
+</blockquote>
+
+<p> which is processed by the command in your .forward+listname file.
+The message should contain, among others, a To: header with the
+encapsulated recipient sender address: </p>
+
+<blockquote>
+<pre>
+To: owner-listname+user=domain@your.domain
+</pre>
+</blockquote>
+
+<p> It is left as an exercise for the reader to parse the To: header
+line and to pull out the user=domain part from the recipient address.
+</p>
+
+<h2> <a name="smtp"> VERP support in the Postfix SMTP server </a> </h2>
+
+<p> The Postfix SMTP server implements a command XVERP to enable
+VERP style delivery. The syntax allows two forms: </p>
+
+<blockquote>
+<pre>
+MAIL FROM:&lt;sender@domain&gt; XVERP
+
+MAIL FROM:&lt;sender@domain&gt; XVERP=+=
+</pre>
+</blockquote>
+
+<p> The first form uses the default main.cf VERP delimiters, the
+second form overrides them explicitly. The values shown are the
+recommended ones. </p>
+
+<p> You can use the smtpd_command_filter feature to append XVERP
+to SMTP commands from legacy software. This requires Postfix 2.7
+or later. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_command_filter = pcre:/etc/postfix/append_verp.pcre
+ smtpd_authorized_verp_clients = $mynetworks
+
+/etc/postfix/append_verp.pcre:
+ /^(MAIL FROM:&lt;listname@example\.com&gt;.*)/ $1 XVERP
+</pre>
+</blockquote>
+
+<h2> <a name="sendmail"> VERP support in the Postfix sendmail command </a> </h2>
+
+<p> The Postfix sendmail command has a -V flag to request VERP style
+delivery. Specify one of the following two forms: </p>
+
+<p> Postfix 2.3 and later:</p>
+<blockquote>
+<pre>
+% sendmail -XV -f owner-listname ....
+
+% sendmail -XV+= -f owner-listname ....
+</pre>
+</blockquote>
+
+<p> Postfix 2.2 and earlier (Postfix 2.3 understands the old syntax
+for backwards compatibility, but will log a warning that reminds
+you of the new syntax): </p>
+
+<blockquote>
+<pre>
+% sendmail -V -f owner-listname ....
+
+% sendmail -V+= -f owner-listname ....
+</pre>
+</blockquote>
+
+<p> The first form uses the default main.cf VERP delimiters, the
+second form overrides them explicitly. The values shown are the
+recommended ones. </p>
+
+<h2> <a name="qmqp"> VERP support in the Postfix QMQP server </a> </h2>
+
+<p> When the Postfix QMQP server receives mail with an envelope
+sender address of the form: </p>
+
+<blockquote>
+<pre>
+listname-@your.domain-@[]
+</pre>
+</blockquote>
+
+<p> Postfix generates sender addresses
+"<tt>listname-user=domain@your.domain</tt>", using "-=" as the VERP
+delimiters because qmail/ezmlm expect this. </p>
+
+<p> More generally, a sender address of "<tt>prefix@origin-@[]</tt>"
+requests VERP style delivery with sender addresses of the form
+"<tt>prefixuser=domain@origin</tt>". However, Postfix allows only
+VERP delimiters that are specified with the verp_delimiter_filter
+parameter. In particular, the "=" delimiter is required for qmail
+compatibility (see the qmail addresses(5) manual page for details).
+
+</body>
+
+</html>
diff --git a/proto/VIRTUAL_README.html b/proto/VIRTUAL_README.html
new file mode 100644
index 0000000..1c5aecc
--- /dev/null
+++ b/proto/VIRTUAL_README.html
@@ -0,0 +1,648 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Virtual Domain Hosting Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
+Virtual Domain Hosting Howto</h1>
+
+<hr>
+
+<h2>Purpose of this document</h2>
+
+<p> This document requires Postfix version 2.0 or later. </p>
+
+<p> This document gives an overview of how Postfix can be used for
+hosting multiple Internet domains, both for final delivery on the
+machine itself and for the purpose of forwarding to destinations
+elsewhere. </p>
+
+<p> The text not only describes delivery mechanisms that are built
+into Postfix, but also gives pointers for using non-Postfix mail
+delivery software. </p>
+
+<p> The following topics are covered: </p>
+
+<ul>
+
+<li> <a href="#canonical">Canonical versus hosted versus other domains</a>
+
+<li> <a href="#local_vs_database">Local files versus network databases</a>
+
+<li> <a href="#local">As simple as can be: shared domains,
+UNIX system accounts</a>
+
+<li> <a href="#virtual_alias">Postfix virtual ALIAS example:
+separate domains, UNIX system accounts</a>
+
+<li> <a href="#virtual_mailbox">Postfix virtual MAILBOX example:
+separate domains, non-UNIX accounts</a>
+
+<li> <a href="#in_virtual_other">Non-Postfix mailbox store: separate
+domains, non-UNIX accounts</a>
+
+<li> <a href="#forwarding">Mail forwarding domains</a>
+
+<li> <a href="#mailing_lists">Mailing lists</a>
+
+<li> <a href="#autoreplies">Autoreplies</a>
+
+</ul>
+
+<h2><a name="canonical">Canonical versus hosted versus
+other domains</a></h2>
+
+<p>Most Postfix systems are the <b>final destination</b> for only a
+few domain names. These include the hostnames and [the IP addresses]
+of the machine that Postfix runs on, and sometimes also include
+the parent domain of the hostname. The remainder of this document
+will refer to these domains as the canonical domains. They are
+usually implemented with the Postfix local domain address class,
+as defined in the ADDRESS_CLASS_README file.</p>
+
+<p> Besides the canonical domains, Postfix can be configured to be
+the <b>final destination</b> for any number of additional domains.
+These domains are called hosted, because they are not directly
+associated with the name of the machine itself. Hosted domains are
+usually implemented with the virtual alias domain address class
+and/or with the virtual mailbox domain address class, as defined
+in the ADDRESS_CLASS_README file. </p>
+
+<p> But wait! There is more. Postfix can be configured as a backup
+MX host for other domains. In this case Postfix is <b>not the final
+destination</b> for those domains. It merely queues the mail when
+the primary MX host is down, and forwards the mail when the primary
+MX host becomes available. This function is implemented with the
+relay domain address class, as defined in the ADDRESS_CLASS_README
+file. </p>
+
+<p> Finally, Postfix can be configured as a transit host for sending
+mail across the internet. Obviously, Postfix is not the final destination
+for such mail. This function is available only for authorized
+clients and/or users, and is implemented by the default domain
+address class, as defined in the ADDRESS_CLASS_README file. </p>
+
+<h2><a name="local_vs_database">Local files versus network databases</a></h2>
+
+<p> The examples in this text use table lookups from local files
+such as DBM or Berkeley DB. These are easy to debug with the
+<b>postmap</b> command: </p>
+
+<blockquote>
+Example: <tt>postmap -q info@example.com hash:/etc/postfix/virtual</tt>
+</blockquote>
+
+<p> See the documentation in LDAP_README, MYSQL_README and PGSQL_README
+for how to replace local files by databases. The reader is strongly
+advised to make the system work with local files before migrating
+to network databases, and to use the <b>postmap</b> command to verify
+that network database lookups produce the exact same results as
+local file lookup. </p>
+
+<blockquote>
+Example: <tt>postmap -q info@example.com ldap:/etc/postfix/virtual.cf</tt>
+</blockquote>
+
+<h2><a name="local">As simple as can be: shared domains, UNIX system
+accounts</a></h2>
+
+<p> The simplest method to host an additional domain is to add the
+domain name to the domains listed in the Postfix mydestination
+configuration parameter, and to add the user names to the UNIX
+password file. </p>
+
+<p> This approach makes no distinction between canonical and hosted
+domains. Each username can receive mail in every domain. </p>
+
+<p> In the examples we will use "example.com" as the domain that is
+being hosted on the local Postfix machine. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ mydestination = $myhostname localhost.$mydomain ... example.com
+</pre>
+</blockquote>
+
+<p> The limitations of this approach are: </p>
+
+<ul>
+
+<li>A total lack of separation: mail for info@my.host.name is
+delivered to the same UNIX system account as mail for info@example.com.
+
+<li> With users in the UNIX password file, administration of large
+numbers of users becomes inconvenient.
+
+</ul>
+
+<p> The examples that follow provide solutions for both limitations.
+</p>
+
+<h2><a name="virtual_alias">Postfix virtual ALIAS example:
+separate domains, UNIX system accounts</a></h2>
+
+<p> With the approach described in this section, every hosted domain
+can have its own info etc. email address. However, it still uses
+UNIX system accounts for local mailbox deliveries. </p>
+
+<p> With virtual alias domains, each hosted address is aliased to
+a local UNIX system account or to a remote address. The example
+below shows how to use this mechanism for the example.com domain.
+</p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 virtual_alias_domains = example.com ...other hosted domains...
+ 3 virtual_alias_maps = hash:/etc/postfix/virtual
+ 4
+ 5 /etc/postfix/virtual:
+ 6 postmaster@example.com postmaster
+ 7 info@example.com joe
+ 8 sales@example.com jane
+ 9 # Uncomment entry below to implement a catch-all address
+10 # @example.com jim
+11 ...virtual aliases for more domains...
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Line 2: the virtual_alias_domains setting tells Postfix
+that example.com is a so-called virtual alias domain. If you omit
+this setting then Postfix will reject mail (relay access denied)
+or will not be able to deliver it (mail for example.com loops back
+to myself). </p>
+
+<p> NEVER list a virtual alias domain name as a mydestination
+domain! </p>
+
+<li> <p> Lines 3-8: the /etc/postfix/virtual file contains the virtual
+aliases. With the example above, mail for postmaster@example.com
+goes to the local postmaster, while mail for info@example.com goes
+to the UNIX account joe, and mail for sales@example.com goes to
+the UNIX account jane. Mail for all other addresses in example.com
+is rejected with the error message "User unknown". </p>
+
+<li> <p> Line 10: the commented out entry (text after #) shows how
+one would implement a catch-all virtual alias that receives mail
+for every example.com address not listed in the virtual alias file.
+This is not without risk. Spammers nowadays try to send mail from
+(or mail to) every possible name that they can think of. A catch-all
+mailbox is likely to receive many spam messages, and many bounces
+for spam messages that were sent in the name of anything@example.com.
+</p>
+
+</ul>
+
+<p>Execute the command "<b>postmap /etc/postfix/virtual</b>" after
+changing the virtual file, and execute the command "<b>postfix
+reload</b>" after changing the main.cf file. </p>
+
+<p> Note: virtual aliases can resolve to a local address or to a
+remote address, or both. They don't have to resolve to UNIX system
+accounts on your machine. </p>
+
+<p> More details about the virtual alias file are given in the
+virtual(5) manual page, including multiple addresses on the right-hand
+side. </p>
+
+<p> Virtual aliasing solves one problem: it allows each domain to
+have its own info mail address. But there still is one drawback:
+each virtual address is aliased to a UNIX system account. As you
+add more virtual addresses you also add more UNIX system accounts.
+The next section eliminates this problem. </p>
+
+<h2><a name="virtual_mailbox">Postfix virtual MAILBOX example:
+separate domains, non-UNIX accounts</a></h2>
+
+<p> As a system hosts more and more domains and users, it becomes less
+desirable to give every user their own UNIX system account.</p>
+
+<p> With the Postfix virtual(8) mailbox delivery agent, every
+recipient address can have its own virtual mailbox. Unlike virtual
+alias domains, virtual mailbox domains do not need the clumsy
+translation from each recipient addresses into a different address,
+and owners of a virtual mailbox address do not need to have a UNIX
+system account.</p>
+
+<p> The Postfix virtual(8) mailbox delivery agent looks up the user
+mailbox pathname, uid and gid via separate tables that are searched
+with the recipient's mail address. Maildir style delivery is turned
+on by terminating the mailbox pathname with "/".</p>
+
+<p> If you find the idea of multiple tables bothersome, remember
+that you can migrate the information (once it works), to an SQL
+database. If you take that route, be sure to review the <a
+href="#local_vs_database"> "local files versus databases"</a>
+section at the top of this document.</p>
+
+<p> Here is an example of a virtual mailbox domain "example.com":
+</p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 virtual_mailbox_domains = example.com ...more domains...
+ 3 virtual_mailbox_base = /var/mail/vhosts
+ 4 virtual_mailbox_maps = hash:/etc/postfix/vmailbox
+ 5 virtual_minimum_uid = 100
+ 6 virtual_uid_maps = static:5000
+ 7 virtual_gid_maps = static:5000
+ 8 virtual_alias_maps = hash:/etc/postfix/virtual
+ 9
+10 /etc/postfix/vmailbox:
+11 info@example.com example.com/info
+12 sales@example.com example.com/sales/
+13 # Comment out the entry below to implement a catch-all.
+14 # @example.com example.com/catchall
+15 ...virtual mailboxes for more domains...
+16
+17 /etc/postfix/virtual:
+18 postmaster@example.com postmaster
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Line 2: The virtual_mailbox_domains setting tells Postfix
+that example.com is a so-called virtual mailbox domain. If you omit
+this setting then Postfix will reject mail (relay access denied)
+or will not be able to deliver it (mail for example.com loops back
+to myself). </p>
+
+<p> NEVER list a virtual MAILBOX domain name as a mydestination
+domain! </p>
+
+<p> NEVER list a virtual MAILBOX domain name as a virtual ALIAS
+domain! </p>
+
+<li> <p> Line 3: The virtual_mailbox_base parameter specifies a
+prefix for all virtual mailbox pathnames. This is a safety mechanism
+in case someone makes a mistake. It prevents mail from being
+delivered all over the file system. </p>
+
+<li> <p> Lines 4, 10-15: The virtual_mailbox_maps parameter specifies
+the lookup table with mailbox (or maildir) pathnames, indexed by
+the virtual mail address. In this example, mail for info@example.com
+goes to the mailbox at /var/mail/vhosts/example.com/info while mail
+for sales@example.com goes to the maildir located at
+/var/mail/vhosts/example.com/sales/. </p>
+
+<li> <p> Line 5: The virtual_minimum_uid specifies a lower bound
+on the mailbox or maildir owner's UID. This is a safety mechanism
+in case someone makes a mistake. It prevents mail from being written
+to sensitive files. </p>
+
+<li> <p> Lines 6, 7: The virtual_uid_maps and virtual_gid_maps
+parameters specify that all the virtual mailboxes are owned by a
+fixed uid and gid 5000. If this is not what you want, specify
+lookup tables that are searched by the recipient's mail address.
+</p>
+
+<li> <p> Line 14: The commented out entry (text after #) shows how
+one would implement a catch-all virtual mailbox address. Be prepared
+to receive a lot of spam, as well as bounced spam that was sent in
+the name of anything@example.com. </p>
+
+<p> NEVER put a virtual MAILBOX wild-card in the virtual ALIAS
+file!! </p>
+
+<li> <p> Lines 8, 17, 18: As you see, it is possible to mix virtual
+aliases with virtual mailboxes. We use this feature to redirect
+mail for example.com's postmaster address to the local postmaster.
+You can use the same mechanism to redirect an address to a remote
+address. </p>
+
+<li> <p> Line 18: This example assumes that in main.cf, $myorigin
+is listed under the mydestination parameter setting. If that is
+not the case, specify an explicit domain name on the right-hand
+side of the virtual alias table entries or else mail will go to
+the wrong domain. </p>
+
+</ul>
+
+<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
+changing the virtual file, execute "<b>postmap /etc/postfix/vmailbox</b>"
+after changing the vmailbox file, and execute the command "<b>postfix
+reload</b>" after changing the main.cf file. </p>
+
+<p> Note: mail delivery happens with the recipient's UID/GID
+privileges specified with virtual_uid_maps and virtual_gid_maps.
+Postfix 2.0 and earlier will not create mailDIRs in world-writable
+parent directories; you must create them in advance before you can
+use them. Postfix may be able to create mailBOX files by itself,
+depending on parent directory write permissions, but it is safer
+to create mailBOX files ahead of time. </p>
+
+<p> More details about the virtual mailbox delivery agent are given
+in the virtual(8) manual page. </p>
+
+<h2><a name="in_virtual_other">Non-Postfix mailbox store: separate
+domains, non-UNIX accounts</a></h2>
+
+<p> This is a variation on the Postfix virtual mailbox example.
+Again, every hosted address can have its own mailbox. However, most
+parameters that control the virtual(8) delivery agent are no longer
+applicable: only virtual_mailbox_domains and virtual_mailbox_maps
+stay in effect. These parameters are needed to reject mail for
+unknown recipients. </p>
+
+<p> While non-Postfix software is being used for final delivery,
+some Postfix concepts are still needed in order to glue everything
+together. For additional background on this glue you may want to
+take a look at the virtual mailbox domain class as defined in the
+ADDRESS_CLASS_README file. </p>
+
+<p> The text in this section describes what things should look like
+from Postfix's point of view. See CYRUS_README or MAILDROP_README
+for specific information about Cyrus or about Courier maildrop.
+</p>
+
+<p> Here is an example for a hosted domain example.com that delivers
+to a non-Postfix delivery agent: </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 virtual_transport = ...see below...
+ 3 virtual_mailbox_domains = example.com ...more domains...
+ 4 virtual_mailbox_maps = hash:/etc/postfix/vmailbox
+ 5 virtual_alias_maps = hash:/etc/postfix/virtual
+ 6
+ 7 /etc/postfix/vmailbox:
+ 8 info@example.com whatever
+ 9 sales@example.com whatever
+10 # Comment out the entry below to implement a catch-all.
+11 # Configure the mailbox store to accept all addresses.
+12 # @example.com whatever
+13 ...virtual mailboxes for more domains...
+14
+15 /etc/postfix/virtual:
+16 postmaster@example.com postmaster
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Line 2: With delivery to a non-Postfix mailbox store for
+hosted domains, the virtual_transport parameter usually specifies
+the Postfix LMTP client, or the name of a master.cf entry that
+executes non-Postfix software via the pipe delivery agent. Typical
+examples (use only one): </p>
+
+<blockquote>
+<pre>
+virtual_transport = lmtp:unix:/path/name (uses UNIX-domain socket)
+virtual_transport = lmtp:hostname:port (uses TCP socket)
+virtual_transport = maildrop: (uses pipe(8) to command)
+</pre>
+</blockquote>
+
+<p> Postfix comes ready with support for LMTP. And an example
+maildrop delivery method is already defined in the default Postfix
+master.cf file. See the MAILDROP_README document for more details.
+</p>
+
+<li> <p> Line 3: The virtual_mailbox_domains setting tells Postfix
+that example.com is delivered via the virtual_transport that was
+discussed in the previous paragraph. If you omit this
+virtual_mailbox_domains setting then Postfix will either reject
+mail (relay access denied) or will not be able to deliver it (mail
+for example.com loops back to myself). </p>
+
+<p> NEVER list a virtual MAILBOX domain name as a mydestination
+domain! </p>
+
+<p> NEVER list a virtual MAILBOX domain name as a virtual ALIAS
+domain! </p>
+
+<li> <p> Lines 4, 7-13: The virtual_mailbox_maps parameter specifies
+the lookup table with all valid recipient addresses. The lookup
+result value is ignored by Postfix. In the above example,
+info@example.com
+and sales@example.com are listed as valid addresses; other mail for
+example.com is rejected with "User unknown" by the Postfix SMTP
+server. It's left up to the non-Postfix delivery agent to reject
+non-existent recipients from local submission or from local alias
+expansion. If you intend to
+use LDAP, MySQL or PgSQL instead of local files, be sure to review
+the <a href="#local_vs_database"> "local files versus databases"</a>
+section at the top of this document! </p>
+
+<li> <p> Line 12: The commented out entry (text after #) shows how
+one would inform Postfix of the existence of a catch-all address.
+Again, the lookup result is ignored by Postfix. </p>
+
+<p> NEVER put a virtual MAILBOX wild-card in the virtual ALIAS
+file!! </p>
+
+<p> Note: if you specify a wildcard in virtual_mailbox_maps, then
+you still need to configure the non-Postfix mailbox store to receive
+mail for any address in that domain. </p>
+
+<li> <p> Lines 5, 15, 16: As you see above, it is possible to mix
+virtual aliases with virtual mailboxes. We use this feature to
+redirect mail for example.com's postmaster address to the local
+postmaster. You can use the same mechanism to redirect any addresses
+to a local or remote address. </p>
+
+<li> <p> Line 16: This example assumes that in main.cf, $myorigin
+is listed under the mydestination parameter setting. If that is
+not the case, specify an explicit domain name on the right-hand
+side of the virtual alias table entries or else mail will go to
+the wrong domain. </p>
+
+</ul>
+
+<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
+changing the virtual file, execute "<b>postmap /etc/postfix/vmailbox</b>"
+after changing the vmailbox file, and execute the command "<b>postfix
+reload</b>" after changing the main.cf file. </p>
+
+<h2><a name="forwarding">Mail forwarding domains</a></h2>
+
+<p> Some providers host domains that have no (or only a few) local
+mailboxes. The main purpose of these domains is to forward mail
+elsewhere. The following example shows how to set up example.com
+as a mail forwarding domain: </p>
+
+<blockquote>
+<pre>
+ 1 /etc/postfix/main.cf:
+ 2 virtual_alias_domains = example.com ...other hosted domains...
+ 3 virtual_alias_maps = hash:/etc/postfix/virtual
+ 4
+ 5 /etc/postfix/virtual:
+ 6 postmaster@example.com postmaster
+ 7 joe@example.com joe@somewhere
+ 8 jane@example.com jane@somewhere-else
+ 9 # Uncomment entry below to implement a catch-all address
+10 # @example.com jim@yet-another-site
+11 ...virtual aliases for more domains...
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Line 2: The virtual_alias_domains setting tells Postfix
+that example.com is a so-called virtual alias domain. If you omit
+this setting then Postfix will reject mail (relay access denied)
+or will not be able to deliver it (mail for example.com loops back
+to myself). </p>
+
+<p> NEVER list a virtual alias domain name as a mydestination
+domain! </p>
+
+<li> <p> Lines 3-11: The /etc/postfix/virtual file contains the
+virtual aliases. With the example above, mail for postmaster@example.com
+goes to the local postmaster, while mail for joe@example.com goes
+to the remote address joe@somewhere, and mail for jane@example.com
+goes to the remote address jane@somewhere-else. Mail for all other
+addresses in example.com is rejected with the error message "User
+unknown". </p>
+
+<li> <p> Line 10: The commented out entry (text after #) shows how
+one would implement a catch-all virtual alias that receives mail
+for every example.com address not listed in the virtual alias file.
+This is not without risk. Spammers nowadays try to send mail from
+(or mail to) every possible name that they can think of. A catch-all
+mailbox is likely to receive many spam messages, and many bounces
+for spam messages that were sent in the name of anything@example.com.
+</p>
+
+</ul>
+
+<p> Execute the command "<b>postmap /etc/postfix/virtual</b>" after
+changing the virtual file, and execute the command "<b>postfix
+reload</b>" after changing the main.cf file. </p>
+
+<p> More details about the virtual alias file are given in the
+virtual(5) manual page, including multiple addresses on the right-hand
+side. </p>
+
+<h2><a name="mailing_lists">Mailing lists</a></h2>
+
+<p> The examples that were given above already show how to direct
+mail for virtual postmaster addresses to a local postmaster. You
+can use the same method to direct mail for any address to a local
+or remote address. </p>
+
+<p> There is one major limitation: virtual aliases and virtual
+mailboxes can't directly deliver to mailing list managers such as
+majordomo. The solution is to set up virtual aliases that direct
+virtual addresses to the local delivery agent: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ virtual_alias_maps = hash:/etc/postfix/virtual
+
+/etc/postfix/virtual:
+ listname-request@example.com listname-request
+ listname@example.com listname
+ owner-listname@example.com owner-listname
+
+/etc/aliases:
+ listname: "|/some/where/majordomo/wrapper ..."
+ owner-listname: ...
+ listname-request: ...
+</pre>
+</blockquote>
+
+<p> This example assumes that in main.cf, $myorigin is listed under
+the mydestination parameter setting. If that is not the case,
+specify an explicit domain name on the right-hand side of the
+virtual alias table entries or else mail will go to the wrong
+domain. </p>
+
+<p> More information about the Postfix local delivery agent can be
+found in the local(8) manual page. </p>
+
+<p> Why does this example use a clumsy virtual alias instead of a
+more elegant transport mapping? The reason is that mail for the
+virtual mailing list would be rejected with "User unknown". In
+order to make the transport mapping work one would still need a
+bunch of virtual alias or virtual mailbox table entries. </p>
+
+<ul>
+
+<li> In case of a virtual alias domain, there would need to be one
+identity mapping from each mailing list address to itself.
+
+<li> In case of a virtual mailbox domain, there would need to be
+a dummy mailbox for each mailing list address.
+
+</ul>
+
+<h2><a name="autoreplies">Autoreplies</a></h2>
+
+<p> In order to set up an autoreply for virtual recipients while
+still delivering mail as normal, set up a rule in a virtual alias
+table: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ virtual_alias_maps = hash:/etc/postfix/virtual
+
+/etc/postfix/virtual:
+ user@domain.tld user@domain.tld, user@domain.tld@autoreply.mydomain.tld
+</pre>
+</blockquote>
+
+<p> This delivers mail to the recipient, and sends a copy of the
+mail to the address that produces automatic replies. The address
+can be serviced on a different machine, or it can be serviced
+locally by setting up a transport map entry that pipes all mail
+for autoreply.mydomain.tld into some script that sends an automatic
+reply back to the sender. </p>
+
+<p> DO NOT list autoreply.mydomain.tld in mydestination! </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+
+/etc/postfix/transport:
+ autoreply.mydomain.tld autoreply:
+
+/etc/postfix/master.cf:
+ # =============================================================
+ # service type private unpriv chroot wakeup maxproc command
+ # (yes) (yes) (yes) (never) (100)
+ # =============================================================
+ autoreply unix - n n - - pipe
+ flags= user=nobody argv=/path/to/autoreply $sender $mailbox
+</pre>
+</blockquote>
+
+<p> This invokes /path/to/autoreply with the sender address and
+the user@domain.tld recipient address on the command line. </p>
+
+<p> For more information, see the pipe(8) manual page, and the
+comments in the Postfix master.cf file. </p>
+
+</body>
+
+</html>
diff --git a/proto/XCLIENT_README.html b/proto/XCLIENT_README.html
new file mode 100644
index 0000000..6393c09
--- /dev/null
+++ b/proto/XCLIENT_README.html
@@ -0,0 +1,267 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix XCLIENT Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix XCLIENT Howto</h1>
+
+<hr>
+
+<h2>Purpose of the XCLIENT extension to SMTP</h2>
+
+<p> When an SMTP server announces support for the XCLIENT command,
+an SMTP client may send information that overrides one or more
+client-related session attributes. The XCLIENT command targets the
+following problems: </p>
+
+<ol>
+
+ <li> <p> Access control tests. SMTP server access rules are
+ difficult to verify when decisions can be triggered only by
+ remote clients. In order to facilitate access rule testing,
+ an authorized SMTP client test program needs the ability to
+ override the SMTP server's idea of the SMTP client hostname,
+ network address, and other client information, for the entire
+ duration of an SMTP session. </p>
+
+ <li> <p> Client software that downloads mail from an up-stream
+ mail server and injects it into a local MTA via SMTP. In order
+ to take advantage of the local MTA's SMTP server access rules,
+ the client software needs the ability to override the SMTP
+ server's idea of the remote client name, client address and
+ other information. Such information can typically be extracted
+ from the up-stream mail server's Received: message header. </p>
+
+ <li> <p> Post-filter access control and logging. With
+ Internet-&gt;filter-&gt;MTA style content filter applications,
+ the filter can be simplified if it can delegate decisions
+ concerning mail relay and other access control to the MTA. This
+ is especially useful when the filter acts as a transparent
+ proxy for SMTP commands. This requires that the filter can
+ override the MTA's idea of the SMTP client hostname, network
+ address, and other information. </p>
+
+</ol>
+
+<h2>XCLIENT Command syntax</h2>
+
+<p> An example client-server conversation is given at the end
+of this document. </p>
+
+<p> In SMTP server EHLO replies, the keyword associated with this
+extension is XCLIENT. It is followed by the names of the attributes
+that the XCLIENT implementation supports. </p>
+
+<p> The XCLIENT command may be sent at any time, except in the
+middle of a mail delivery transaction (i.e. between MAIL and DOT,
+or MAIL and RSET). The XCLIENT command may be pipelined when the
+server supports ESMTP command pipelining. To avoid triggering
+spamware detectors, the command should be sent at the end of a
+command group. </p>
+
+<p> The syntax of XCLIENT requests is described below. Upper case
+and quoted strings specify terminals, lowercase strings specify
+meta terminals, and SP is whitespace. Although command and attribute
+names are shown in upper case, they are in fact case insensitive.
+</p>
+
+<blockquote>
+<p>
+ xclient-command = XCLIENT 1*( SP attribute-name"="attribute-value )
+</p>
+<p>
+ attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | LOGIN | DESTADDR | DESTPORT )
+</p>
+<p>
+ attribute-value = xtext
+</p>
+</blockquote>
+
+<ul>
+
+ <li> <p> Attribute values are xtext encoded as per RFC 1891.
+ </p>
+
+ <li> <p> The NAME attribute specifies a remote SMTP client
+ hostname (not an SMTP client address), [UNAVAILABLE] when client
+ hostname lookup failed due to a permanent error, or [TEMPUNAVAIL]
+ when the lookup error condition was transient. </p>
+
+ <li> <p> The ADDR attribute specifies a remote SMTP client
+ numerical IPv4 network address, an IPv6 address prefixed with
+ IPV6:, or [UNAVAILABLE] when the address information is
+ unavailable. Address information is not enclosed with []. </p>
+
+ <li> <p> The PORT attribute specifies a remote SMTP client TCP
+ port number as a decimal number, or [UNAVAILABLE] when the
+ information is unavailable. </p>
+
+ <li> <p> The PROTO attribute specifies either SMTP or ESMTP.
+ </p>
+
+ <li> <p> The DESTADDR attribute specifies a local SMTP server
+ numerical IPv4 network address, an IPv6 address prefixed with
+ IPV6:, or [UNAVAILABLE] when the address information is
+ unavailable. Address information is not enclosed with []. </p>
+
+ <li> <p> The DESTPORT attribute specifies a local SMTP server
+ TCP port number as a decimal number, or [UNAVAILABLE] when the
+ information is unavailable. </p>
+
+ <li> <p> The HELO attribute specifies an SMTP HELO parameter
+ value, or the value [UNAVAILABLE] when the information is
+ unavailable. </p>
+
+ <li> <p> The LOGIN attribute specifies a SASL login name, or
+ the value [UNAVAILABLE] when the information is unavailable.
+ </p>
+
+</ul>
+
+<p> Note 1: syntactically valid NAME and HELO attribute-value
+elements can be up to 255 characters long. The client must not send
+XCLIENT commands that exceed the 512 character limit for SMTP
+commands. To avoid exceeding the limit the client should send the
+information in multiple XCLIENT commands; for example, send NAME
+and ADDR last, after HELO and PROTO. Once ADDR is sent, the client
+is usually no longer authorized to send XCLIENT commands. </p>
+
+<p> Note 2: [UNAVAILABLE], [TEMPUNAVAIL] and IPV6: may be specified
+in upper case, lower case or mixed case. </p>
+
+<p> Note 3: Postfix implementations prior to version 2.3 do not
+xtext encode attribute values. Servers that wish to interoperate
+with these older implementations should be prepared to receive
+unencoded information. </p>
+
+<p> Note 4: Some Postfix implementations do not implement the PORT
+or LOGIN attributes. </p>
+
+<h2>XCLIENT Server response</h2>
+
+<p> Upon receipt of a correctly formatted XCLIENT command, the
+server resets state to the initial SMTP greeting protocol stage.
+Depending on the outcome of optional access decisions, the server
+responds with 220 or with a suitable rejection code.
+
+<p> For practical reasons it is not always possible to reset the
+complete server state to the initial SMTP greeting protocol stage:
+</p>
+
+<ul>
+
+<li> <p> TLS session information may not be reset, because turning off
+TLS leaves the connection in an undefined state. Consequently, the
+server may not announce STARTTLS when TLS is already active, and
+access decisions may be influenced by client certificate information
+that was received prior to the XCLIENT command. </p>
+
+<li> <p> The SMTP server must not reset attributes that were received
+with the last XCLIENT command. This includes HELO or PROTO attributes.
+</p>
+
+</ul>
+
+<p> NOTE: Postfix implementations prior to version 2.3 do not jump
+back to the initial SMTP greeting protocol stage. These older
+implementations will not correctly simulate connection-level access
+decisions under some conditions. </p>
+
+<h2> XCLIENT server reply codes </h2>
+
+<blockquote>
+
+<table border="1" bgcolor="#f0f0ff">
+
+<tr> <th> Code </th> <th> Meaning </th> </tr>
+
+<tr> <td> 220 </td> <td> success </td> </tr>
+
+<tr> <td> 421 </td> <td> unable to proceed, disconnecting </td> </tr>
+
+<tr> <td> 501 </td> <td> bad command parameter syntax </td> </tr>
+
+<tr> <td> 503 </td> <td> mail transaction in progress </td> </tr>
+
+<tr> <td> 550 </td> <td> insufficient authorization </td> </tr>
+
+<tr> <td> other </td> <td> connection rejected by connection-level
+access decision </td> </tr>
+
+</table>
+
+</blockquote>
+
+<h2>XCLIENT Example</h2>
+
+<p> In the example, the client impersonates a mail originating
+system by passing all SMTP client information via the XCLIENT
+command. Information sent by the client is shown in bold font.
+</p>
+
+<blockquote>
+<pre>
+220 server.example.com ESMTP Postfix
+<b>EHLO client.example.com</b>
+250-server.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-VRFY
+250-ETRN
+250-XCLIENT NAME ADDR PROTO HELO
+250 8BITMIME
+<b>XCLIENT NAME=spike.porcupine.org ADDR=168.100.189.2</b>
+220 server.example.com ESMTP Postfix
+<b>EHLO spike.porcupine.org</b>
+250-server.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-VRFY
+250-ETRN
+250-XCLIENT NAME ADDR PROTO HELO
+250 8BITMIME
+<b>MAIL FROM:&lt;wietse@porcupine.org&gt;</b>
+250 Ok
+<b>RCPT TO:&lt;user@example.com&gt;</b>
+250 Ok
+<b>DATA</b>
+354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;
+<b>. . .<i>message content</i>. . .</b>
+<b>.</b>
+250 Ok: queued as 763402AAE6
+<b>QUIT</b>
+221 Bye
+</pre>
+</blockquote>
+
+<h2>Security</h2>
+
+<p> The XCLIENT command changes audit trails and/or SMTP client
+access permissions. Use of this command must be restricted to
+authorized SMTP clients. </p>
+
+<h2>SMTP connection caching</h2>
+
+<p> XCLIENT attributes persist until the end of an SMTP session.
+If one session is used to deliver mail on behalf of different SMTP
+clients, the XCLIENT attributes need to be reset as appropriate
+before each MAIL FROM command. </p>
+
+<h2> References </h2>
+
+<p> Moore, K, "SMTP Service Extension for Delivery Status Notifications",
+RFC 1891, January 1996. </p>
+
+</body>
+
+</html>
diff --git a/proto/XFORWARD_README.html b/proto/XFORWARD_README.html
new file mode 100644
index 0000000..1165e98
--- /dev/null
+++ b/proto/XFORWARD_README.html
@@ -0,0 +1,241 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix XFORWARD Howto</title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix XFORWARD Howto</h1>
+
+<hr>
+
+<h2>Purpose of the XFORWARD extension to SMTP</h2>
+
+<p> When an SMTP server announces support for the XFORWARD command,
+an SMTP client may send information that overrides one or more
+client-related logging attributes. The XFORWARD command targets
+the following problem: </p>
+
+<ul>
+
+ <li> <p> Logging after SMTP-based content filter. With the
+ deployment of Internet-&gt;MTA1-&gt;filter-&gt;MTA2 style
+ content filter applications, the logging of client and message
+ identifying information changes when MTA1 gives the mail to
+ the content filter. To simplify the interpretation of MTA2
+ logging, it would help if MTA1 could forward remote client
+ and/or message identifying information through the content
+ filter to MTA2, so that the information could be logged as part
+ of mail handling transactions. </p>
+
+</ul>
+
+<p> This extension is implemented as a separate ESMTP command, and
+can be used to transmit client or message attributes incrementally.
+It is not implemented by passing additional parameters via the MAIL
+FROM command, because doing so would require extending the MAIL
+FROM command length limit by another 600 or more characters beyond
+the space that is already needed to support other extensions such
+as AUTH and DSN. </p>
+
+<h2>XFORWARD Command syntax</h2>
+
+<p> An example of a client-server conversation is given at the end
+of this document. </p>
+
+<p> In SMTP server EHLO replies, the keyword associated with this
+extension is XFORWARD. The keyword is followed by the names of the
+attributes that the XFORWARD implementation supports. </p>
+
+<p> After receiving the server's announcement for XFORWARD support,
+the client may send XFORWARD requests at any time except in
+the middle of a mail delivery transaction (i.e. between MAIL and
+RSET or DOT). The command may be pipelined when the server supports
+ESMTP command pipelining. </p>
+
+<p> The syntax of XFORWARD requests is described below. Upper case
+and quoted strings specify terminals, lowercase strings specify
+meta terminals, and SP is whitespace. Although command and attribute
+names are shown in upper case, they are in fact case insensitive.
+</p>
+
+<blockquote>
+<p>
+ xforward-command = XFORWARD 1*( SP attribute-name"="attribute-value )
+</p>
+<p>
+ attribute-name = ( NAME | ADDR | PORT | PROTO | HELO | IDENT | SOURCE )
+</p>
+<p>
+ attribute-value = xtext
+</p>
+</blockquote>
+
+<ul>
+
+ <li> <p> Attribute values are xtext encoded as per RFC 1891.
+ </p>
+
+ <li> <p> The NAME attribute specifies the up-stream hostname,
+ or [UNAVAILABLE] when the information is unavailable. The
+ hostname may be a non-DNS hostname. </p>
+
+ <li> <p> The ADDR attribute specifies the up-stream network
+ address: a numerical IPv4 network address, an IPv6 address
+ prefixed with IPV6:, or [UNAVAILABLE] when the address information
+ is unavailable. Address information is not enclosed with [].
+ </p>
+
+ <li> <p> The PORT attribute specifies an up-stream client TCP
+ port number in decimal, or [UNAVAILABLE] when the information
+ is unavailable. </p>
+
+ <li> <p> The PROTO attribute specifies the mail protocol for
+ receiving mail from the up-stream host. This may be an SMTP or
+ non-SMTP protocol name of up to 64 characters, or [UNAVAILABLE]
+ when the information is unavailable. </p>
+
+ <li> <p> The HELO attribute specifies the hostname that the
+ up-stream host announced itself with (not necessarily via the
+ SMTP HELO command), or [UNAVAILABLE] when the information is
+ unavailable. The hostname may be a non-DNS hostname. </p>
+
+ <li> <p> The IDENT attribute specifies a local message identifier
+ on the up-stream host, or [UNAVAILABLE] when the information
+ is unavailable. The down-stream MTA may log this information
+ together with its own local message identifier to facilitate
+ message tracking across MTAs. </p>
+
+ <li> <p> The SOURCE attribute specifies LOCAL when the message
+ was received from a source that is local with respect to the
+ up-stream host (for example, the message originated from the
+ up-stream host itself), REMOTE for all other mail, or [UNAVAILABLE]
+ when the information is unavailable. The down-stream MTA may
+ decide to enable features such as header munging or address
+ qualification with mail from local sources but not other sources.
+ </p>
+
+</ul>
+
+<p> Note 1: an attribute-value element must not be longer than
+255 characters (specific attributes may impose shorter lengths).
+After xtext decoding, attribute values must not contain control
+characters, non-ASCII characters, whitespace, or other characters
+that are special in message headers. </p>
+
+<p> Note 2: DNS hostnames can be up to 255 characters long. The
+XFORWARD client implementation must not send XFORWARD commands that
+exceed the 512 character limit for SMTP commands. </p>
+
+<p> Note 3: [UNAVAILABLE] may be specified in upper case, lower
+case or mixed case. </p>
+
+<p> Note 4: Postfix implementations prior to version 2.3 do not
+xtext encode attribute values. Servers that wish to interoperate
+with these older implementations should be prepared to receive
+unencoded information. </p>
+
+<h2> XFORWARD Server operation </h2>
+
+<p> The server maintains a set of XFORWARD attributes with forwarded
+information, in addition the current SMTP session attributes.
+Normally, all XFORWARD attributes are in the undefined state, and
+the server uses the current SMTP session attributes for logging
+purposes. </p>
+
+<p> Upon receipt of an initial XFORWARD command, the SMTP server
+initializes all XFORWARD attributes to [UNAVAILABLE]. With each
+valid XFORWARD command, the server updates XFORWARD attributes with
+the specified values. </p>
+
+<p> The server must not mix client attributes from XFORWARD with
+client attributes from the current SMTP session. </p>
+
+<p> At the end of each MAIL FROM transaction (i.e. RSET or DOT),
+the server resets all XFORWARD attributes to the undefined state,
+and is ready to receive another initial XFORWARD command. </p>
+
+<h2> XFORWARD Server reply codes </h2>
+
+<blockquote>
+
+<table bgcolor="#f0f0ff" border="1">
+
+<tr> <th> Code </th> <th> Meaning </th> </tr>
+
+<tr> <td> 250 </td> <td> success </td> </tr>
+
+<tr> <td> 421 </td> <td> unable to proceed, disconnecting </td> </tr>
+
+<tr> <td> 501 </td> <td> bad command parameter syntax </td> </tr>
+
+<tr> <td> 503 </td> <td> mail transaction in progress </td> </tr>
+
+<tr> <td> 550 </td> <td> insufficient authorization </td> </tr>
+
+</table>
+
+</blockquote>
+
+<h2>XFORWARD Example</h2>
+
+<p> In the following example, information sent by the client is
+shown in bold font. </p>
+
+<blockquote>
+<pre>
+220 server.example.com ESMTP Postfix
+<b>EHLO client.example.com</b>
+250-server.example.com
+250-PIPELINING
+250-SIZE 10240000
+250-VRFY
+250-ETRN
+250-XFORWARD NAME ADDR PROTO HELO
+250 8BITMIME
+<b>XFORWARD NAME=spike.porcupine.org ADDR=168.100.189.2 PROTO=ESMTP </b>
+250 Ok
+<b>XFORWARD HELO=spike.porcupine.org</b>
+250 Ok
+<b>MAIL FROM:&lt;wietse@porcupine.org&gt;</b>
+250 Ok
+<b>RCPT TO:&lt;user@example.com&gt;</b>
+250 Ok
+<b>DATA</b>
+354 End data with &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;
+<b>. . .<i>message content</i>. . .</b>
+<b>.</b>
+250 Ok: queued as 3CF6B2AAE8
+<b>QUIT</b>
+221 Bye
+</pre>
+</blockquote>
+
+<h2>Security</h2>
+
+<p> The XFORWARD command changes audit trails. Use of this command
+must be restricted to authorized clients. </p>
+
+<h2>SMTP connection caching</h2>
+
+<p> SMTP connection caching makes it possible to deliver multiple
+messages within the same SMTP session. The XFORWARD attributes are
+reset after the MAIL FROM transaction completes (after RSET or DOT),
+so there is no risk of information leakage. </p>
+
+<h2> References </h2>
+
+<p> Moore, K, "SMTP Service Extension for Delivery Status Notifications",
+RFC 1891, January 1996. </p>
+
+</body>
+
+</html>
diff --git a/proto/access b/proto/access
new file mode 100644
index 0000000..0fe2a89
--- /dev/null
+++ b/proto/access
@@ -0,0 +1,468 @@
+#++
+# NAME
+# access 5
+# SUMMARY
+# Postfix SMTP server access table
+# SYNOPSIS
+# \fBpostmap /etc/postfix/access\fR
+#
+# \fBpostmap -q "\fIstring\fB" /etc/postfix/access\fR
+#
+# \fBpostmap -q - /etc/postfix/access <\fIinputfile\fR
+# DESCRIPTION
+# This document describes access control on remote SMTP client
+# information: host names, network addresses, and envelope
+# sender or recipient addresses; it is implemented by the
+# Postfix SMTP server. See \fBheader_checks\fR(5) or
+# \fBbody_checks\fR(5) for access control on the content of
+# email messages.
+#
+# Normally, the \fBaccess\fR(5) table is specified as a text file
+# that serves as input to the \fBpostmap\fR(1) command.
+# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
+# is used for fast searching by the mail system. Execute the
+# command "\fBpostmap /etc/postfix/access\fR" to rebuild an
+# indexed file after changing the corresponding text file.
+#
+# When the table is provided via other means such as NIS, LDAP
+# or SQL, the same lookups are done as for ordinary indexed files.
+#
+# Alternatively, the table can be provided as a regular-expression
+# map where patterns are given as regular expressions, or lookups
+# can be directed to a TCP-based server. In those cases, the lookups
+# are done in a slightly different way as described below under
+# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES".
+# CASE FOLDING
+# .ad
+# .fi
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+# TABLE FORMAT
+# .ad
+# .fi
+# The input format for the \fBpostmap\fR(1) command is as follows:
+# .IP "\fIpattern action\fR"
+# When \fIpattern\fR matches a mail address, domain or host address,
+# perform the corresponding \fIaction\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# EMAIL ADDRESS PATTERNS
+# .ad
+# .fi
+# With lookups from indexed files such as DB or DBM, or from networked
+# tables such as NIS, LDAP or SQL, patterns are tried in the order as
+# listed below:
+# .IP \fIuser\fR@\fIdomain\fR
+# Matches the specified mail address.
+# .IP \fIdomain.tld\fR
+# Matches \fIdomain.tld\fR as the domain part of an email address.
+# .sp
+# The pattern \fIdomain.tld\fR also matches subdomains, but only
+# when the string \fBsmtpd_access_maps\fR is listed in the Postfix
+# \fBparent_domain_matches_subdomains\fR configuration setting.
+# .IP \fI.domain.tld\fR
+# Matches subdomains of \fIdomain.tld\fR, but only when the
+# string \fBsmtpd_access_maps\fR is not listed in the Postfix
+# \fBparent_domain_matches_subdomains\fR configuration setting.
+# .IP \fIuser\fR@
+# Matches all mail addresses with the specified user part.
+# .PP
+# Note: lookup of the null sender address is not possible with
+# some types of lookup table. By default, Postfix uses \fB<>\fR
+# as the lookup key for such addresses. The value is specified with
+# the \fBsmtpd_null_access_lookup_key\fR parameter in the Postfix
+# \fBmain.cf\fR file.
+# EMAIL ADDRESS EXTENSION
+# .fi
+# .ad
+# When a mail address localpart contains the optional recipient delimiter
+# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
+# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIdomain\fR,
+# \fIuser+foo\fR@, and \fIuser\fR@.
+# HOST NAME/ADDRESS PATTERNS
+# .ad
+# .fi
+# With lookups from indexed files such as DB or DBM, or from networked
+# tables such as NIS, LDAP or SQL, the following lookup patterns are
+# examined in the order as listed:
+# .IP \fIdomain.tld\fR
+# Matches \fIdomain.tld\fR.
+# .sp
+# The pattern \fIdomain.tld\fR also matches subdomains, but only
+# when the string \fBsmtpd_access_maps\fR is listed in the Postfix
+# \fBparent_domain_matches_subdomains\fR configuration setting.
+# .IP \fI.domain.tld\fR
+# Matches subdomains of \fIdomain.tld\fR, but only when the
+# string \fBsmtpd_access_maps\fR is not listed in the Postfix
+# \fBparent_domain_matches_subdomains\fR configuration setting.
+# .IP \fInet.work.addr.ess\fR
+# .IP \fInet.work.addr\fR
+# .IP \fInet.work\fR
+# .IP \fInet\fR
+# Matches a remote IPv4 host address or network address range.
+# Specify one to four decimal octets separated by ".". Do not
+# specify "[]" , "/", leading zeros, or hexadecimal forms.
+#
+# Network ranges are matched by repeatedly truncating the last
+# ".octet" from a remote IPv4 host address string, until a
+# match is found in the access table, or until further
+# truncation is not possible.
+#
+# NOTE: use the \fBcidr\fR lookup table type to specify
+# network/netmask patterns. See \fBcidr_table\fR(5) for details.
+# .IP \fInet:work:addr:ess\fR
+# .IP \fInet:work:addr\fR
+# .IP \fInet:work\fR
+# .IP \fInet\fR
+# Matches a remote IPv6 host address or network address range.
+# Specify three to eight hexadecimal octet pairs separated
+# by ":", using the compressed form "::" for a sequence of
+# zero-valued octet pairs. Do not specify "[]", "/", leading
+# zeros, or non-compressed forms.
+#
+# A network range is matched by repeatedly truncating the
+# last ":octetpair" from the compressed-form remote IPv6 host
+# address string, until a match is found in the access table,
+# or until further truncation is not possible.
+#
+# NOTE: use the \fBcidr\fR lookup table type to specify
+# network/netmask patterns. See \fBcidr_table\fR(5) for details.
+#
+# IPv6 support is available in Postfix 2.2 and later.
+# ACCEPT ACTIONS
+# .ad
+# .fi
+# .IP \fBOK\fR
+# Accept the address etc. that matches the pattern.
+# .IP \fIall-numerical\fR
+# An all-numerical result is treated as OK. This format is
+# generated by address-based relay authorization schemes
+# such as pop-before-smtp.
+# .PP
+# For other accept actions, see "OTHER ACTIONS" below.
+# REJECT ACTIONS
+# .ad
+# .fi
+# Postfix version 2.3 and later support enhanced status codes
+# as defined in RFC 3463.
+# When no code is specified at the beginning of the \fItext\fR
+# below, Postfix inserts a default enhanced status code of "5.7.1"
+# in the case of reject actions, and "4.7.1" in the case of
+# defer actions. See "ENHANCED STATUS CODES" below.
+# .IP "\fB4\fINN text\fR"
+# .IP "\fB5\fINN text\fR"
+# Reject the address etc. that matches the pattern, and respond with
+# the numerical three-digit code and text. \fB4\fINN\fR means "try
+# again later", while \fB5\fINN\fR means "do not try again".
+#
+# The following responses have special meaning for the Postfix
+# SMTP server:
+# .RS
+# .IP "\fB421 \fItext\fR (Postfix 2.3 and later)"
+# .IP "\fB521 \fItext\fR (Postfix 2.6 and later)"
+# After responding with the numerical three-digit code and
+# text, disconnect immediately from the SMTP client. This
+# frees up SMTP server resources so that they can be made
+# available to another SMTP client.
+# .IP
+# Note: The "521" response should be used only with botnets
+# and other malware where interoperability is of no concern.
+# The "send 521 and disconnect" behavior is NOT defined in
+# the SMTP standard.
+# .RE
+# .IP "\fBREJECT \fIoptional text...\fR
+# Reject the address etc. that matches the pattern. Reply with
+# "\fB$access_map_reject_code \fIoptional text...\fR" when the
+# optional text is
+# specified, otherwise reply with a generic error response message.
+# .IP "\fBDEFER \fIoptional text...\fR
+# Reject the address etc. that matches the pattern. Reply with
+# "\fB$access_map_defer_code \fIoptional text...\fR" when the
+# optional text is
+# specified, otherwise reply with a generic error response message.
+# .sp
+# This feature is available in Postfix 2.6 and later.
+# .IP "\fBDEFER_IF_REJECT \fIoptional text...\fR
+# Defer the request if some later restriction would result in a
+# REJECT action. Reply with "\fB$access_map_defer_code 4.7.1
+# \fIoptional text...\fR" when the
+# optional text is specified, otherwise reply with a generic error
+# response message.
+# .sp
+# Prior to Postfix 2.6, the SMTP reply code is 450.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .IP "\fBDEFER_IF_PERMIT \fIoptional text...\fR
+# Defer the request if some later restriction would result in
+# an explicit or implicit PERMIT action.
+# Reply with "\fB$access_map_defer_code 4.7.1 \fI optional
+# text...\fR" when the
+# optional text is specified, otherwise reply with a generic error
+# response message.
+# .sp
+# Prior to Postfix 2.6, the SMTP reply code is 450.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .PP
+# For other reject actions, see "OTHER ACTIONS" below.
+# OTHER ACTIONS
+# .ad
+# .fi
+# .IP \fIrestriction...\fR
+# Apply the named UCE restriction(s) (\fBpermit\fR, \fBreject\fR,
+# \fBreject_unauth_destination\fR, and so on).
+# .IP "\fBBCC \fIuser@domain\fR"
+# Send one copy of the message to the specified recipient.
+# .sp
+# If multiple BCC actions are specified within the same SMTP
+# MAIL transaction, with Postfix 3.0 only the last action
+# will be used.
+# .sp
+# This feature is available in Postfix 3.0 and later.
+# \" .IP "\fBDELAY \fItime\fR"
+# \" Place the message into the deferred queue, and delay the
+# \" initial delivery attempt by \fItime\fR. The time value may
+# \" be followed by a one-character suffix that specifies the
+# \" time unit: s (seconds), m (minutes), h (hours), d (days),
+# \" w (weeks). The default time unit is s (seconds).
+# \" .sp
+# \" Limitations:
+# \" .RS
+# \" .IP \(bu
+# \" This action affects all the recipients of the message.
+# \" .IP \(bu
+# \" The delay value has no effect with remote file systems that
+# \" don't correctly emulate UNIX local file system semantics.
+# \" In that case, the delay will be half of $queue_run_delay
+# \" on average.
+# \" .IP \(bu
+# \" Mail will still be delivered with "sendmail -q", "postfix
+# \" flush" or "postqueue -f".
+# \" .IP \(bu
+# \" Delayed mail increases the amount of disk I/O during deferred
+# \" queue scans. When large amounts of mail are queued for
+# \" delayed delivery it may be preferable to use the HOLD feature
+# \" instead.
+# \" .RE
+# \" .IP
+# \" This feature is available in Postfix 2.3 and later.
+# .IP "\fBDISCARD \fIoptional text...\fR
+# Claim successful delivery and silently discard the message.
+# Log the optional text if specified, otherwise log a generic
+# message.
+# .sp
+# Note: this action currently affects all recipients of the message.
+# To discard only one recipient without discarding the entire message,
+# use the transport(5) table to direct mail to the discard(8) service.
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .IP \fBDUNNO\fR
+# Pretend that the lookup key was not found. This
+# prevents Postfix from trying substrings of the lookup key
+# (such as a subdomain name, or a network address subnetwork).
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .IP "\fBFILTER \fItransport:destination\fR"
+# After the message is queued, send the entire message through
+# the specified external content filter. The \fItransport\fR
+# name specifies the first field of a mail delivery agent
+# definition in master.cf; the syntax of the next-hop
+# \fIdestination\fR is described in the manual page of the
+# corresponding delivery agent. More information about
+# external content filters is in the Postfix FILTER_README
+# file.
+# .sp
+# Note 1: do not use $\fInumber\fR regular expression
+# substitutions for \fItransport\fR or \fIdestination\fR
+# unless you know that the information has a trusted origin.
+# .sp
+# Note 2: this action overrides the main.cf \fBcontent_filter\fR
+# setting, and affects all recipients of the message. In the
+# case that multiple \fBFILTER\fR actions fire, only the last
+# one is executed.
+# .sp
+# Note 3: the purpose of the FILTER command is to override
+# message routing. To override the recipient's \fItransport\fR
+# but not the next-hop \fIdestination\fR, specify an empty
+# filter \fIdestination\fR (Postfix 2.7 and later), or specify
+# a \fItransport:destination\fR that delivers through a
+# different Postfix instance (Postfix 2.6 and earlier). Other
+# options are using the recipient-dependent \fBtrans\%port\%_maps\fR
+# or the sen\%der-dependent
+# \fBsender\%_de\%pen\%dent\%_de\%fault\%_trans\%port\%_maps\fR
+# features.
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .IP "\fBHOLD \fIoptional text...\fR"
+# Place the message on the \fBhold\fR queue, where it will
+# sit until someone either deletes it or releases it for
+# delivery.
+# Log the optional text if specified, otherwise log a generic
+# message.
+#
+# Mail that is placed on hold can be examined with the
+# \fBpostcat\fR(1) command, and can be destroyed or released with
+# the \fBpostsuper\fR(1) command.
+# .sp
+# Note: use "\fBpostsuper -r\fR" to release mail that was kept on
+# hold for a significant fraction of \fB$maximal_queue_lifetime\fR
+# or \fB$bounce_queue_lifetime\fR, or longer. Use "\fBpostsuper -H\fR"
+# only for mail that will not expire within a few delivery attempts.
+# .sp
+# Note: this action currently affects all recipients of the message.
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .IP "\fBPREPEND \fIheadername: headervalue\fR"
+# Prepend the specified message header to the message.
+# When more than one PREPEND action executes, the first
+# prepended header appears before the second etc. prepended
+# header.
+# .sp
+# Note: this action must execute before the message content
+# is received; it cannot execute in the context of
+# \fBsmtpd_end_of_data_restrictions\fR.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .IP "\fBREDIRECT \fIuser@domain\fR"
+# After the message is queued, send the message to the specified
+# address instead of the intended recipient(s). When multiple
+# \fBREDIRECT\fR actions fire, only the last one takes effect.
+# .sp
+# Note: this action overrides the FILTER action, and currently
+# overrides all recipients of the message.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .IP "\fBINFO \fIoptional text...\fR
+# Log an informational record with the optional text, together
+# with client information and if available, with helo, sender,
+# recipient and protocol information.
+# .sp
+# This feature is available in Postfix 3.0 and later.
+# .IP "\fBWARN \fIoptional text...\fR
+# Log a warning with the optional text, together with client information
+# and if available, with helo, sender, recipient and protocol information.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# ENHANCED STATUS CODES
+# .ad
+# .fi
+# Postfix version 2.3 and later support enhanced status codes
+# as defined in RFC 3463.
+# When an enhanced status code is specified in an access
+# table, it is subject to modification. The following
+# transformations are needed when the same access table is
+# used for client, helo, sender, or recipient access restrictions;
+# they happen regardless of whether Postfix replies to a MAIL
+# FROM, RCPT TO or other SMTP command.
+# .IP \(bu
+# When a sender address matches a REJECT action, the Postfix
+# SMTP server will transform a recipient DSN status (e.g.,
+# 4.1.1-4.1.6) into the corresponding sender DSN status, and
+# vice versa.
+# .IP \(bu
+# When non-address information matches a REJECT action (such
+# as the HELO command argument or the client hostname/address),
+# the Postfix SMTP server will transform a sender or recipient
+# DSN status into a generic non-address DSN status (e.g.,
+# 4.0.0).
+# REGULAR EXPRESSION TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when the table
+# is given in the form of regular expressions. For a description of
+# regular expression lookup table syntax, see \fBregexp_table\fR(5)
+# or \fBpcre_table\fR(5).
+#
+# Each pattern is a regular expression that is applied to the entire
+# string being looked up. Depending on the application, that string
+# is an entire client hostname, an entire client IP address, or an
+# entire mail address. Thus, no parent domain or parent network search
+# is done, \fIuser@domain\fR mail addresses are not broken up into
+# their \fIuser@\fR and \fIdomain\fR constituent parts, nor is
+# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the search string.
+#
+# Actions are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from the
+# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on.
+# TCP-BASED TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when lookups
+# are directed to a TCP-based server. For a description of the TCP
+# client/server lookup protocol, see \fBtcp_table\fR(5).
+# This feature is not available up to and including Postfix version 2.4.
+#
+# Each lookup operation uses the entire query string once.
+# Depending on the application, that string is an entire client
+# hostname, an entire client IP address, or an entire mail address.
+# Thus, no parent domain or parent network search is done,
+# \fIuser@domain\fR mail addresses are not broken up into
+# their \fIuser@\fR and \fIdomain\fR constituent parts, nor is
+# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Actions are the same as with indexed file lookups.
+# EXAMPLE
+# .ad
+# .fi
+# The following example uses an indexed file, so that the
+# order of table entries does not matter. The example permits
+# access by the client at address 1.2.3.4 but rejects all
+# other clients in 1.2.3.0/24. Instead of \fBhash\fR lookup
+# tables, some systems use \fBdbm\fR. Use the command
+# "\fBpostconf -m\fR" to find out what lookup tables Postfix
+# supports on your system.
+#
+# .nf
+# .na
+# /etc/postfix/main.cf:
+# smtpd_client_restrictions =
+# check_client_access hash:/etc/postfix/access
+#
+# /etc/postfix/access:
+# 1.2.3 REJECT
+# 1.2.3.4 OK
+# .fi
+# .ad
+#
+# Execute the command "\fBpostmap /etc/postfix/access\fR" after
+# editing the file.
+# BUGS
+# The table format does not understand quoting conventions.
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# smtpd(8), SMTP server
+# postconf(5), configuration parameters
+# transport(5), transport:nexthop syntax
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# SMTPD_ACCESS_README, built-in SMTP server access control
+# DATABASE_README, Postfix lookup table overview
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/aliases b/proto/aliases
new file mode 100644
index 0000000..ed01ec0
--- /dev/null
+++ b/proto/aliases
@@ -0,0 +1,205 @@
+#++
+# NAME
+# aliases 5
+# SUMMARY
+# Postfix local alias database format
+# SYNOPSIS
+# .fi
+# \fBnewaliases\fR
+# DESCRIPTION
+# The \fBaliases\fR(5) table provides a system-wide mechanism to
+# redirect mail for local recipients. The redirections are
+# processed by the Postfix \fBlocal\fR(8) delivery agent.
+#
+# Normally, the \fBaliases\fR(5) table is specified as a text file
+# that serves as input to the \fBpostalias\fR(1) command. The
+# result, an indexed file in \fBdbm\fR or \fBdb\fR format, is
+# used for fast lookup by the mail system. Execute the command
+# \fBnewaliases\fR in order to rebuild the indexed file after
+# changing the Postfix alias database.
+#
+# When the table is provided via other means such as NIS, LDAP
+# or SQL, the same lookups are done as for ordinary indexed files.
+#
+# Alternatively, the table can be provided as a regular-expression
+# map where patterns are given as regular expressions. In
+# this case, the lookups are done in a slightly different way
+# as described below under "REGULAR EXPRESSION TABLES".
+#
+# Users can control delivery of their own mail by setting
+# up \fB.forward\fR files in their home directory.
+# Lines in per-user \fB.forward\fR files have the same syntax
+# as the right-hand side of \fBaliases\fR(5) entries.
+#
+# The format of the alias database input file is as follows:
+# .IP \(bu
+# An alias definition has the form
+# .sp
+# .nf
+# \fIname\fR: \fIvalue1\fR, \fIvalue2\fR, \fI...\fR
+# .fi
+# .IP \(bu
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP \(bu
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# .PP
+# The \fIname\fR is a local address (no domain part).
+# Use double quotes when the name contains any special characters
+# such as whitespace, `#', `:', or `@'. The \fIname\fR is folded to
+# lowercase, in order to make database lookups case insensitive.
+# .PP
+# In addition, when an alias exists for \fBowner-\fIname\fR,
+# this will override the envelope sender address, so that
+# delivery diagnostics are directed to \fBowner-\fIname\fR,
+# instead of the originator of the message (for details, see
+# \fBowner_request_special\fR, \fBexpand_owner_alias\fR and
+# \fBreset_owner_alias\fR).
+# This is typically used to direct delivery errors to the maintainer of
+# a mailing list, who is in a better position to deal with mailing
+# list delivery problems than the originator of the undelivered mail.
+# .PP
+# The \fIvalue\fR contains one or more of the following:
+# .IP \fIaddress\fR
+# Mail is forwarded to \fIaddress\fR, which is compatible
+# with the RFC 822 standard.
+# .IP \fI/file/name\fR
+# Mail is appended to \fI/file/name\fR. See \fBlocal\fR(8)
+# for details of delivery to file.
+# Delivery is not limited to regular files. For example, to dispose
+# of unwanted mail, deflect it to \fB/dev/null\fR.
+# .IP "|\fIcommand\fR"
+# Mail is piped into \fIcommand\fR. Commands that contain special
+# characters, such as whitespace, should be enclosed between double
+# quotes. See \fBlocal\fR(8) for details of delivery to command.
+# .sp
+# When the command fails, a limited amount of command output is
+# mailed back to the sender. The file \fB/usr/include/sysexits.h\fR
+# defines the expected exit status codes. For example, use
+# \fB"|exit 67"\fR to simulate a "user unknown" error, and
+# \fB"|exit 0"\fR to implement an expensive black hole.
+# .IP \fB:include:\fI/file/name\fR
+# Mail is sent to the destinations listed in the named file.
+# Lines in \fB:include:\fR files have the same syntax
+# as the right-hand side of alias entries.
+# .sp
+# A destination can be any destination that is described in this
+# manual page. However, delivery to "|\fIcommand\fR" and
+# \fI/file/name\fR is disallowed by default. To enable, edit the
+# \fBallow_mail_to_commands\fR and \fBallow_mail_to_files\fR
+# configuration parameters.
+# ADDRESS EXTENSION
+# .ad
+# .fi
+# When alias database search fails, and the recipient localpart
+# contains the optional recipient delimiter (e.g., \fIuser+foo\fR),
+# the search is repeated for the unextended address (e.g., \fIuser\fR).
+#
+# The \fBpropagate_unmatched_extensions\fR parameter controls
+# whether an unmatched address extension (\fI+foo\fR) is
+# propagated to the result of table lookup.
+# CASE FOLDING
+# .ad
+# .fi
+# The local(8) delivery agent always folds the search string
+# to lowercase before database lookup.
+# REGULAR EXPRESSION TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when the table
+# is given in the form of regular expressions. For a description of
+# regular expression lookup table syntax, see \fBregexp_table\fR(5)
+# or \fBpcre_table\fR(5). NOTE: these formats do not use ":" at the
+# end of a pattern.
+#
+# Each regular expression is applied to the entire search
+# string. Thus, a search string \fIuser+foo\fR is not broken
+# up into \fIuser\fR and \fIfoo\fR.
+#
+# Regular expressions are applied in the order as specified
+# in the table, until a regular expression is found that
+# matches the search string.
+#
+# Lookup results are the same as with indexed file lookups.
+# For security reasons there is no support for \fB$1\fR,
+# \fB$2\fR etc. substring interpolation.
+# SECURITY
+# .ad
+# .fi
+# The \fBlocal\fR(8) delivery agent disallows regular expression
+# substitution of $1 etc. in \fBalias_maps\fR, because that
+# would open a security hole.
+#
+# The \fBlocal\fR(8) delivery agent will silently ignore
+# requests to use the \fBproxymap\fR(8) server within
+# \fBalias_maps\fR. Instead it will open the table directly.
+# Before Postfix version 2.2, the \fBlocal\fR(8) delivery
+# agent will terminate with a fatal error.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# The following \fBmain.cf\fR parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# \fBpostconf\fR(5) for more details including examples.
+# .IP "\fBalias_database (see 'postconf -d' output)\fR"
+# The alias databases for \fBlocal\fR(8) delivery that are updated with
+# "\fBnewaliases\fR" or with "\fBsendmail -bi\fR".
+# .IP "\fBalias_maps (see 'postconf -d' output)\fR"
+# The alias databases that are used for \fBlocal\fR(8) delivery.
+# .IP "\fBallow_mail_to_commands (alias, forward)\fR"
+# Restrict \fBlocal\fR(8) mail delivery to external commands.
+# .IP "\fBallow_mail_to_files (alias, forward)\fR"
+# Restrict \fBlocal\fR(8) mail delivery to external files.
+# .IP "\fBexpand_owner_alias (no)\fR"
+# When delivering to an alias "\fIaliasname\fR" that has an
+# "owner-\fIaliasname\fR" companion alias, set the envelope sender
+# address to the expansion of the "owner-\fIaliasname\fR" alias.
+# .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR"
+# What address lookup tables copy an address extension from the lookup
+# key to the lookup result.
+# .IP "\fBowner_request_special (yes)\fR"
+# Enable special treatment for owner-\fIlistname\fR entries in the
+# \fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and
+# \fIlistname\fR-request address localparts when the recipient_delimiter
+# is set to "-".
+# .IP "\fBrecipient_delimiter (empty)\fR"
+# The set of characters that can separate an email address
+# localpart, user name, or a .forward file name from its extension.
+# .PP
+# Available in Postfix version 2.3 and later:
+# .IP "\fBfrozen_delivered_to (yes)\fR"
+# Update the \fBlocal\fR(8) delivery agent's idea of the Delivered-To:
+# address (see prepend_delivered_header) only once, at the start of
+# a delivery attempt; do not update the Delivered-To: address while
+# expanding aliases or .forward files.
+# STANDARDS
+# RFC 822 (ARPA Internet Text Messages)
+# SEE ALSO
+# local(8), local delivery agent
+# newaliases(1), create/update alias database
+# postalias(1), create/update alias database
+# postconf(5), configuration parameters
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/aliases0 b/proto/aliases0
new file mode 100644
index 0000000..b00a3e1
--- /dev/null
+++ b/proto/aliases0
@@ -0,0 +1,38 @@
+#
+# Sample aliases file. Install in the location as specified by the
+# output from the command "postconf alias_maps". Typical path names
+# are /etc/aliases or /etc/mail/aliases.
+#
+# >>>>>>>>>> The program "newaliases" must be run after
+# >> NOTE >> this file is updated for any changes to
+# >>>>>>>>>> show through to Postfix.
+#
+
+# Person who should get root's mail. Don't receive mail as root!
+#root: you
+
+# Basic system aliases -- these MUST be present
+MAILER-DAEMON: postmaster
+postmaster: root
+
+# General redirections for pseudo accounts
+bin: root
+daemon: root
+named: root
+nobody: root
+uucp: root
+www: root
+ftp-bugs: root
+postfix: root
+
+# Put your local aliases here.
+
+# Well-known aliases
+manager: root
+dumper: root
+operator: root
+abuse: postmaster
+
+# trap decode to catch security attacks
+decode: root
+
diff --git a/proto/bounce b/proto/bounce
new file mode 100644
index 0000000..e7f5815
--- /dev/null
+++ b/proto/bounce
@@ -0,0 +1,214 @@
+#++
+# NAME
+# bounce 5
+# SUMMARY
+# Postfix bounce message template format
+# SYNOPSIS
+# \fBbounce_template_file = /etc/postfix/bounce.cf\fR
+#
+# \fBpostconf -b\fR [\fItemplate_file\fR]
+# DESCRIPTION
+# The Postfix \fBbounce\fR(8) server produces delivery status
+# notification (DSN) messages for undeliverable mail, delayed
+# mail, successful delivery or address verification requests.
+#
+# By default, these notifications are generated from built-in
+# templates with message headers and message text. Sites can
+# override the built-in information by specifying a bounce
+# template file with the \fBbounce_template_file\fR configuration
+# parameter.
+#
+# This document describes the general procedure to create a
+# bounce template file, followed by the specific details of
+# bounce template formats.
+# GENERAL PROCEDURE
+# .ad
+# .fi
+# To create a customized bounce template file, create a
+# temporary
+# copy of the file \fB/etc/postfix/bounce.cf.default\fR and
+# edit the temporary file.
+#
+# To preview the results of $\fIname\fR expansions in the
+# template text, use the command
+#
+# .nf
+# \fBpostconf -b\fR \fItemporary_file\fR
+# .fi
+#
+# Errors in the template will be reported to the standard
+# error stream and to the syslog daemon.
+#
+# While previewing the text, be sure to pay particular attention
+# to the expansion of time value parameters that appear in
+# the delayed mail notification text.
+#
+# Once the result is satisfactory, copy the template to the
+# Postfix configuration directory and specify in main.cf
+# something like:
+#
+# .nf
+# /etc/postfix/main.cf:
+# bounce_template_file = /etc/postfix/bounce.cf
+# .fi
+# TEMPLATE FILE FORMAT
+# .ad
+# .fi
+# The template file can specify templates for failed mail,
+# delayed mail, successful delivery or for address verification.
+# These templates are named \fBfailure_template\fR,
+# \fBdelay_template\fR, \fBsuccess_template\fR and
+# \fBverify_template\fR, respectively. You can but do not
+# have to specify all four templates in a bounce template
+# file.
+#
+# Each template starts with "\fItemplate_name\fB = <<EOF\fR"
+# and ends with a line that contains the word "\fBEOF\fR"
+# only. You can change the word EOF, but you can't enclose
+# it in quotes as with the shell or with Perl (\fItemplate_name\fB
+# = <<'EOF'\fR). Here is an example:
+#
+# .nf
+# # The failure template is used for undeliverable mail.
+#
+# failure_template = <<EOF
+# Charset: us-ascii
+# From: MAILER-DAEMON (Mail Delivery System)
+# Subject: Undelivered Mail Returned to Sender
+# Postmaster-Subject: Postmaster Copy: Undelivered Mail
+#
+# This is the mail system at host $myhostname.
+#
+# I'm sorry to have to inform you that your message could not
+# be delivered to one or more recipients. It's attached below.
+#
+# For further assistance, please send mail to postmaster.
+#
+# If you do so, please include this problem report. You can
+# delete your own text from the attached returned message.
+#
+# The mail system
+# EOF
+# .fi
+# .PP
+# The usage and specification of bounce templates is
+# subject to the following restrictions:
+# .IP \(bu
+# No special meaning is given to the backslash character or
+# to leading whitespace; these are always taken literally.
+# .IP \(bu
+# Inside the << context, the "$" character is special. To
+# produce a "$" character as output, specify "$$".
+# .IP \(bu
+# Outside the << context, lines beginning with "#" are ignored,
+# as are empty lines, and lines consisting of whitespace only.
+# .PP
+# Examples of all templates can be found in the file
+# \fBbounce.cf.default\fR in the Postfix configuration
+# directory.
+# TEMPLATE HEADER FORMAT
+# .ad
+# .fi
+# The first portion of a bounce template consists of optional
+# template headers. Some become message headers in the
+# delivery status notification; some control the formatting
+# of that notification. Headers not specified in a template
+# will be left at their default value.
+#
+# The following headers are supported:
+# .IP \fBCharset:\fR
+# The MIME character set of the template message text. See
+# the "TEMPLATE MESSAGE TEXT FORMAT" description below.
+# .IP \fBFrom:\fR
+# The sender address in the message header of the delivery
+# status notification.
+# .IP \fBSubject:\fR
+# The subject in the message header of the delivery status
+# notification that is returned to the sender.
+# .IP \fBPostmaster-Subject:\fR
+# The subject that will be used in Postmaster copies of
+# undeliverable or delayed mail notifications. These copies
+# are sent under control of the notify_classes configuration
+# parameter.
+# .PP
+# The usage and specification of template message headers is
+# subject to the following restrictions:
+# .IP \(bu
+# Template message header names can be specified in upper
+# case, lower case or mixed case. Postfix always produces
+# bounce message header labels of the form "\fBFrom:\fR" and
+# "\fBSubject:\fR".
+# .IP \(bu
+# Template message headers must not span multiple lines.
+# .IP \(bu
+# Template message headers do not support $parameter expansions.
+# .IP \(bu
+# Template message headers must contain ASCII characters only,
+# and must not contain ASCII null characters.
+# TEMPLATE MESSAGE TEXT FORMAT
+# .ad
+# .fi
+# The second portion of a bounce template consists of message
+# text. As the above example shows, template message text may
+# contain main.cf $parameters. Besides the parameters that are
+# defined in main.cf, the following parameters are treated
+# specially depending on the suffix that is appended to their
+# name.
+# .IP \fBdelay_warning_time_\fIsuffix\fR
+# Expands into the value of the \fBdelay_warning_time\fR
+# parameter, expressed in the time unit specified by
+# \fIsuffix\fR, which is one of \fBseconds\fR, \fBminutes\fR,
+# \fBhours\fB, \fBdays\fR, or \fBweeks\fR.
+# .IP \fBmaximal_queue_lifetime_\fIsuffix\fR
+# Expands into the value of the \fBmaximal_queue_lifetime\fR
+# parameter, expressed in the time unit specified by
+# \fIsuffix\fR. See above under \fBdelay_warning_time\fR for
+# possible \fIsuffix\fR values.
+# .IP \fBmydomain\fR
+# Expands into the value of the \fBmydomain\fR parameter.
+# With "smtputf8_enable = yes", this replaces ACE labels
+# (xn--mumble) with their UTF-8 equivalent.
+# .sp
+# This feature is available in Postfix 3.0.
+# .IP \fBmyhostname\fR
+# Expands into the value of the \fBmyhostname\fR parameter.
+# With "smtputf8_enable = yes", this replaces ACE labels
+# (xn--mumble) with their UTF-8 equivalent.
+# .sp
+# This feature is available in Postfix 3.0.
+# .PP
+# The usage and specification of template message text is
+# subject to the following restrictions:
+# .IP \(bu
+# The template message text is not sent in Postmaster copies
+# of delivery status notifications.
+# .IP \(bu
+# If the template message text contains non-ASCII characters,
+# Postfix requires that the \fBCharset:\fR template header
+# is updated. Specify an appropriate superset of US-ASCII.
+# A superset is needed because Postfix appends ASCII text
+# after the message template when it sends a delivery status
+# notification.
+# SEE ALSO
+# bounce(8), Postfix delivery status notifications
+# postconf(5), configuration parameters
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# .ad
+# .fi
+# The Postfix bounce template format was originally developed by
+# Nicolas Riendeau.
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/canonical b/proto/canonical
new file mode 100644
index 0000000..6364d3e
--- /dev/null
+++ b/proto/canonical
@@ -0,0 +1,273 @@
+#++
+# NAME
+# canonical 5
+# SUMMARY
+# Postfix canonical table format
+# SYNOPSIS
+# \fBpostmap /etc/postfix/canonical\fR
+#
+# \fBpostmap -q "\fIstring\fB" /etc/postfix/canonical\fR
+#
+# \fBpostmap -q - /etc/postfix/canonical <\fIinputfile\fR
+# DESCRIPTION
+# The optional \fBcanonical\fR(5) table specifies an address mapping for
+# local and non-local addresses. The mapping is used by the
+# \fBcleanup\fR(8) daemon, before mail is stored into the
+# queue. The address mapping is recursive.
+#
+# Normally, the \fBcanonical\fR(5) table is specified as a text file
+# that serves as input to the \fBpostmap\fR(1) command.
+# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
+# is used for fast searching by the mail system. Execute the command
+# "\fBpostmap /etc/postfix/canonical\fR" to rebuild an indexed
+# file after changing the corresponding text file.
+#
+# When the table is provided via other means such as NIS, LDAP
+# or SQL, the same lookups are done as for ordinary indexed files.
+#
+# Alternatively, the table can be provided as a regular-expression
+# map where patterns are given as regular expressions, or lookups
+# can be directed to a TCP-based server. In those cases, the lookups
+# are done in a slightly different way as described below under
+# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES".
+#
+# By default the \fBcanonical\fR(5) mapping affects both message
+# header addresses (i.e. addresses that appear inside messages)
+# and message envelope addresses (for example, the addresses
+# that are used in SMTP protocol commands). This is controlled with
+# the \fBcanonical_classes\fR parameter.
+#
+# NOTE: Postfix versions 2.2 and later rewrite message headers
+# from remote SMTP clients only if the client matches the
+# local_header_rewrite_clients parameter, or if the
+# remote_header_rewrite_domain configuration parameter specifies
+# a non-empty value. To get the behavior before Postfix 2.2,
+# specify "local_header_rewrite_clients = static:all".
+#
+# Typically, one would use the \fBcanonical\fR(5) table to replace login
+# names by \fIFirstname.Lastname\fR, or to clean up addresses produced
+# by legacy mail systems.
+#
+# The \fBcanonical\fR(5) mapping is not to be confused with \fIvirtual
+# alias\fR support or with local aliasing. To change the destination
+# but not the headers, use the \fBvirtual\fR(5) or \fBaliases\fR(5)
+# map instead.
+# CASE FOLDING
+# .ad
+# .fi
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+# TABLE FORMAT
+# .ad
+# .fi
+# The input format for the \fBpostmap\fR(1) command is as follows:
+# .IP "\fIpattern address\fR"
+# When \fIpattern\fR matches a mail address, replace it by the
+# corresponding \fIaddress\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# TABLE SEARCH ORDER
+# .ad
+# .fi
+# With lookups from indexed files such as DB or DBM, or from networked
+# tables such as NIS, LDAP or SQL, each \fIuser\fR@\fIdomain\fR
+# query produces a sequence of query patterns as described below.
+#
+# Each query pattern is sent to each specified lookup table
+# before trying the next query pattern, until a match is
+# found.
+# .IP "\fIuser\fR@\fIdomain address\fR"
+# Replace \fIuser\fR@\fIdomain\fR by \fIaddress\fR. This form
+# has the highest precedence.
+# .sp
+# This is useful to clean up addresses produced by legacy mail systems.
+# It can also be used to produce \fIFirstname.Lastname\fR style
+# addresses, but see below for a simpler solution.
+# .IP "\fIuser address\fR"
+# Replace \fIuser\fR@\fIsite\fR by \fIaddress\fR when \fIsite\fR is
+# equal to $\fBmyorigin\fR, when \fIsite\fR is listed in
+# $\fBmydestination\fR, or when it is listed in $\fBinet_interfaces\fR
+# or $\fBproxy_interfaces\fR.
+# .sp
+# This form is useful for replacing login names by
+# \fIFirstname.Lastname\fR.
+# .IP "@\fIdomain address\fR"
+# Replace other addresses in \fIdomain\fR by \fIaddress\fR.
+# This form has the lowest precedence.
+# .sp
+# Note: @\fIdomain\fR is a wild-card. When this form is applied
+# to recipient addresses, the Postfix SMTP server accepts
+# mail for any recipient in \fIdomain\fR, regardless of whether
+# that recipient exists. This may turn your mail system into
+# a backscatter source: Postfix first accepts mail for
+# non-existent recipients and then tries to return that mail
+# as "undeliverable" to the often forged sender address.
+# .sp
+# To avoid backscatter with mail for a wild-card domain,
+# replace the wild-card mapping with explicit 1:1 mappings,
+# or add a reject_unverified_recipient restriction for that
+# domain:
+#
+# .nf
+# smtpd_recipient_restrictions =
+# ...
+# reject_unauth_destination
+# check_recipient_access
+# inline:{example.com=reject_unverified_recipient}
+# unverified_recipient_reject_code = 550
+# .fi
+#
+# In the above example, Postfix may contact a remote server
+# if the recipient is rewritten to a remote address.
+# RESULT ADDRESS REWRITING
+# .ad
+# .fi
+# The lookup result is subject to address rewriting:
+# .IP \(bu
+# When the result has the form @\fIotherdomain\fR, the
+# result becomes the same \fIuser\fR in \fIotherdomain\fR.
+# .IP \(bu
+# When "\fBappend_at_myorigin=yes\fR", append "\fB@$myorigin\fR"
+# to addresses without "@domain".
+# .IP \(bu
+# When "\fBappend_dot_mydomain=yes\fR", append
+# "\fB.$mydomain\fR" to addresses without ".domain".
+# ADDRESS EXTENSION
+# .fi
+# .ad
+# When a mail address localpart contains the optional recipient delimiter
+# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
+# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
+# \fIuser\fR, and @\fIdomain\fR.
+#
+# The \fBpropagate_unmatched_extensions\fR parameter controls whether
+# an unmatched address extension (\fI+foo\fR) is propagated to the
+# result of table lookup.
+# REGULAR EXPRESSION TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when the table
+# is given in the form of regular expressions. For a description of
+# regular expression lookup table syntax, see \fBregexp_table\fR(5)
+# or \fBpcre_table\fR(5).
+#
+# Each pattern is a regular expression that is applied to the entire
+# address being looked up. Thus, \fIuser@domain\fR mail addresses are not
+# broken up into their \fIuser\fR and \fI@domain\fR constituent parts,
+# nor is \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the search string.
+#
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from the
+# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on.
+# TCP-BASED TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when lookups
+# are directed to a TCP-based server. For a description of the TCP
+# client/server lookup protocol, see \fBtcp_table\fR(5).
+# This feature is not available up to and including Postfix version 2.4.
+#
+# Each lookup operation uses the entire address once. Thus,
+# \fIuser@domain\fR mail addresses are not broken up into their
+# \fIuser\fR and \fI@domain\fR constituent parts, nor is
+# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Results are the same as with indexed file lookups.
+# BUGS
+# The table format does not understand quoting conventions.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# The following \fBmain.cf\fR parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# \fBpostconf\fR(5) for more details including examples.
+# .IP "\fBcanonical_classes (envelope_sender, envelope_recipient, header_sender, header_recipient)\fR"
+# What addresses are subject to canonical_maps address mapping.
+# .IP "\fBcanonical_maps (empty)\fR"
+# Optional address mapping lookup tables for message headers and
+# envelopes.
+# .IP "\fBrecipient_canonical_maps (empty)\fR"
+# Optional address mapping lookup tables for envelope and header
+# recipient addresses.
+# .IP "\fBsender_canonical_maps (empty)\fR"
+# Optional address mapping lookup tables for envelope and header
+# sender addresses.
+# .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR"
+# What address lookup tables copy an address extension from the lookup
+# key to the lookup result.
+# .PP
+# Other parameters of interest:
+# .IP "\fBinet_interfaces (all)\fR"
+# The network interface addresses that this mail system receives
+# mail on.
+# .IP "\fBlocal_header_rewrite_clients (permit_inet_interfaces)\fR"
+# Rewrite message header addresses in mail from these clients and
+# update incomplete addresses with the domain name in $myorigin or
+# $mydomain; either don't rewrite message headers from other clients
+# at all, or rewrite message headers and update incomplete addresses
+# with the domain specified in the remote_header_rewrite_domain
+# parameter.
+# .IP "\fBproxy_interfaces (empty)\fR"
+# The network interface addresses that this mail system receives mail
+# on by way of a proxy or network address translation unit.
+# .IP "\fBmasquerade_classes (envelope_sender, header_sender, header_recipient)\fR"
+# What addresses are subject to address masquerading.
+# .IP "\fBmasquerade_domains (empty)\fR"
+# Optional list of domains whose subdomain structure will be stripped
+# off in email addresses.
+# .IP "\fBmasquerade_exceptions (empty)\fR"
+# Optional list of user names that are not subjected to address
+# masquerading, even when their addresses match $masquerade_domains.
+# .IP "\fBmydestination ($myhostname, localhost.$mydomain, localhost)\fR"
+# The list of domains that are delivered via the $local_transport
+# mail delivery transport.
+# .IP "\fBmyorigin ($myhostname)\fR"
+# The domain name that locally-posted mail appears to come
+# from, and that locally posted mail is delivered to.
+# .IP "\fBowner_request_special (yes)\fR"
+# Enable special treatment for owner-\fIlistname\fR entries in the
+# \fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and
+# \fIlistname\fR-request address localparts when the recipient_delimiter
+# is set to "-".
+# .IP "\fBremote_header_rewrite_domain (empty)\fR"
+# Don't rewrite message headers from remote clients at all when
+# this parameter is empty; otherwise, rewrite message headers and
+# append the specified domain name to incomplete addresses.
+# SEE ALSO
+# cleanup(8), canonicalize and enqueue mail
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# virtual(5), virtual aliasing
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# ADDRESS_REWRITING_README, address rewriting guide
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/cidr_table b/proto/cidr_table
new file mode 100644
index 0000000..9eed9ce
--- /dev/null
+++ b/proto/cidr_table
@@ -0,0 +1,176 @@
+#++
+# NAME
+# cidr_table 5
+# SUMMARY
+# format of Postfix CIDR tables
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" cidr:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - cidr:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional lookup tables.
+# These tables are usually in \fBdbm\fR or \fBdb\fR format.
+# Alternatively, lookup tables can be specified in CIDR
+# (Classless Inter-Domain Routing) form. In this case, each
+# input is compared against a list of patterns. When a match
+# is found, the corresponding result is returned and the search
+# is terminated.
+#
+# To find out what types of lookup tables your Postfix system
+# supports use the "\fBpostconf -m\fR" command.
+#
+# To test lookup tables, use the "\fBpostmap -q\fR" command as
+# described in the SYNOPSIS above.
+# TABLE FORMAT
+# .ad
+# .fi
+# The general form of a Postfix CIDR table is:
+# .IP "\fIpattern result\fR"
+# When a search string matches the specified \fIpattern\fR, use
+# the corresponding \fIresult\fR value. The \fIpattern\fR must be
+# in \fInetwork/prefix\fR or \fInetwork_address\fR form (see
+# ADDRESS PATTERN SYNTAX below).
+# .IP "\fB!\fIpattern result\fR"
+# When a search string does not match the specified \fIpattern\fR,
+# use the specified \fIresult\fR value. The \fIpattern\fR must
+# be in \fInetwork/prefix\fR or \fInetwork_address\fR form (see
+# ADDRESS PATTERN SYNTAX below).
+# .sp
+# This feature is available in Postfix 3.2 and later.
+# .IP "\fBif \fIpattern\fR"
+# .IP "\fBendif\fR"
+# When a search string matches the specified \fIpattern\fR, match
+# that search string against the patterns between \fBif\fR and
+# \fBendif\fR. The \fIpattern\fR must be in \fInetwork/prefix\fR or
+# \fInetwork_address\fR form (see ADDRESS PATTERN SYNTAX below). The
+# \fBif\fR..\fBendif\fR can nest.
+# .sp
+# Note: do not prepend whitespace to text between
+# \fBif\fR..\fBendif\fR.
+# .sp
+# This feature is available in Postfix 3.2 and later.
+# .IP "\fBif !\fIpattern\fR"
+# .IP "\fBendif\fR"
+# When a search string does not match the specified \fIpattern\fR,
+# match that search string against the patterns between \fBif\fR and
+# \fBendif\fR. The \fIpattern\fR must be in \fInetwork/prefix\fR or
+# \fInetwork_address\fR form (see ADDRESS PATTERN SYNTAX below). The
+# \fBif\fR..\fBendif\fR can nest.
+# .sp
+# Note: do not prepend whitespace to text between
+# \fBif\fR..\fBendif\fR.
+# .sp
+# This feature is available in Postfix 3.2 and later.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# TABLE SEARCH ORDER
+# .ad
+# .fi
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the search string.
+# ADDRESS PATTERN SYNTAX
+# .ad
+# .fi
+# Postfix CIDR tables are pattern-based. A pattern is either
+# a \fInetwork_address\fR which requires an exact match, or a
+# \fInetwork_address/prefix_length\fR where the \fIprefix_length\fR
+# part specifies the length of the \fInetwork_address\fR prefix
+# that must be matched (the other bits in the \fInetwork_address\fR
+# part must be zero).
+#
+# An IPv4 network address is a sequence of four decimal octets
+# separated by ".", and an IPv6 network address is a sequence
+# of three to eight hexadecimal octet pairs separated by ":"
+# or "::", where the latter is short-hand for a sequence of
+# one or more all-zero octet pairs. The pattern 0.0.0.0/0
+# matches every IPv4 address, and ::/0 matches every IPv6
+# address. IPv6 support is available in Postfix 2.2 and
+# later.
+#
+# Before comparisons are made, lookup keys and table entries
+# are converted from string to binary. Therefore, IPv6 patterns
+# will be matched regardless of leading zeros (a leading zero in
+# an IPv4 address octet indicates octal notation).
+#
+# Note: address information may be enclosed inside "[]" but
+# this form is not required.
+# INLINE SPECIFICATION
+# .ad
+# .fi
+# The contents of a table may be specified in the table name
+# (Postfix 3.7 and later).
+# The basic syntax is:
+#
+# .nf
+# main.cf:
+# \fIparameter\fR \fB= .. cidr:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR
+#
+# master.cf:
+# \fB.. -o { \fIparameter\fR \fB= .. cidr:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
+# .fi
+#
+# Postfix ignores whitespace after '{' and before '}', and
+# writes each \fIrule\fR as one text line to an in-memory
+# file:
+#
+# .nf
+# in-memory file:
+# rule-1
+# rule-2
+# ..
+# .fi
+#
+# Postfix parses the result as if it is a file in /etc/postfix.
+#
+# Note: if a rule contains \fB$\fR, specify \fB$$\fR to keep
+# Postfix from trying to do \fI$name\fR expansion as it
+# evaluates a parameter value.
+# EXAMPLE SMTPD ACCESS MAP
+# .nf
+# /etc/postfix/main.cf:
+# smtpd_client_restrictions = ... cidr:/etc/postfix/client.cidr ...
+#
+# /etc/postfix/client.cidr:
+# # Rule order matters. Put more specific allowlist entries
+# # before more general denylist entries.
+# 192.168.1.1 OK
+# 192.168.0.0/16 REJECT
+# 2001:db8::1 OK
+# 2001:db8::/32 REJECT
+# .fi
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# regexp_table(5), format of regular expression tables
+# pcre_table(5), format of PCRE tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# HISTORY
+# CIDR table support was introduced with Postfix version 2.1.
+# AUTHOR(S)
+# The CIDR table lookup code was originally written by:
+# Jozsef Kadlecsik
+# KFKI Research Institute for Particle and Nuclear Physics
+# POB. 49
+# 1525 Budapest, Hungary
+#
+# Adopted and adapted by:
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/generic b/proto/generic
new file mode 100644
index 0000000..fdeb1ea
--- /dev/null
+++ b/proto/generic
@@ -0,0 +1,239 @@
+#++
+# NAME
+# generic 5
+# SUMMARY
+# Postfix generic table format
+# SYNOPSIS
+# \fBpostmap /etc/postfix/generic\fR
+#
+# \fBpostmap -q "\fIstring\fB" /etc/postfix/generic\fR
+#
+# \fBpostmap -q - /etc/postfix/generic <\fIinputfile\fR
+# DESCRIPTION
+# The optional \fBgeneric\fR(5) table specifies an address
+# mapping that applies when mail is delivered. This is the
+# opposite of \fBcanonical\fR(5) mapping, which applies when
+# mail is received.
+#
+# Typically, one would use the \fBgeneric\fR(5) table on a
+# system that does not have a valid Internet domain name and
+# that uses something like \fIlocaldomain.local\fR instead.
+# The \fBgeneric\fR(5) table is then used by the \fBsmtp\fR(8)
+# client to transform local mail addresses into valid Internet
+# mail addresses when mail has to be sent across the Internet.
+# See the EXAMPLE section at the end of this document.
+#
+# The \fBgeneric\fR(5) mapping affects both message header
+# addresses (i.e. addresses that appear inside messages) and
+# message envelope addresses (for example, the addresses that
+# are used in SMTP protocol commands).
+#
+# Normally, the \fBgeneric\fR(5) table is specified as a
+# text file that serves as input to the \fBpostmap\fR(1)
+# command. The result, an indexed file in \fBdbm\fR or
+# \fBdb\fR format, is used for fast searching by the mail
+# system. Execute the command "\fBpostmap /etc/postfix/generic\fR"
+# to rebuild an indexed file after changing the corresponding
+# text file.
+#
+# When the table is provided via other means such as NIS, LDAP
+# or SQL, the same lookups are done as for ordinary indexed files.
+#
+# Alternatively, the table can be provided as a regular-expression
+# map where patterns are given as regular expressions, or lookups
+# can be directed to a TCP-based server. In those cases, the lookups
+# are done in a slightly different way as described below under
+# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES".
+# CASE FOLDING
+# .ad
+# .fi
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+# TABLE FORMAT
+# .ad
+# .fi
+# The input format for the \fBpostmap\fR(1) command is as follows:
+# .IP "\fIpattern result\fR"
+# When \fIpattern\fR matches a mail address, replace it by the
+# corresponding \fIresult\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# TABLE SEARCH ORDER
+# .ad
+# .fi
+# With lookups from indexed files such as DB or DBM, or from networked
+# tables such as NIS, LDAP or SQL, each \fIuser\fR@\fIdomain\fR
+# query produces a sequence of query patterns as described below.
+#
+# Each query pattern is sent to each specified lookup table
+# before trying the next query pattern, until a match is
+# found.
+# .IP "\fIuser\fR@\fIdomain address\fR"
+# Replace \fIuser\fR@\fIdomain\fR by \fIaddress\fR. This form
+# has the highest precedence.
+# .IP "\fIuser address\fR"
+# Replace \fIuser\fR@\fIsite\fR by \fIaddress\fR when \fIsite\fR is
+# equal to $\fBmyorigin\fR, when \fIsite\fR is listed in
+# $\fBmydestination\fR, or when it is listed in $\fBinet_interfaces\fR
+# or $\fBproxy_interfaces\fR.
+# .IP "@\fIdomain address\fR"
+# Replace other addresses in \fIdomain\fR by \fIaddress\fR.
+# This form has the lowest precedence.
+# RESULT ADDRESS REWRITING
+# .ad
+# .fi
+# The lookup result is subject to address rewriting:
+# .IP \(bu
+# When the result has the form @\fIotherdomain\fR, the
+# result becomes the same \fIuser\fR in \fIotherdomain\fR.
+# .IP \(bu
+# When "\fBappend_at_myorigin=yes\fR", append "\fB@$myorigin\fR"
+# to addresses without "@domain".
+# .IP \(bu
+# When "\fBappend_dot_mydomain=yes\fR", append
+# "\fB.$mydomain\fR" to addresses without ".domain".
+# ADDRESS EXTENSION
+# .fi
+# .ad
+# When a mail address localpart contains the optional recipient delimiter
+# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
+# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
+# \fIuser\fR, and @\fIdomain\fR.
+#
+# The \fBpropagate_unmatched_extensions\fR parameter controls whether
+# an unmatched address extension (\fI+foo\fR) is propagated to the
+# result of table lookup.
+# REGULAR EXPRESSION TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when the table
+# is given in the form of regular expressions. For a description of
+# regular expression lookup table syntax, see \fBregexp_table\fR(5)
+# or \fBpcre_table\fR(5).
+#
+# Each pattern is a regular expression that is applied to the entire
+# address being looked up. Thus, \fIuser@domain\fR mail addresses are not
+# broken up into their \fIuser\fR and \fI@domain\fR constituent parts,
+# nor is \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the search string.
+#
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from the
+# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on.
+# TCP-BASED TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when lookups
+# are directed to a TCP-based server. For a description of the TCP
+# client/server lookup protocol, see \fBtcp_table\fR(5).
+# This feature is available in Postfix 2.5 and later.
+#
+# Each lookup operation uses the entire address once. Thus,
+# \fIuser@domain\fR mail addresses are not broken up into their
+# \fIuser\fR and \fI@domain\fR constituent parts, nor is
+# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Results are the same as with indexed file lookups.
+# EXAMPLE
+# .ad
+# .fi
+# The following shows a generic mapping with an indexed file.
+# When mail is sent to a remote host via SMTP, this replaces
+# \fIhis@localdomain.local\fR by his ISP mail address, replaces
+# \fIher@localdomain.local\fR by her ISP mail address, and
+# replaces other local addresses by his ISP account, with
+# an address extension of \fI+local\fR (this example assumes
+# that the ISP supports "+" style address extensions).
+#
+# .na
+# .nf
+# /etc/postfix/main.cf:
+# smtp_generic_maps = hash:/etc/postfix/generic
+#
+# /etc/postfix/generic:
+# his@localdomain.local hisaccount@hisisp.example
+# her@localdomain.local heraccount@herisp.example
+# @localdomain.local hisaccount+local@hisisp.example
+#
+# .ad
+# .fi
+# Execute the command "\fBpostmap /etc/postfix/generic\fR"
+# whenever the table is changed. Instead of \fBhash\fR, some
+# systems use \fBdbm\fR database files. To find out what
+# tables your system supports use the command "\fBpostconf
+# -m\fR".
+# BUGS
+# The table format does not understand quoting conventions.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# The following \fBmain.cf\fR parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# \fBpostconf\fR(5) for more details including examples.
+# .IP "\fBsmtp_generic_maps (empty)\fR"
+# Optional lookup tables that perform address rewriting in the
+# Postfix SMTP client, typically to transform a locally valid address into
+# a globally valid address when sending mail across the Internet.
+# .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR"
+# What address lookup tables copy an address extension from the lookup
+# key to the lookup result.
+# .PP
+# Other parameters of interest:
+# .IP "\fBinet_interfaces (all)\fR"
+# The network interface addresses that this mail system receives
+# mail on.
+# .IP "\fBproxy_interfaces (empty)\fR"
+# The network interface addresses that this mail system receives mail
+# on by way of a proxy or network address translation unit.
+# .IP "\fBmydestination ($myhostname, localhost.$mydomain, localhost)\fR"
+# The list of domains that are delivered via the $local_transport
+# mail delivery transport.
+# .IP "\fBmyorigin ($myhostname)\fR"
+# The domain name that locally-posted mail appears to come
+# from, and that locally posted mail is delivered to.
+# .IP "\fBowner_request_special (yes)\fR"
+# Enable special treatment for owner-\fIlistname\fR entries in the
+# \fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and
+# \fIlistname\fR-request address localparts when the recipient_delimiter
+# is set to "-".
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# smtp(8), Postfix SMTP client
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# ADDRESS_REWRITING_README, address rewriting guide
+# DATABASE_README, Postfix lookup table overview
+# STANDARD_CONFIGURATION_README, configuration examples
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# A genericstable feature appears in the Sendmail MTA.
+#
+# This feature is available in Postfix 2.2 and later.
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/header_checks b/proto/header_checks
new file mode 100644
index 0000000..1aa6f5a
--- /dev/null
+++ b/proto/header_checks
@@ -0,0 +1,520 @@
+#++
+# NAME
+# header_checks 5
+# SUMMARY
+# Postfix built-in content inspection
+# SYNOPSIS
+# .nf
+# \fBheader_checks = pcre:/etc/postfix/header_checks\fR
+# \fBmime_header_checks = pcre:/etc/postfix/mime_header_checks\fR
+# \fBnested_header_checks = pcre:/etc/postfix/nested_header_checks\fR
+# \fBbody_checks = pcre:/etc/postfix/body_checks\fR
+# .sp
+# \fBmilter_header_checks = pcre:/etc/postfix/milter_header_checks\fR
+# .sp
+# \fBsmtp_header_checks = pcre:/etc/postfix/smtp_header_checks\fR
+# \fBsmtp_mime_header_checks = pcre:/etc/postfix/smtp_mime_header_checks\fR
+# \fBsmtp_nested_header_checks = pcre:/etc/postfix/smtp_nested_header_checks\fR
+# \fBsmtp_body_checks = pcre:/etc/postfix/smtp_body_checks\fR
+# .sp
+# \fBpostmap -q "\fIstring\fB" pcre:/etc/postfix/\fIfilename\fR
+# \fBpostmap -q - pcre:/etc/postfix/\fIfilename\fR <\fIinputfile\fR
+# .fi
+# DESCRIPTION
+# This document describes access control on the content of
+# message headers and message body lines; it is implemented
+# by the Postfix \fBcleanup\fR(8) server before mail is queued.
+# See \fBaccess\fR(5) for access control on remote SMTP client
+# information.
+#
+# Each message header or message body line is compared against
+# a list of patterns.
+# When a match is found the corresponding action is executed, and
+# the matching process is repeated for the next message header or
+# message body line.
+#
+# Note: message headers are examined one logical header at a time,
+# even when a message header spans multiple lines. Body lines are
+# always examined one line at a time.
+#
+# For examples, see the EXAMPLES section at the end of this
+# manual page.
+#
+# Postfix header or body_checks are designed to stop a flood of mail
+# from worms or viruses; they do not decode attachments, and they do
+# not unzip archives. See the documents referenced below in the README
+# FILES section if you need more sophisticated content analysis.
+# FILTERS WHILE RECEIVING MAIL
+# .ad
+# .fi
+# Postfix implements the following four built-in content
+# inspection classes while receiving mail:
+# .IP "\fBheader_checks\fR (default: empty)"
+# These are applied to initial message headers (except for
+# the headers that are processed with \fBmime_header_checks\fR).
+# .IP "\fBmime_header_checks\fR (default: \fB$header_checks\fR)"
+# These are applied to MIME related message headers only.
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .IP "\fBnested_header_checks\fR (default: \fB$header_checks\fR)"
+# These are applied to message headers of attached email
+# messages (except for the headers that are processed with
+# \fBmime_header_checks\fR).
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .IP \fBbody_checks\fR
+# These are applied to all other content, including multi-part
+# message boundaries.
+# .sp
+# With Postfix versions before 2.0, all content after the initial
+# message headers is treated as body content.
+# FILTERS AFTER RECEIVING MAIL
+# .ad
+# .fi
+# Postfix supports a subset of the built-in content inspection
+# classes after the message is received:
+# .IP "\fBmilter_header_checks\fR (default: empty)"
+# These are applied to headers that are added with Milter
+# applications.
+# .sp
+# This feature is available in Postfix 2.7 and later.
+# FILTERS WHILE DELIVERING MAIL
+# .ad
+# .fi
+# Postfix supports all four content inspection classes while
+# delivering mail via SMTP.
+# .IP "\fBsmtp_header_checks\fR (default: empty)"
+# .IP "\fBsmtp_mime_header_checks\fR (default: empty)"
+# .IP "\fBsmtp_nested_header_checks\fR (default: empty)"
+# .IP "\fBsmtp_body_checks\fR (default: empty)"
+# These features are available in Postfix 2.5 and later.
+# COMPATIBILITY
+# .ad
+# .fi
+# With Postfix version 2.2 and earlier specify "\fBpostmap
+# -fq\fR" to query a table that contains case sensitive
+# patterns. By default, regexp: and pcre: patterns are case
+# insensitive.
+# TABLE FORMAT
+# .ad
+# .fi
+# This document assumes that header and body_checks rules are specified
+# in the form of Postfix regular expression lookup tables. Usually the
+# best performance is obtained with \fBpcre\fR (Perl Compatible Regular
+# Expression) tables. The \fBregexp\fR (POSIX regular
+# expressions) tables are usually slower, but more widely
+# available.
+# Use the command "\fBpostconf -m\fR" to find out what lookup table
+# types your Postfix system supports.
+#
+# The general format of Postfix regular expression tables is
+# given below.
+# For a discussion of specific pattern or flags syntax,
+# see \fBpcre_table\fR(5) or \fBregexp_table\fR(5), respectively.
+# .IP "\fB/\fIpattern\fB/\fIflags action\fR"
+# When /\fIpattern\fR/ matches the input string, execute
+# the corresponding \fIaction\fR. See below for a list
+# of possible actions.
+# .IP "\fB!/\fIpattern\fB/\fIflags action\fR"
+# When /\fIpattern\fR/ does \fBnot\fR match the input string,
+# execute the corresponding \fIaction\fR.
+# .IP "\fBif /\fIpattern\fB/\fIflags\fR"
+# .IP "\fBendif\fR"
+# If the input string matches /\fIpattern\fR/, then match that
+# input string against the patterns between \fBif\fR and
+# \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
+# .sp
+# Note: do not prepend whitespace to patterns inside
+# \fBif\fR..\fBendif\fR.
+# .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
+# .IP "\fBendif\fR"
+# If the input string does not match /\fIpattern\fR/, then
+# match that input string against the patterns between \fBif\fR
+# and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A pattern/action line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# TABLE SEARCH ORDER
+# .ad
+# .fi
+# For each line of message input, the patterns are applied in the
+# order as specified in the table. When a pattern is found that matches
+# the input line, the corresponding action is executed and then the
+# next input line is inspected.
+# TEXT SUBSTITUTION
+# .ad
+# .fi
+# Substitution of substrings from the matched expression into the
+# \fIaction\fR
+# string is possible using the conventional Perl syntax
+# (\fB$1\fR, \fB$2\fR, etc.).
+# The macros in the result string may need to be written as \fB${n}\fR
+# or \fB$(n)\fR if they aren't followed by whitespace.
+#
+# Note: since negated patterns (those preceded by \fB!\fR) return a
+# result when the expression does not match, substitutions are not
+# available for negated patterns.
+# ACTIONS
+# .ad
+# .fi
+# Action names are case insensitive. They are shown in upper case
+# for consistency with other Postfix documentation.
+# .IP "\fBBCC \fIuser@domain\fR"
+# Add the specified address as a BCC recipient, and inspect
+# the next input line. The address
+# must have a local part and domain part. The number of BCC
+# addresses that can be added is limited only by the amount
+# of available storage space.
+#
+# Note 1: the BCC address is added as if it was specified with
+# NOTIFY=NONE. The sender will not be notified when the BCC
+# address is undeliverable, as long as all down-stream software
+# implements RFC 3461.
+#
+# Note 2: this ignores duplicate addresses (with the same
+# delivery status notification options).
+# .sp
+# This feature is available in Postfix 3.0 and later.
+# .sp
+# This feature is not supported with smtp header/body checks.
+# \" .IP "\fBDELAY \fItime\fR"
+# \" Place the message into the deferred queue, and delay the
+# \" initial delivery attempt by \fItime\fR. The time value may
+# \" be followed by a one-character suffix that specifies the
+# \" time unit: s (seconds), m (minutes), h (hours), d (days),
+# \" w (weeks). The default time unit is s (seconds).
+# \" .sp
+# \" Limitations:
+# \" .RS
+# \" .IP \(bu
+# \" This action affects all the recipients of the message.
+# \" .IP \(bu
+# \" The delay value has no effect with remote file systems that
+# \" don't correctly emulate UNIX local file system semantics.
+# \" In that case, the delay will be half of $queue_run_delay
+# \" on average.
+# \" .IP \(bu
+# \" Mail will still be delivered with "sendmail -q", "postfix
+# \" flush" or "postqueue -f".
+# \" .IP \(bu
+# \" Delayed mail increases the amount of disk I/O during deferred
+# \" queue scans. When large amounts of mail are queued for
+# \" delayed delivery it may be preferable to use the HOLD feature
+# \" instead.
+# \" .RE
+# \" .IP
+# \" This feature is available in Postfix 2.3 and later.
+# .IP "\fBDISCARD \fIoptional text...\fR"
+# Claim successful delivery and silently discard the message.
+# Do not inspect the remainder of the input message.
+# Log the optional text if specified, otherwise log a generic
+# message.
+# .sp
+# Note: this action disables further header or body_checks inspection
+# of the current message and affects all recipients.
+# To discard only one recipient without discarding the entire message,
+# use the transport(5) table to direct mail to the discard(8) service.
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .sp
+# This feature is not supported with smtp header/body checks.
+# .IP \fBDUNNO\fR
+# Pretend that the input line did not match any pattern, and inspect the
+# next input line. This action can be used to shorten the table search.
+# .sp
+# For backwards compatibility reasons, Postfix also accepts
+# \fBOK\fR but it is (and always has been) treated as \fBDUNNO\fR.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .IP "\fBFILTER \fItransport:destination\fR"
+# Override the content_filter parameter setting, and inspect
+# the next input line.
+# After the message is queued, send the entire message through
+# the specified external content filter. The \fItransport\fR
+# name specifies the first field of a mail delivery agent
+# definition in master.cf; the syntax of the next-hop
+# \fIdestination\fR is described in the manual page of the
+# corresponding delivery agent. More information about
+# external content filters is in the Postfix FILTER_README
+# file.
+# .sp
+# Note 1: do not use $\fInumber\fR regular expression
+# substitutions for \fItransport\fR or \fIdestination\fR
+# unless you know that the information has a trusted origin.
+# .sp
+# Note 2: this action overrides the main.cf \fBcontent_filter\fR
+# setting, and affects all recipients of the message. In the
+# case that multiple \fBFILTER\fR actions fire, only the last
+# one is executed.
+# .sp
+# Note 3: the purpose of the FILTER command is to override
+# message routing. To override the recipient's \fItransport\fR
+# but not the next-hop \fIdestination\fR, specify an empty
+# filter \fIdestination\fR (Postfix 2.7 and later), or specify
+# a \fItransport:destination\fR that delivers through a
+# different Postfix instance (Postfix 2.6 and earlier). Other
+# options are using the recipient-dependent \fBtrans\%port\%_maps\fR
+# or the sen\%der-dependent
+# \fBsender\%_de\%pen\%dent\%_de\%fault\%_trans\%port\%_maps\fR
+# features.
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .sp
+# This feature is not supported with smtp header/body checks.
+# .IP "\fBHOLD \fIoptional text...\fR"
+# Arrange for the message to be placed on the \fBhold\fR queue,
+# and inspect the next input line. The message remains on \fBhold\fR
+# until someone either deletes it or releases it for delivery.
+# Log the optional text if specified, otherwise log a generic
+# message.
+#
+# Mail that is placed on hold can be examined with the
+# \fBpostcat\fR(1) command, and can be destroyed or released with
+# the \fBpostsuper\fR(1) command.
+# .sp
+# Note: use "\fBpostsuper -r\fR" to release mail that was kept on
+# hold for a significant fraction of \fB$maximal_queue_lifetime\fR
+# or \fB$bounce_queue_lifetime\fR, or longer. Use "\fBpostsuper -H\fR"
+# only for mail that will not expire within a few delivery attempts.
+# .sp
+# Note: this action affects all recipients of the message.
+# .sp
+# This feature is available in Postfix 2.0 and later.
+# .sp
+# This feature is not supported with smtp header/body checks.
+# .IP \fBIGNORE\fR
+# Delete the current line from the input, and inspect
+# the next input line. See \fBSTRIP\fR for an alternative
+# that logs the action.
+# .IP "\fBINFO \fIoptional text...\fR
+# Log an "info:" record with the \fIoptional text...\fR (or
+# log a generic text), and inspect the next input line. This
+# action is useful for routine logging or for debugging.
+# .sp
+# This feature is available in Postfix 2.8 and later.
+# .IP "\fBPASS \fIoptional text...\fR"
+# Log a "pass:" record with the \fIoptional text...\fR (or
+# log a generic text), and turn off header, body, and Milter
+# inspection for the remainder of this message.
+# .sp
+# Note: this feature relies on trust in information that is
+# easy to forge.
+# .sp
+# This feature is available in Postfix 3.2 and later.
+# .sp
+# This feature is not supported with smtp header/body checks.
+# .IP "\fBPREPEND \fItext...\fR"
+# Prepend one line with the specified text, and inspect the next
+# input line.
+# .sp
+# Notes:
+# .RS
+# .IP \(bu
+# The prepended text is output on a separate line, immediately
+# before the input that triggered the \fBPREPEND\fR action.
+# .IP \(bu
+# The prepended text is not considered part of the input
+# stream: it is not subject to header/body checks or address
+# rewriting, and it does not affect the way that Postfix adds
+# missing message headers.
+# .IP \(bu
+# When prepending text before a message header line, the prepended
+# text must begin with a valid message header label.
+# .IP \(bu
+# This action cannot be used to prepend multi-line text.
+# .RE
+# .IP
+# This feature is available in Postfix 2.1 and later.
+# .sp
+# This feature is not supported with milter_header_checks.
+# .IP "\fBREDIRECT \fIuser@domain\fR"
+# Write a message redirection request to the queue file, and
+# inspect the next input line. After the message is queued,
+# it will be sent to the specified address instead of the
+# intended recipient(s).
+# .sp
+# Note: this action overrides the \fBFILTER\fR action, and affects
+# all recipients of the message. If multiple \fBREDIRECT\fR actions
+# fire, only the last one is executed.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .sp
+# This feature is not supported with smtp header/body checks.
+# .IP "\fBREPLACE \fItext...\fR"
+# Replace the current line with the specified text, and inspect the next
+# input line.
+# .sp
+# This feature is available in Postfix 2.2 and later. The
+# description below applies to Postfix 2.2.2 and later.
+# .sp
+# Notes:
+# .RS
+# .IP \(bu
+# When replacing a message header line, the replacement text
+# must begin with a valid header label.
+# .IP \(bu
+# The replaced text remains part of the input stream. Unlike
+# the result from the \fBPREPEND\fR action, a replaced message
+# header may be subject to address rewriting and may affect
+# the way that Postfix adds missing message headers.
+# .RE
+# .IP "\fBREJECT \fIoptional text...\fR
+# Reject the entire message. Do not inspect the remainder of
+# the input message. Reply with \fIoptional text...\fR when
+# the optional text is specified, otherwise reply with a
+# generic error message.
+# .sp
+# Note: this action disables further header or body_checks inspection
+# of the current message and affects all recipients.
+# .sp
+# Postfix version 2.3 and later support enhanced status codes.
+# When no code is specified at the beginning of \fIoptional
+# text...\fR, Postfix inserts a default enhanced status code of
+# "5.7.1".
+# .sp
+# This feature is not supported with smtp header/body checks.
+# .IP "\fBSTRIP \fIoptional text...\fR"
+# Log a "strip:" record with the \fIoptional text...\fR (or
+# log a generic text), delete the input line from the input,
+# and inspect the next input line. See \fBIGNORE\fR for a
+# silent alternative.
+# .sp
+# This feature is available in Postfix 3.2 and later.
+# .IP "\fBWARN \fIoptional text...\fR
+# Log a "warning:" record with the \fIoptional text...\fR (or
+# log a generic text), and inspect the next input line. This
+# action is useful for debugging and for testing a pattern
+# before applying more drastic actions.
+# BUGS
+# Empty lines never match, because some map types mis-behave
+# when given a zero-length search string. This limitation may
+# be removed for regular expression tables in a future release.
+#
+# Many people overlook the main limitations of header and body_checks
+# rules.
+# .IP \(bu
+# These rules operate on one logical message header or one body
+# line at a time. A decision made for one line is not carried over
+# to the next line.
+# .IP \(bu
+# If text in the message body is encoded
+# (RFC 2045) then the rules need to be specified for the encoded
+# form.
+# .IP \(bu
+# Likewise, when message headers are encoded (RFC
+# 2047) then the rules need to be specified for the encoded
+# form.
+# .PP
+# Message headers added by the \fBcleanup\fR(8) daemon itself
+# are excluded from inspection. Examples of such message headers
+# are \fBFrom:\fR, \fBTo:\fR, \fBMessage-ID:\fR, \fBDate:\fR.
+#
+# Message headers deleted by the \fBcleanup\fR(8) daemon will
+# be examined before they are deleted. Examples are: \fBBcc:\fR,
+# \fBContent-Length:\fR, \fBReturn-Path:\fR.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# .IP \fBbody_checks\fR
+# Lookup tables with content filter rules for message body lines.
+# These filters see one physical line at a time, in chunks of
+# at most \fB$line_length_limit\fR bytes.
+# .IP \fBbody_checks_size_limit\fP
+# The amount of content per message body segment (attachment) that is
+# subjected to \fB$body_checks\fR filtering.
+# .IP \fBheader_checks\fR
+# .IP "\fBmime_header_checks\fR (default: \fB$header_checks\fR)"
+# .IP "\fBnested_header_checks\fR (default: \fB$header_checks\fR)"
+# Lookup tables with content filter rules for message header lines:
+# respectively, these are applied to the initial message headers
+# (not including MIME headers), to the MIME headers anywhere in
+# the message, and to the initial headers of attached messages.
+# .sp
+# Note: these filters see one logical message header at a time, even
+# when a message header spans multiple lines. Message headers that
+# are longer than \fB$header_size_limit\fR characters are truncated.
+# .IP \fBdisable_mime_input_processing\fR
+# While receiving mail, give no special treatment to MIME related
+# message headers; all text after the initial message headers is
+# considered to be part of the message body. This means that
+# \fBheader_checks\fR is applied to all the initial message headers,
+# and that \fBbody_checks\fR is applied to the remainder of the
+# message.
+# .sp
+# Note: when used in this manner, \fBbody_checks\fR will process
+# a multi-line message header one line at a time.
+# EXAMPLES
+# .ad
+# .fi
+# Header pattern to block attachments with bad file name
+# extensions. For convenience, the PCRE /x flag is specified,
+# so that there is no need to collapse the pattern into a
+# single line of text. The purpose of the [[:xdigit:]]
+# sub-expressions is to recognize Windows CLSID strings.
+#
+# .na
+# .nf
+# /etc/postfix/main.cf:
+# header_checks = pcre:/etc/postfix/header_checks.pcre
+#
+# /etc/postfix/header_checks.pcre:
+# /^Content-(Disposition|Type).*name\es*=\es*"?([^;]*(\e.|=2E)(
+# ade|adp|asp|bas|bat|chm|cmd|com|cpl|crt|dll|exe|
+# hlp|ht[at]|
+# inf|ins|isp|jse?|lnk|md[betw]|ms[cipt]|nws|
+# \e{[[:xdigit:]]{8}(?:-[[:xdigit:]]{4}){3}-[[:xdigit:]]{12}\e}|
+# ops|pcd|pif|prf|reg|sc[frt]|sh[bsm]|swf|
+# vb[esx]?|vxd|ws[cfh]))(\e?=)?"?\es*(;|$)/x
+# REJECT Attachment name "$2" may not end with ".$4"
+# .ad
+# .fi
+#
+# Body pattern to stop a specific HTML browser vulnerability exploit.
+#
+# .na
+# .nf
+# /etc/postfix/main.cf:
+# body_checks = regexp:/etc/postfix/body_checks
+#
+# /etc/postfix/body_checks:
+# /^<iframe src=(3D)?cid:.* height=(3D)?0 width=(3D)?0>$/
+# REJECT IFRAME vulnerability exploit
+# SEE ALSO
+# cleanup(8), canonicalize and enqueue Postfix message
+# pcre_table(5), format of PCRE lookup tables
+# regexp_table(5), format of POSIX regular expression tables
+# postconf(1), Postfix configuration utility
+# postmap(1), Postfix lookup table management
+# postsuper(1), Postfix janitor
+# postcat(1), show Postfix queue file contents
+# RFC 2045, base64 and quoted-printable encoding rules
+# RFC 2047, message header encoding for non-ASCII text
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# CONTENT_INSPECTION_README, Postfix content inspection overview
+# BUILTIN_FILTER_README, Postfix built-in content inspection
+# BACKSCATTER_README, blocking returned forged mail
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/html2text.rc b/proto/html2text.rc
new file mode 100644
index 0000000..9e8819f
--- /dev/null
+++ b/proto/html2text.rc
@@ -0,0 +1,13 @@
+P.vspace.after = 1
+PRE.indent.left = 0
+UL.indents = 4 4 4 4 4
+OL.indents = 4 4 4 4 4
+DL.vspace.before = 0
+DL.vspace.after = 0
+DT.vspace.before = 0
+DT.indent.left = 0
+DD.indent.left = 4
+BLOCKQUOTE.indent.left = 4
+BLOCKQUOTE.indent.right = 0
+A.attributes.internal_link = NONE
+A.attributes.external_link = NONE
diff --git a/proto/ldap_table b/proto/ldap_table
new file mode 100644
index 0000000..fe3626a
--- /dev/null
+++ b/proto/ldap_table
@@ -0,0 +1,723 @@
+#++
+# NAME
+# ldap_table 5
+# SUMMARY
+# Postfix LDAP client configuration
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" ldap:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - ldap:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting or mail routing. These tables are usually in
+# \fBdbm\fR or \fBdb\fR format.
+#
+# Alternatively, lookup tables can be specified as LDAP databases.
+#
+# In order to use LDAP lookups, define an LDAP source as a lookup
+# table in main.cf, for example:
+#
+# .nf
+# alias_maps = ldap:/etc/postfix/ldap-aliases.cf
+# .fi
+#
+# The file /etc/postfix/ldap-aliases.cf has the same format as
+# the Postfix main.cf file, and can specify the parameters
+# described below. An example is given at the end of this manual.
+#
+# This configuration method is available with Postfix version
+# 2.1 and later. See the section "OBSOLETE MAIN.CF PARAMETERS"
+# below for older Postfix versions.
+#
+# For details about LDAP SSL and STARTTLS, see the section
+# on SSL and STARTTLS below.
+# LIST MEMBERSHIP
+# .ad
+# .fi
+# When using LDAP to store lists such as $mynetworks,
+# $mydestination, $relay_domains, $local_recipient_maps,
+# etc., it is important to understand that the table must
+# store each list member as a separate key. The table lookup
+# verifies the *existence* of the key. See "Postfix lists
+# versus tables" in the DATABASE_README document for a
+# discussion.
+#
+# Do NOT create tables that return the full list of domains
+# in $mydestination or $relay_domains etc., or IP addresses
+# in $mynetworks.
+#
+# DO create tables with each matching item as a key and with
+# an arbitrary value. With LDAP databases it is not uncommon to
+# return the key itself.
+#
+# For example, NEVER do this in a map defining $mydestination:
+#
+# .nf
+# query_filter = domain=*
+# result_attribute = domain
+# .fi
+#
+# Do this instead:
+#
+# .nf
+# query_filter = domain=%s
+# result_attribute = domain
+# .fi
+# GENERAL LDAP PARAMETERS
+# .ad
+# .fi
+# In the text below, default values are given in parentheses.
+# Note: don't use quotes in these variables; at least, not until the
+# Postfix configuration routines understand how to deal with quoted
+# strings.
+# .IP "\fBserver_host (default: localhost)\fR"
+# The name of the host running the LDAP server, e.g.
+#
+# .nf
+# server_host = ldap.example.com
+# .fi
+#
+# Depending on the LDAP client library you're using, it should
+# be possible to specify multiple servers here, with the library
+# trying them in order should the first one fail. It should also
+# be possible to give each server in the list a different port
+# (overriding \fBserver_port\fR below), by naming them like
+#
+# .nf
+# server_host = ldap.example.com:1444
+# .fi
+#
+# With OpenLDAP, a (list of) LDAP URLs can be used to specify both
+# the hostname(s) and the port(s):
+#
+# .nf
+# server_host = ldap://ldap.example.com:1444
+# ldap://ldap2.example.com:1444
+# .fi
+#
+# All LDAP URLs accepted by the OpenLDAP library are supported,
+# including connections over UNIX domain sockets, and LDAP SSL
+# (the last one provided that OpenLDAP was compiled with support
+# for SSL):
+#
+# .nf
+# server_host = ldapi://%2Fsome%2Fpath
+# ldaps://ldap.example.com:636
+# .fi
+# .IP "\fBserver_port (default: 389)\fR"
+# The port the LDAP server listens on, e.g.
+#
+# .nf
+# server_port = 778
+# .fi
+# .IP "\fBtimeout (default: 10 seconds)\fR"
+# The number of seconds a search can take before timing out, e.g.
+#
+# .fi
+# timeout = 5
+# .fi
+# .IP "\fBsearch_base (No default; you must configure this)\fR"
+# The RFC2253 base DN at which to conduct the search, e.g.
+#
+# .nf
+# search_base = dc=your, dc=com
+# .fi
+# .IP
+# With Postfix 2.2 and later this parameter supports the
+# following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character.
+# .IP "\fB%s\fR"
+# This is replaced by the input key.
+# RFC 2253 quoting is used to make sure that the input key
+# does not add unexpected metacharacters.
+# .IP "\fB%u\fR"
+# When the input key is an address of the form user@domain, \fB%u\fR
+# is replaced by the (RFC 2253) quoted local part of the address.
+# Otherwise, \fB%u\fR is replaced by the entire search string.
+# If the localpart is empty, the search is suppressed and returns
+# no results.
+# .IP "\fB%d\fR"
+# When the input key is an address of the form user@domain, \fB%d\fR
+# is replaced by the (RFC 2253) quoted domain part of the address.
+# Otherwise, the search is suppressed and returns no results.
+# .IP "\fB%[SUD]\fR"
+# For the \fBsearch_base\fR parameter, the upper-case equivalents
+# of the above expansions behave identically to their lower-case
+# counter-parts. With the \fBresult_format\fR parameter (previously
+# called \fBresult_filter\fR see the OTHER OBSOLETE FEATURES section
+# and below), they expand to the corresponding components of input
+# key rather than the result value.
+# .IP "\fB%[1-9]\fR"
+# The patterns %1, %2, ... %9 are replaced by the corresponding
+# most significant component of the input key's domain. If the
+# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR,
+# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is
+# unqualified or does not have enough domain components to satisfy
+# all the specified patterns, the search is suppressed and returns
+# no results.
+# .RE
+# .IP "\fBquery_filter (default: mailacceptinggeneralid=%s)\fR"
+# The RFC2254 filter used to search the directory, where \fB%s\fR
+# is a substitute for the address Postfix is trying to resolve,
+# e.g.
+#
+# .nf
+# query_filter = (&(mail=%s)(paid_up=true))
+# .fi
+#
+# This parameter supports the following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character. (Postfix 2.2 and later).
+# .IP "\fB%s\fR"
+# This is replaced by the input key.
+# RFC 2254 quoting is used to make sure that the input key
+# does not add unexpected metacharacters.
+# .IP "\fB%u\fR"
+# When the input key is an address of the form user@domain, \fB%u\fR
+# is replaced by the (RFC 2254) quoted local part of the address.
+# Otherwise, \fB%u\fR is replaced by the entire search string.
+# If the localpart is empty, the search is suppressed and returns
+# no results.
+# .IP "\fB%d\fR"
+# When the input key is an address of the form user@domain, \fB%d\fR
+# is replaced by the (RFC 2254) quoted domain part of the address.
+# Otherwise, the search is suppressed and returns no results.
+# .IP "\fB%[SUD]\fR"
+# The upper-case equivalents of the above expansions behave in the
+# \fBquery_filter\fR parameter identically to their lower-case
+# counter-parts. With the \fBresult_format\fR parameter (previously
+# called \fBresult_filter\fR see the OTHER OBSOLETE FEATURES section
+# and below), they expand to the corresponding components of input
+# key rather than the result value.
+# .IP
+# The above %S, %U and %D expansions are available with Postfix 2.2
+# and later.
+# .IP "\fB%[1-9]\fR"
+# The patterns %1, %2, ... %9 are replaced by the corresponding
+# most significant component of the input key's domain. If the
+# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR,
+# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is
+# unqualified or does not have enough domain components to satisfy
+# all the specified patterns, the search is suppressed and returns
+# no results.
+# .IP
+# The above %1, ..., %9 expansions are available with Postfix 2.2
+# and later.
+# .RE
+# .IP
+# The "domain" parameter described below limits the input
+# keys to addresses in matching domains. When the "domain"
+# parameter is non-empty, LDAP queries for unqualified
+# addresses or addresses in non-matching domains are suppressed
+# and return no results.
+#
+# NOTE: DO NOT put quotes around the \fBquery_filter\fR parameter.
+# .IP "\fBresult_format (default: \fB%s\fR)\fR"
+# Called \fBresult_filter\fR in Postfix releases prior to 2.2.
+# Format template applied to result attributes. Most commonly used
+# to append (or prepend) text to the result. This parameter supports
+# the following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character. (Postfix 2.2 and later).
+# .IP "\fB%s\fR"
+# This is replaced by the value of the result attribute. When
+# result is empty it is skipped.
+# .IP "\fB%u\fR
+# When the result attribute value is an address of the form
+# user@domain, \fB%u\fR is replaced by the local part of the
+# address. When the result has an empty localpart it is skipped.
+# .IP "\fB%d\fR"
+# When a result attribute value is an address of the form
+# user@domain, \fB%d\fR is replaced by the domain part of
+# the attribute value. When the result is unqualified it
+# is skipped.
+# .IP "\fB%[SUD1-9]\fR"
+# The upper-case and decimal digit expansions interpolate
+# the parts of the input key rather than the result. Their
+# behavior is identical to that described with \fBquery_filter\fR,
+# and in fact because the input key is known in advance, lookups
+# whose key does not contain all the information specified in
+# the result template are suppressed and return no results.
+# .IP
+# The above %S, %U, %D and %1, ..., %9 expansions are available with
+# Postfix 2.2 and later.
+# .RE
+# .IP
+# For example, using "result_format = smtp:[%s]" allows one
+# to use a mailHost attribute as the basis of a transport(5)
+# table. After applying the result format, multiple values
+# are concatenated as comma separated strings. The expansion_limit
+# and size_limit parameters explained below allow one to
+# restrict the number of values in the result, which is
+# especially useful for maps that should return a single
+# value.
+#
+# The default value \fB%s\fR specifies that each
+# attribute value should be used as is.
+#
+# This parameter was called \fBresult_filter\fR in Postfix
+# releases prior to 2.2. If no "result_format" is specified,
+# the value of "result_filter" will be used instead before
+# resorting to the default value. This provides compatibility
+# with old configuration files.
+#
+# NOTE: DO NOT put quotes around the result format!
+# .IP "\fBdomain (default: no domain list)\fR"
+# This is a list of domain names, paths to files, or
+# "type:table" databases. When specified, only fully qualified search
+# keys with a *non-empty* localpart and a matching domain
+# are eligible for lookup: 'user' lookups, bare domain lookups
+# and "@domain" lookups are not performed. This can significantly
+# reduce the query load on the LDAP server.
+#
+# .nf
+# domain = postfix.org, hash:/etc/postfix/searchdomains
+# .fi
+#
+# It is best not to use LDAP to store the domains eligible
+# for LDAP lookups.
+#
+# NOTE: DO NOT define this parameter for local(8) aliases.
+#
+# This feature is available in Postfix 1.0 and later.
+# .IP "\fBresult_attribute (default: maildrop)\fR"
+# The attribute(s) Postfix will read from any directory
+# entries returned by the lookup, to be resolved to an email
+# address.
+#
+# .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 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
+# .fi
+#
+# DN recursion retrieves the same result_attributes as the
+# main query, including the special attributes 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 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
+# result attributes are returned. This is useful for delegating expansion
+# of group members to a particular host, by using an optional "maildrop"
+# attribute on selected groups to route the group to a specific host,
+# where the group is expanded, possibly via mailing-list manager or
+# 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
+# (see above) LDAP entry, leaf result attributes are excluded from the
+# expansion of that entry. This is useful when expanding groups and the
+# desired mail address attribute(s) of the member objects obtained via
+# DN or URI recursion are also present in the group object. To only
+# return the attribute values from the leaf objects and not the
+# containing group, add the attribute to the leaf_result_attribute list,
+# and not the result_attribute list, which is always expanded. Note,
+# the default value of "result_attribute" is not empty, you may want to
+# set it explicitly empty when using "leaf_result_attribute" to expand
+# the group to a list of member DN addresses. If groups have both
+# member DN references AND attributes that hold multiple string valued
+# rfc822 addresses, then the string attributes go in "result_attribute".
+# The attributes that represent the email addresses of objects
+# referenced via a DN (or LDAP URI) go in "leaf_result_attribute".
+#
+# .nf
+# result_attribute = memberaddr
+# special_result_attribute = memberdn
+# terminal_result_attribute = maildrop
+# 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.
+# These translate into LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE,
+# and LDAP_SCOPE_ONELEVEL.
+# .IP "\fBbind (default: yes)\fR"
+# Whether or how to bind to the LDAP server. Newer LDAP
+# implementations don't require clients to bind, which saves
+# time. Example:
+#
+# .nf
+# # Don't bind
+# bind = no
+# # Use SIMPLE bind
+# bind = yes
+# # Use SASL bind
+# bind = sasl
+# .fi
+#
+# Postfix versions prior to 2.8 only support "bind = no" which
+# means don't bind, and "bind = yes" which means do a SIMPLE bind.
+# Postfix 2.8 and later also supports "bind = SASL" when compiled
+# with LDAP SASL support as described in LDAP_README, it also adds
+# the synonyms "bind = none" and "bind = simple" for "bind = no"
+# and "bind = yes" respectively. See the SASL section below for
+# additional parameters available with "bind = sasl".
+#
+# If you do need to bind, you might consider configuring
+# Postfix to connect to the local machine on a port that's
+# an SSL tunnel to your LDAP server. If your LDAP server
+# doesn't natively support SSL, put a tunnel (wrapper, proxy,
+# whatever you want to call it) on that system too. This
+# should prevent the password from traversing the network in
+# the clear.
+# .IP "\fBbind_dn (default: empty)\fR"
+# If you do have to bind, do it with this distinguished name. Example:
+#
+# .nf
+# bind_dn = uid=postfix, dc=your, dc=com
+# .fi
+# With "bind = sasl" (see above) the DN may be optional for some SASL
+# mechanisms, don't specify a DN if not needed.
+# .IP "\fBbind_pw (default: empty)\fR"
+# The password for the distinguished name above. If you have
+# to use this, you probably want to make the map configuration
+# file readable only by the Postfix user. When using the
+# obsolete ldap:ldapsource syntax, with map parameters in
+# main.cf, it is not possible to securely store the bind
+# password. This is because main.cf needs to be world readable
+# to allow local accounts to submit mail via the sendmail
+# command. Example:
+#
+# .nf
+# bind_pw = postfixpw
+# .fi
+# With "bind = sasl" (see above) the password may be optional
+# for some SASL mechanisms, don't specify a password if not needed.
+# .IP "\fBcache (IGNORED with a warning)\fR"
+# .IP "\fBcache_expiry (IGNORED with a warning)\fR"
+# .IP "\fBcache_size (IGNORED with a warning)\fR"
+# The above parameters are NO LONGER SUPPORTED by Postfix.
+# Cache support has been dropped from OpenLDAP as of release
+# 2.1.13.
+# .IP "\fBrecursion_limit (default: 1000)\fR"
+# A limit on the nesting depth of DN and URL special result
+# attribute evaluation. The limit must be a non-zero positive
+# number.
+# .IP "\fBexpansion_limit (default: 0)\fR"
+# A limit on the total number of result elements returned
+# (as a comma separated list) by a lookup against the map.
+# A setting of zero disables the limit. Lookups fail with a
+# temporary error if the limit is exceeded. Setting the
+# limit to 1 ensures that lookups do not return multiple
+# values.
+# .IP "\fBsize_limit (default: $expansion_limit)\fR"
+# A limit on the number of LDAP entries returned by any single
+# LDAP search performed as part of the lookup. A setting of
+# 0 disables the limit. Expansion of DN and URL references
+# involves nested LDAP queries, each of which is separately
+# subjected to this limit.
+#
+# Note: even a single LDAP entry can generate multiple lookup
+# results, via multiple result attributes and/or multi-valued
+# result attributes. This limit caps the per search resource
+# utilization on the LDAP server, not the final multiplicity
+# of the lookup result. It is analogous to the "-z" option
+# of "ldapsearch".
+# .IP "\fBdereference (default: 0)\fR"
+# When to dereference LDAP aliases. (Note that this has
+# nothing do with Postfix aliases.) The permitted values are
+# those legal for the OpenLDAP/UM LDAP implementations:
+# .RS
+# .IP 0
+# never
+# .IP 1
+# when searching
+# .IP 2
+# when locating the base object for the search
+# .IP 3
+# always
+# .RE
+# .IP
+# See ldap.h or the ldap_open(3) or ldapsearch(1) man pages
+# for more information. And if you're using an LDAP package
+# that has other possible values, please bring it to the
+# attention of the postfix-users@postfix.org mailing list.
+# .IP "\fBchase_referrals (default: 0)\fR"
+# Sets (or clears) LDAP_OPT_REFERRALS (requires LDAP version
+# 3 support).
+# .IP "\fBversion (default: 2)\fR"
+# Specifies the LDAP protocol version to use.
+# .IP "\fBdebuglevel (default: 0)\fR"
+# What level to set for debugging in the OpenLDAP libraries.
+# LDAP SASL PARAMETERS
+# .ad
+# .fi
+# If you're using the OpenLDAP libraries compiled with SASL
+# support, Postfix 2.8 and later built with LDAP SASL support
+# as described in LDAP_README can authenticate to LDAP servers
+# via SASL.
+#
+# This enables authentication to the LDAP server via mechanisms
+# other than a simple password. The added flexibility has a cost:
+# it is no longer practical to set an explicit timeout on the duration
+# of an LDAP bind operation. Under adverse conditions, whether a SASL
+# bind times out, or if it does, the duration of the timeout is
+# determined by the LDAP and SASL libraries.
+#
+# It is best to use tables that use SASL binds via proxymap(8), this
+# way the requesting process can time-out the proxymap request. This
+# also lets you tailer the process environment by overriding the
+# proxymap(8) import_environment setting in master.cf(5). Special
+# environment settings may be needed to configure GSSAPI credential
+# caches or other SASL mechanism specific options. The GSSAPI
+# credentials used for LDAP lookups may need to be different than
+# say those used for the Postfix SMTP client to authenticate to remote
+# servers.
+#
+# Using SASL mechanisms requires LDAP protocol version 3, the default
+# protocol version is 2 for backwards compatibility. You must set
+# "version = 3" in addition to "bind = sasl".
+#
+# The following parameters are relevant to using LDAP with SASL
+# .IP "\fBsasl_mechs (default: empty)\fR"
+# Space separated list of SASL mechanism(s) to try.
+# .IP "\fBsasl_realm (default: empty)\fR"
+# SASL Realm to use, if applicable.
+# .IP "\fBsasl_authz_id (default: empty)\fR"
+# The SASL authorization identity to assert, if applicable.
+# .IP "\fBsasl_minssf (default: 0)\fR"
+# The minimum required sasl security factor required to establish a
+# connection.
+# LDAP SSL AND STARTTLS PARAMETERS
+# .ad
+# .fi
+# If you're using the OpenLDAP libraries compiled with SSL
+# support, Postfix can connect to LDAP SSL servers and can
+# issue the STARTTLS command.
+#
+# LDAP SSL service can be requested by using a LDAP SSL URL
+# in the server_host parameter:
+#
+# .nf
+# server_host = ldaps://ldap.example.com:636
+# .fi
+#
+# STARTTLS can be turned on with the start_tls parameter:
+#
+# .nf
+# start_tls = yes
+# .fi
+#
+# Both forms require LDAP protocol version 3, which has to be set
+# explicitly with:
+#
+# .nf
+# version = 3
+# .fi
+#
+# If any of the Postfix programs querying the map is configured in
+# master.cf to run chrooted, all the certificates and keys involved
+# have to be copied to the chroot jail. Of course, the private keys
+# should only be readable by the user "postfix".
+#
+# The following parameters are relevant to LDAP SSL and STARTTLS:
+# .IP "\fBstart_tls (default: no)\fR"
+# Whether or not to issue STARTTLS upon connection to the
+# server. Don't set this with LDAP SSL (the SSL session is setup
+# automatically when the TCP connection is opened).
+# .IP "\fBtls_ca_cert_dir (No default; set either this or tls_ca_cert_file)\fR"
+# Directory containing X509 Certification Authority certificates
+# in PEM format which are to be recognized by the client in
+# SSL/TLS connections. The files each contain one CA certificate.
+# The files are looked up by the CA subject name hash value,
+# which must hence be available. If more than one CA certificate
+# with the same name hash value exist, the extension must be
+# different (e.g. 9d66eef0.0, 9d66eef0.1 etc). The search is
+# performed in the ordering of the extension number, regardless
+# of other properties of the certificates. Use the c_rehash
+# utility (from the OpenSSL distribution) to create the
+# necessary links.
+# .IP "\fBtls_ca_cert_file (No default; set either this or tls_ca_cert_dir)\fR"
+# File containing the X509 Certification Authority certificates
+# in PEM format which are to be recognized by the client in
+# SSL/TLS connections. This setting takes precedence over
+# tls_ca_cert_dir.
+# .IP "\fBtls_cert (No default; you must set this)\fR"
+# File containing client's X509 certificate to be used by
+# the client in SSL/ TLS connections.
+# .IP "\fBtls_key (No default; you must set this)\fR"
+# File containing the private key corresponding to the above
+# tls_cert.
+# .IP "\fBtls_require_cert (default: no)\fR"
+# Whether or not to request server's X509 certificate and
+# check its validity when establishing SSL/TLS connections.
+# The supported values are \fBno\fR and \fByes\fR.
+# .sp
+# With \fBno\fR, the server certificate trust chain is not checked,
+# but with OpenLDAP prior to 2.1.13, the name in the server
+# certificate must still match the LDAP server name. With OpenLDAP
+# 2.0.0 to 2.0.11 the server name is not necessarily what you
+# specified, rather it is determined (by reverse lookup) from the
+# IP address of the LDAP server connection. With OpenLDAP prior to
+# 2.0.13, subjectAlternativeName extensions in the LDAP server
+# certificate are ignored: the server name must match the subject
+# CommonName. The \fBno\fR setting corresponds to the \fBnever\fR
+# value of \fBTLS_REQCERT\fR in LDAP client configuration files.
+# .sp
+# Don't use TLS with OpenLDAP 2.0.x (and especially with x <= 11)
+# if you can avoid it.
+# .sp
+# With \fByes\fR, the server certificate must be issued by a trusted
+# CA, and not be expired. The LDAP server name must match one of the
+# name(s) found in the certificate (see above for OpenLDAP library
+# version dependent behavior). The \fByes\fR setting corresponds to the
+# \fBdemand\fR value of \fBTLS_REQCERT\fR in LDAP client configuration
+# files.
+# .sp
+# The "try" and "allow" values of \fBTLS_REQCERT\fR have no equivalents
+# here. They are not available with OpenLDAP 2.0, and in any case have
+# questionable security properties. Either you want TLS verified LDAP
+# connections, or you don't.
+# .sp
+# The \fByes\fR value only works correctly with Postfix 2.5 and later,
+# or with OpenLDAP 2.0. Earlier Postfix releases or later OpenLDAP
+# releases don't work together with this setting. Support for LDAP
+# over TLS was added to Postfix based on the OpenLDAP 2.0 API.
+# .IP "\fBtls_random_file (No default)\fR"
+# Path of a file to obtain random bits from when /dev/[u]random
+# is not available, to be used by the client in SSL/TLS
+# connections.
+# .IP "\fBtls_cipher_suite (No default)\fR"
+# Cipher suite to use in SSL/TLS negotiations.
+# EXAMPLE
+# .ad
+# .fi
+# Here's a basic example for using LDAP to look up local(8)
+# aliases.
+# Assume that in main.cf, you have:
+#
+# .nf
+# alias_maps = hash:/etc/aliases,
+# ldap:/etc/postfix/ldap-aliases.cf
+# .fi
+#
+# and in ldap:/etc/postfix/ldap-aliases.cf you have:
+#
+# .nf
+# server_host = ldap.example.com
+# search_base = dc=example, dc=com
+# .fi
+#
+# Upon receiving mail for a local address "ldapuser" that
+# isn't found in the /etc/aliases database, Postfix will
+# search the LDAP server listening at port 389 on ldap.example.com.
+# It will bind anonymously, 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 RFC822 addresses
+# to which the message will be delivered.
+# OBSOLETE MAIN.CF PARAMETERS
+# .ad
+# .fi
+# For backwards compatibility with Postfix version 2.0 and earlier,
+# LDAP parameters can also be defined in main.cf. Specify
+# as LDAP source a name that doesn't begin with a slash or
+# a dot. The LDAP parameters will then be accessible as the
+# name you've given the source in its definition, an underscore,
+# and the name of the parameter. For example, if the map is
+# specified as "ldap:\fIldapsource\fR", the "server_host"
+# parameter below would be defined in main.cf as
+# "\fIldapsource\fR_server_host".
+#
+# Note: with this form, the passwords for the LDAP sources are
+# written in main.cf, which is normally world-readable. Support
+# for this form will be removed in a future Postfix version.
+# OTHER OBSOLETE FEATURES
+# .ad
+# .fi
+# For backwards compatibility with the pre
+# 2.2 LDAP clients, \fBresult_filter\fR can for now be used instead
+# of \fBresult_format\fR, when the latter parameter is not also set.
+# The new name better reflects the function of the parameter. This
+# compatibility interface may be removed in a future release.
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# mysql_table(5), MySQL lookup tables
+# pgsql_table(5), PostgreSQL lookup tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# LDAP_README, Postfix LDAP client guide
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# AUTHOR(S)
+# .ad
+# .fi
+# Carsten Hoeger,
+# Hery Rakotoarisoa,
+# John Hensley,
+# Keith Stevenson,
+# LaMont Jones,
+# Liviu Daia,
+# Manuel Guesdon,
+# Mike Mattice,
+# Prabhat K Singh,
+# Sami Haahtinen,
+# Samuel Tardieu,
+# Victor Duchovni,
+# and many others.
+#--
diff --git a/proto/lmdb_table b/proto/lmdb_table
new file mode 100644
index 0000000..5bbbc14
--- /dev/null
+++ b/proto/lmdb_table
@@ -0,0 +1,119 @@
+#++
+# NAME
+# lmdb_table 5
+# SUMMARY
+# Postfix LMDB adapter
+# SYNOPSIS
+# \fBpostmap lmdb:/etc/postfix/\fIfilename\fR
+# .br
+# \fBpostmap -i lmdb:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+#
+# \fBpostmap -d "\fIkey\fB" lmdb:/etc/postfix/\fIfilename\fR
+# .br
+# \fBpostmap -d - lmdb:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+#
+# \fBpostmap -q "\fIkey\fB" lmdb:/etc/postfix/\fIfilename\fR
+# .br
+# \fBpostmap -q - lmdb:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix LMDB adapter provides access to a persistent,
+# memory-mapped, key-value store. The database size is limited
+# only by the size of the memory address space (typically 31
+# or 47 bits on 32-bit or 64-bit CPUs, respectively) and by
+# the available file system space.
+# REQUESTS
+# .ad
+# .fi
+# The LMDB adapter supports all Postfix lookup table operations.
+# This makes LMDB suitable for Postfix address rewriting,
+# routing, access policies, caches, or any information that
+# can be stored under a fixed lookup key.
+#
+# When a transaction fails due to a full database, Postfix
+# resizes the database and retries the transaction.
+#
+# Postfix table lookups may generate partial search keys such
+# as domain names without one or more subdomains, network
+# addresses without one or more least-significant octets, or
+# email addresses without the localpart, address extension
+# or domain portion. This behavior is also found with, for
+# example, btree:, hash:, or ldap: tables.
+#
+# Changes to an LMDB database do not trigger an automatic
+# daemon restart, and do not require a daemon restart with
+# "\fBpostfix reload\fR".
+# RELIABILITY
+# .ad
+# .fi
+# LMDB's copy-on-write architecture provides safe updates,
+# at the cost of using more space than some other flat-file
+# databases. Read operations are memory-mapped for speed.
+# Write operations are not memory-mapped to avoid silent
+# corruption due to stray pointer bugs.
+#
+# Multiple processes can safely update an LMDB database without
+# serializing requests through the proxymap(8) service. This
+# makes LMDB suitable as a shared cache for verify(8) or
+# postscreen(8) services.
+# SYNCHRONIZATION
+# .ad
+# .fi
+# The Postfix LMDB adapter does not use LMDB's built-in locking
+# scheme, because that would require world-writable lockfiles
+# and would violate the Postfix security model. Instead,
+# Postfix uses fcntl(2) locks with whole-file granularity.
+# Programs that use LMDB's built-in locking protocol will
+# corrupt a Postfix LMDB database or will read garbage.
+#
+# Every Postfix LMDB database read or write transaction must
+# be protected from start to end with a shared or exclusive
+# fcntl(2) lock. A writer may atomically downgrade an exclusive
+# lock to a shared lock, but it must hold an exclusive lock
+# while opening another write transaction.
+#
+# Note that fcntl(2) locks do not protect transactions within
+# the same process against each other. If a program cannot
+# avoid making simultaneous database requests, then it must
+# protect its transactions with in-process locks, in addition
+# to the per-process fcntl(2) locks.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# Short-lived programs automatically pick up changes to
+# main.cf. With long-running daemon programs, Use the command
+# "\fBpostfix reload\fR" after a configuration change.
+# .IP "\fBlmdb_map_size (16777216)\fR"
+# The initial OpenLDAP LMDB database size limit in bytes.
+# SEE ALSO
+# postconf(1), Postfix supported lookup tables
+# postmap(1), Postfix lookup table maintenance
+# postconf(5), configuration parameters
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# LMDB_README, Postfix OpenLDAP LMDB howto
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# LMDB support was introduced with Postfix version 2.11.
+# AUTHOR(S)
+# Howard Chu
+# Symas Corporation
+#
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/manual-format b/proto/manual-format
new file mode 100644
index 0000000..2e34b9a
--- /dev/null
+++ b/proto/manual-format
@@ -0,0 +1,21 @@
+Be consistent and improve the order later.
+
+NAME
+DESCRIPTION
+SECURITY
+STANDARDS
+DIAGNOSTICS
+BUGS
+ENVIRONMENT
+CONFIGURATION PARAMETERS
+FILES
+SEE ALSO
+daemons
+commands
+configuration files
+master
+syslogd
+README FILES
+LICENSE
+HISTORY
+AUTHOR(S)
diff --git a/proto/master b/proto/master
new file mode 100644
index 0000000..28040b6
--- /dev/null
+++ b/proto/master
@@ -0,0 +1,257 @@
+#++
+# NAME
+# master 5
+# SUMMARY
+# Postfix master process configuration file format
+# DESCRIPTION
+# The Postfix mail system is implemented by small number of
+# (mostly) client commands that are invoked by users, and by
+# a larger number of services that run in the background.
+#
+# Postfix services are implemented by daemon processes. These
+# run in the background, started on-demand by the \fBmaster\fR(8)
+# process. The master.cf configuration file defines how a
+# client program connects to a service, and what daemon
+# program runs when a service is requested. Most daemon
+# processes are short-lived and terminate voluntarily after
+# serving \fBmax_use\fR clients, or after inactivity for
+# \fBmax_idle\fR or more units of time.
+#
+# All daemons specified here must speak a Postfix-internal
+# protocol. In order to execute non-Postfix software use the
+# \fBlocal\fR(8), \fBpipe\fR(8) or \fBspawn\fR(8) services, or
+# execute the software with \fBinetd\fR(8) or equivalent.
+# .PP
+# After changing master.cf you must execute "\fBpostfix reload\fR"
+# to reload the configuration.
+# SYNTAX
+# .ad
+# .fi
+# The general format of the master.cf file is as follows:
+# .IP \(bu
+# Empty lines and whitespace-only lines are ignored, as are
+# lines whose first non-whitespace character is a `#'.
+# .IP \(bu
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# .IP \(bu
+# Each logical line defines a single Postfix service.
+# Each service is identified by its name and type as described
+# below. When multiple lines specify the same service name
+# and type, only the last one is remembered. Otherwise, the
+# order of master.cf service definitions does not matter.
+# .PP
+# Each logical line consists of eight fields separated by
+# whitespace. These are described below in the order as they
+# appear in the master.cf file.
+#
+# Where applicable a field of "-" requests that the built-in
+# default value be used. For boolean fields specify "y" or
+# "n" to override the default value.
+# .IP "\fBService name\fR"
+# The service name syntax depends on the service type as
+# described next.
+# .IP "\fBService type\fR"
+# Specify one of the following service types:
+# .RS
+# .IP \fBinet\fR
+# The service listens on a TCP/IP socket and is accessible
+# via the network.
+#
+# The service name is specified as \fIhost:port\fR, denoting
+# the host and port on which new connections should be
+# accepted. The host part (and colon) may be omitted. Either
+# host or port may be given in symbolic form (see \fBhosts\fR(5) or
+# \fBservices\fR(5)) or in numeric form (IP address or port number).
+# Host information may be enclosed inside "[]"; this form
+# is necessary only with IPv6 addresses.
+# .sp
+# Examples: a service named \fB127.0.0.1:smtp\fR or \fB::1:smtp\fR
+# receives
+# mail via the loopback interface only; and a service named
+# \fB10025\fR accepts connections on TCP port 10025 via
+# all interfaces configured with the \fBinet_interfaces\fR
+# parameter.
+#
+# .sp
+# Note: with Postfix version 2.2 and later specify
+# "\fBinet_interfaces = loopback-only\fR" in main.cf, instead
+# of hard-coding loopback IP address information in master.cf
+# or in main.cf.
+# .IP \fBunix\fR
+# The service listens on a UNIX-domain stream socket and is
+# accessible for local clients only.
+#
+# The service name is a pathname relative to the Postfix
+# queue directory (pathname controlled with the \fBqueue_directory\fR
+# configuration parameter in main.cf).
+# .sp
+# On Solaris 8 and earlier systems the \fBunix\fR type is
+# implemented with streams sockets.
+# .IP \fBunix-dgram\fR
+# The service listens on a UNIX-domain datagram socket and is
+# accessible for local clients only.
+#
+# The service name is a pathname relative to the Postfix
+# queue directory (pathname controlled with the \fBqueue_directory\fR
+# configuration parameter in main.cf).
+# .IP "\fBfifo\fR (obsolete)"
+# The service listens on a FIFO (named pipe) and is accessible
+# for local clients only.
+#
+# The service name is a pathname relative to the Postfix
+# queue directory (pathname controlled with the \fBqueue_directory\fR
+# configuration parameter in main.cf).
+# .IP \fBpass\fR
+# The service listens on a UNIX-domain stream socket, and is
+# accessible to local clients only. It receives one open
+# connection (file descriptor passing) per connection request.
+#
+# The service name is a pathname relative to the Postfix
+# queue directory (pathname controlled with the \fBqueue_directory\fR
+# configuration parameter in main.cf).
+# .sp
+# On Solaris 8 and earlier systems the \fBpass\fR type is
+# implemented with streams sockets.
+#
+# This feature is available as of Postfix version 2.5.
+# .RE
+# .IP "\fBPrivate (default: y)\fR"
+# Whether a service is internal to Postfix (pathname starts
+# with \fBprivate/\fR), or exposed through Postfix command-line
+# tools (pathname starts with \fBpublic/\fR).
+# Internet (type \fBinet\fR) services can't be private.
+# .IP "\fBUnprivileged (default: y)\fR"
+# Whether the service runs with root privileges or as the
+# owner of the Postfix system (the owner name is controlled
+# by the \fBmail_owner\fR configuration variable in the
+# main.cf file).
+# .sp
+# The \fBlocal\fR(8), \fBpipe\fR(8), \fBspawn\fR(8), and
+# \fBvirtual\fR(8) daemons require privileges.
+# .IP "\fBChroot (default: Postfix >= 3.0: n, Postfix < 3.0: y)\fR"
+# Whether or not the service runs chrooted to the mail queue
+# directory (pathname is controlled by the \fBqueue_directory\fR
+# configuration variable in the main.cf file).
+# .sp
+# Chroot should not be used with the \fBlocal\fR(8),
+# \fBpipe\fR(8), \fBspawn\fR(8), and \fBvirtual\fR(8) daemons.
+# Although the
+# \fBproxymap\fR(8) server can run chrooted, doing so defeats
+# most of the purpose of having that service in the first
+# place.
+# .sp
+# The files in the examples/chroot-setup subdirectory of the
+# Postfix source show how to set up a Postfix chroot environment
+# on a variety of systems. See also BASIC_CONFIGURATION_README
+# for issues related to running daemons chrooted.
+# .IP "\fBWake up time (default: 0)\fR"
+# Automatically wake up the named service after the specified
+# number of seconds. The wake up is implemented by connecting
+# to the service and sending a wake up request. A ? at the
+# end of the wake-up time field requests that no wake up
+# events be sent before the first time a service is used.
+# Specify 0 for no automatic wake up.
+# .sp
+# The \fBpickup\fR(8), \fBqmgr\fR(8) and \fBflush\fR(8)
+# daemons require a wake up timer.
+# .IP "\fBProcess limit (default: $default_process_limit)\fR"
+# The maximum number of processes that may execute this
+# service simultaneously. Specify 0 for no process count limit.
+# .sp
+# NOTE: Some Postfix services must be configured as a
+# single-process service (for example, \fBqmgr\fR(8)) and
+# some services must be configured with no process limit (for
+# example, \fBcleanup\fR(8)). These limits must not be
+# changed.
+# .IP "\fBCommand name + arguments\fR"
+# The command to be executed. Characters that are special
+# to the shell such as ">" or "|" have no special meaning
+# here, and quotes cannot be used to protect arguments
+# containing whitespace. To protect whitespace, use "{"
+# and "}" as described below.
+# .sp
+# The command name is relative to the Postfix daemon directory
+# (pathname is controlled by the \fBdaemon_directory\fR
+# configuration variable).
+# .sp
+# The command argument syntax for specific commands is
+# specified in the respective daemon manual page.
+# .sp
+# The following command-line options have the same effect for
+# all daemon programs:
+# .RS
+# .IP \fB-D\fR
+# Run the daemon under control by the command specified with
+# the \fBdebugger_command\fR variable in the main.cf
+# configuration file. See DEBUG_README for hints and tips.
+# .IP "\fB-o { \fIname\fR = \fIvalue\fB }\fR (long form, Postfix >= 3.0)"
+# .IP "\fB-o \fIname\fR=\fIvalue\fR (short form)"
+# Override the named main.cf configuration parameter. The
+# parameter value can refer to other parameters as \fI$name\fR
+# etc., just like in main.cf. See \fBpostconf\fR(5) for
+# syntax.
+# .sp
+# NOTE 1: With the "long form" shown above, whitespace
+# after "{", around "=", and before "}" is ignored, and
+# whitespace within the parameter value is preserved.
+# .sp
+# NOTE 2: with the "short form" shown above, do not specify
+# whitespace around the "=" or in
+# parameter values. To specify a parameter value that contains
+# whitespace, use the long form described above, or use commas
+# instead of spaces, or specify the value in main.cf. Example:
+# .sp
+# .nf
+# /etc/postfix/master.cf:
+# submission inet .... smtpd
+# -o smtpd_xxx_yyy=$submission_xxx_yyy
+# .sp
+# /etc/postfix/main.cf
+# submission_xxx_yyy = text with whitespace...
+# .fi
+# .sp
+# NOTE 3: Over-zealous use of parameter overrides makes the
+# Postfix configuration hard to understand and maintain. At
+# a certain point, it might be easier to configure multiple
+# instances of Postfix, instead of configuring multiple
+# personalities via master.cf.
+# .IP \fB-v\fR
+# Increase the verbose logging level. Specify multiple \fB-v\fR
+# options to make a Postfix daemon process increasingly verbose.
+# .IP "Other command-line arguments"
+# Specify "{" and "}" around command arguments that contain
+# whitespace (Postfix 3.0 and later). Whitespace
+# after "{" and before "}" is ignored.
+# SEE ALSO
+# master(8), process manager
+# postconf(5), configuration parameters
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# BASIC_CONFIGURATION_README, basic configuration
+# DEBUG_README, Postfix debugging
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# AUTHOR(S)
+# Initial version by
+# Magnus Baeck
+# Lund Institute of Technology
+# Sweden
+#
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/memcache_table b/proto/memcache_table
new file mode 100644
index 0000000..c97a9b4
--- /dev/null
+++ b/proto/memcache_table
@@ -0,0 +1,236 @@
+#++
+# NAME
+# memcache_table 5
+# SUMMARY
+# Postfix memcache client configuration
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" memcache:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - memcache:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting or mail routing. These tables are usually in
+# \fBdbm\fR or \fBdb\fR format.
+#
+# Alternatively, lookup tables can be specified as memcache
+# instances. To use memcache lookups, define a memcache
+# source as a lookup table in main.cf, for example:
+#
+# .nf
+# virtual_alias_maps = memcache:/etc/postfix/memcache-aliases.cf
+# .fi
+#
+# The file /etc/postfix/memcache-aliases.cf has the same
+# format as the Postfix main.cf file, and specifies the
+# parameters described below.
+#
+# The Postfix memcache client supports the lookup, update,
+# delete and sequence (first/next) operations. The sequence
+# operation requires a backup database that supports the
+# operation.
+# MEMCACHE MAIN PARAMETERS
+# .ad
+# .fi
+# .IP "\fBmemcache (default: inet:localhost:11211)\fR"
+# The memcache server (note: singular) that Postfix will try
+# to connect to. For a TCP server specify "inet:" followed by
+# a hostname or address, ":", and a port name or number.
+# Specify an IPv6 address inside "[]".
+# For a UNIX-domain server specify "unix:" followed by the
+# socket pathname. Examples:
+#
+# .nf
+# memcache = inet:memcache.example.com:11211
+# memcache = inet:127.0.0.1:11211
+# memcache = inet:[fc00:8d00:189::3]:11211
+# memcache = unix:/path/to/socket
+# .fi
+#
+# NOTE: to access a UNIX-domain socket with the proxymap(8)
+# server, the socket must be accessible by the unprivileged
+# postfix user.
+# .IP "\fBbackup (default: undefined)\fR"
+# An optional Postfix database that provides persistent backup
+# for the memcache database. The Postfix memcache client will
+# update the memcache database whenever it looks up or changes
+# information in the persistent database. Specify a Postfix
+# "type:table" database. Examples:
+#
+# .nf
+# # Non-shared postscreen cache.
+# backup = btree:/var/lib/postfix/postscreen_cache_map
+#
+# # Shared postscreen cache for processes on the same host.
+# backup = proxy:btree:/var/lib/postfix/postscreen_cache_map
+# .fi
+#
+# Access to remote proxymap servers is under development.
+#
+# NOTE 1: When sharing a persistent \fBpostscreen\fR(8) or
+# \fBverify\fR(8) cache, disable automatic cache cleanup (set
+# *_cache_cleanup_interval = 0) except with one Postfix
+# instance that will be responsible for cache cleanup.
+#
+# NOTE 2: When multiple tables share the same memcache
+# database, each table should use the \fBkey_format\fR feature
+# (see below) to prepend its own unique string to the lookup
+# key. Otherwise, automatic \fBpostscreen\fR(8) or \fBverify\fR(8)
+# cache cleanup may not work.
+#
+# NOTE 3: When the backup database is accessed with "proxy:"
+# lookups, the full backup database name (including the
+# "proxy:" prefix) must be specified in the proxymap server's
+# proxy_read_maps or proxy_write_maps setting (depending on
+# whether the access is read-only or read-write).
+# .IP "\fBflags (default: 0)\fR"
+# Optional flags that should be stored along with a memcache
+# update. The flags are ignored when looking up information.
+# .IP "\fBttl (default: 3600)\fR"
+# The expiration time in seconds of memcache updates.
+#
+# NOTE 1: When using a memcache table as \fBpostscreen\fR(8)
+# or \fBverify\fR(8) cache without persistent backup, specify
+# a zero *_cache_cleanup_interval value with all Postfix
+# instances that use the memcache, and specify the largest
+# \fBpostscreen\fR(8) *_ttl value or \fBverify\fR(8) *_expire_time
+# value as the memcache table's \fBttl\fR value.
+#
+# NOTE 2: According to memcache protocol documentation, a
+# value greater than 30 days (2592000 seconds) specifies
+# absolute UNIX
+# time. Smaller values are relative to the time of the update.
+# MEMCACHE KEY PARAMETERS
+# .ad
+# .fi
+# .IP "\fBkey_format (default: %s)\fB"
+# Format of the lookup and update keys that the Postfix
+# memcache client sends to the memcache server.
+# By default, these are the same as the lookup and update
+# keys that the memcache client receives from Postfix
+# applications.
+#
+# NOTE 1: The \fBkey_format\fR feature is not used for \fBbackup\fR
+# database requests.
+#
+# NOTE 2: When multiple tables share the same memcache
+# database, each table should prepend its own unique string
+# to the lookup key. Otherwise, automatic \fBpostscreen\fR(8)
+# or \fBverify\fR(8) cache cleanup may not work.
+#
+# Examples:
+#
+# .nf
+# key_format = aliases:%s
+# key_format = verify:%s
+# key_format = postscreen:%s
+# .fi
+#
+# The \fBkey_format\fR parameter supports the following '%'
+# expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character.
+# .IP "\fB%s\fR"
+# This is replaced by the memcache client input key.
+# .IP "\fB%u\fR"
+# When the input key is an address of the form user@domain,
+# \fB%u\fR is replaced by the SQL quoted local part of the
+# address. Otherwise, \fB%u\fR is replaced by the entire
+# search string. If the localpart is empty, a lookup is
+# silently suppressed and returns no results (an update is
+# skipped with a warning).
+# .IP "\fB%d\fR"
+# When the input key is an address of the form user@domain,
+# \fB%d\fR is replaced by the domain part of the address.
+# Otherwise, a lookup is silently suppressed and returns no
+# results (an update is skipped with a warning).
+# .IP "\fB%[SUD]\fR"
+# The upper-case equivalents of the above expansions behave
+# in the \fBkey_format\fR parameter identically to their
+# lower-case counter-parts.
+# .IP "\fB%[1-9]\fR"
+# The patterns %1, %2, ... %9 are replaced by the corresponding
+# most significant component of the input key's domain. If
+# the input key is \fIuser@mail.example.com\fR, then %1 is
+# \fBcom\fR, %2 is \fBexample\fR and %3 is \fBmail\fR. If the
+# input key is unqualified or does not have enough domain
+# components to satisfy all the specified patterns, a lookup
+# is silently suppressed and returns no results (an update
+# is skipped with a warning).
+# .RE
+# .IP "\fBdomain (default: no domain list)\fR"
+# This feature can significantly reduce database server load.
+# Specify a list of domain names, paths to files, or "type:table"
+# databases.
+# When specified, only fully qualified search keys with a
+# *non-empty* localpart and a matching domain are eligible
+# for lookup or update: bare 'user' lookups, bare domain
+# lookups and "@domain" lookups are silently skipped (updates
+# are skipped with a warning). Example:
+#
+# .nf
+# domain = example.com, hash:/etc/postfix/searchdomains
+# .fi
+# MEMCACHE ERROR CONTROLS
+# .ad
+# .fi
+# .IP "\fBdata_size_limit (default: 10240)\fR"
+# The maximal memcache reply data length in bytes.
+# .IP "\fBline_size_limit (default: 1024)\fR"
+# The maximal memcache reply line length in bytes.
+# .IP "\fBmax_try (default: 2)\fR"
+# The number of times to try a memcache command before giving
+# up. The memcache client does not retry a command when the
+# memcache server accepts no connection.
+# .IP "\fBretry_pause (default: 1)\fR"
+# The time in seconds before retrying a failed memcache command.
+# .IP "\fBtimeout (default: 2)\fR"
+# The time limit for sending a memcache command and for
+# receiving a memcache reply.
+# BUGS
+# The Postfix memcache client cannot be used for security-sensitive
+# tables such as \fBalias_maps\fR (these may contain
+# "\fI|command\fR and "\fI/file/name\fR" destinations), or
+# \fBvirtual_uid_maps\fR, \fBvirtual_gid_maps\fR and
+# \fBvirtual_mailbox_maps\fR (these specify UNIX process
+# privileges or "\fI/file/name\fR" destinations). In a typical
+# deployment a memcache database is writable by any process
+# that can talk to the memcache server; in contrast,
+# security-sensitive tables must never be writable by the
+# unprivileged Postfix user.
+#
+# The Postfix memcache client requires additional configuration
+# when used as \fBpostscreen\fR(8) or \fBverify\fR(8) cache.
+# For details see the \fBbackup\fR and \fBttl\fR parameter
+# discussions in the MEMCACHE MAIN PARAMETERS section above.
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# MEMCACHE_README, Postfix memcache client guide
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# .ad
+# .fi
+# Memcache support was introduced with Postfix version 2.9.
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/mysql_table b/proto/mysql_table
new file mode 100644
index 0000000..6870acf
--- /dev/null
+++ b/proto/mysql_table
@@ -0,0 +1,401 @@
+#++
+# NAME
+# mysql_table 5
+# SUMMARY
+# Postfix MySQL client configuration
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" mysql:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - mysql:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting or mail routing. These tables are usually in
+# \fBdbm\fR or \fBdb\fR format.
+#
+# Alternatively, lookup tables can be specified as MySQL databases.
+# In order to use MySQL lookups, define a MySQL source as a lookup
+# table in main.cf, for example:
+# .nf
+# alias_maps = mysql:/etc/postfix/mysql-aliases.cf
+# .fi
+#
+# The file /etc/postfix/mysql-aliases.cf has the same format as
+# the Postfix main.cf file, and can specify the parameters
+# described below.
+# LIST MEMBERSHIP
+# .ad
+# .fi
+# When using SQL to store lists such as $mynetworks,
+# $mydestination, $relay_domains, $local_recipient_maps,
+# etc., it is important to understand that the table must
+# store each list member as a separate key. The table lookup
+# verifies the *existence* of the key. See "Postfix lists
+# versus tables" in the DATABASE_README document for a
+# discussion.
+#
+# Do NOT create tables that return the full list of domains
+# in $mydestination or $relay_domains etc., or IP addresses
+# in $mynetworks.
+#
+# DO create tables with each matching item as a key and with
+# an arbitrary value. With SQL databases it is not uncommon to
+# return the key itself or a constant value.
+# MYSQL PARAMETERS
+# .ad
+# .fi
+# .IP "\fBhosts\fR"
+# The hosts that Postfix will try to connect to and query from.
+# Specify \fIunix:\fR for UNIX domain sockets, \fIinet:\fR for TCP
+# connections (default). Examples:
+# .nf
+# hosts = inet:host1.some.domain inet:host2.some.domain:port
+# hosts = host1.some.domain host2.some.domain:port
+# hosts = unix:/file/name
+# .fi
+#
+# The hosts are tried in random order, with all connections over
+# UNIX domain sockets being tried before those over TCP. The
+# connections are automatically closed after being idle for about
+# 1 minute, and are re-opened as necessary. Postfix versions 2.0
+# and earlier do not randomize the host order.
+#
+# NOTE: if you specify localhost as a hostname (even if you
+# prefix it with \fIinet:\fR), MySQL will connect to the default
+# UNIX domain socket. In order to instruct MySQL to connect to
+# localhost over TCP you have to specify
+# .nf
+# hosts = 127.0.0.1
+# .fi
+# .IP "\fBuser, password\fR"
+# The user name and password to log into the mysql server.
+# Example:
+# .nf
+# user = someone
+# password = some_password
+# .fi
+# .IP "\fBdbname\fR"
+# The database name on the servers. Example:
+# .nf
+# dbname = customer_database
+# .fi
+# .IP "\fBquery\fR"
+# The SQL query template used to search the database, where \fB%s\fR
+# is a substitute for the address Postfix is trying to resolve,
+# e.g.
+# .nf
+# query = SELECT replacement FROM aliases WHERE mailbox = '%s'
+# .fi
+#
+# By default, every query must return a result set (instead
+# of storing its results in a table); with "\fBrequire_result_set
+# = no\fR" (Postfix 3.2 and later), the absence of a result
+# set is treated as "not found".
+#
+# This parameter supports the following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character.
+# .IP "\fB%s\fR"
+# This is replaced by the input key.
+# SQL quoting is used to make sure that the input key does not
+# add unexpected metacharacters.
+# .IP "\fB%u\fR"
+# When the input key is an address of the form user@domain, \fB%u\fR
+# is replaced by the SQL quoted local part of the address.
+# Otherwise, \fB%u\fR is replaced by the entire search string.
+# If the localpart is empty, the query is suppressed and returns
+# no results.
+# .IP "\fB%d\fR"
+# When the input key is an address of the form user@domain, \fB%d\fR
+# is replaced by the SQL quoted domain part of the address.
+# Otherwise, the query is suppressed and returns no results.
+# .IP "\fB%[SUD]\fR"
+# The upper-case equivalents of the above expansions behave in the
+# \fBquery\fR parameter identically to their lower-case counter-parts.
+# With the \fBresult_format\fR parameter (see below), they expand the
+# input key rather than the result value.
+# .IP "\fB%[1-9]\fR"
+# The patterns %1, %2, ... %9 are replaced by the corresponding
+# most significant component of the input key's domain. If the
+# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR,
+# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is
+# unqualified or does not have enough domain components to satisfy
+# all the specified patterns, the query is suppressed and returns
+# no results.
+# .RE
+# .IP
+# The \fBdomain\fR parameter described below limits the input
+# keys to addresses in matching domains. When the \fBdomain\fR
+# parameter is non-empty, SQL queries for unqualified addresses
+# or addresses in non-matching domains are suppressed
+# and return no results.
+#
+# This parameter is available with Postfix 2.2. In prior releases
+# the SQL query was built from the separate parameters:
+# \fBselect_field\fR, \fBtable\fR, \fBwhere_field\fR and
+# \fBadditional_conditions\fR. The mapping from the old parameters
+# to the equivalent query is:
+#
+# .nf
+# SELECT [\fBselect_field\fR]
+# FROM [\fBtable\fR]
+# WHERE [\fBwhere_field\fR] = '%s'
+# [\fBadditional_conditions\fR]
+# .fi
+#
+# The '%s' in the \fBWHERE\fR clause expands to the escaped search string.
+# With Postfix 2.2 these legacy parameters are used if the \fBquery\fR
+# parameter is not specified.
+#
+# NOTE: DO NOT put quotes around the query parameter.
+# .IP "\fBresult_format (default: \fB%s\fR)\fR"
+# Format template applied to result attributes. Most commonly used
+# to append (or prepend) text to the result. This parameter supports
+# the following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character.
+# .IP "\fB%s\fR"
+# This is replaced by the value of the result attribute. When
+# result is empty it is skipped.
+# .IP "\fB%u\fR
+# When the result attribute value is an address of the form
+# user@domain, \fB%u\fR is replaced by the local part of the
+# address. When the result has an empty localpart it is skipped.
+# .IP "\fB%d\fR"
+# When a result attribute value is an address of the form
+# user@domain, \fB%d\fR is replaced by the domain part of
+# the attribute value. When the result is unqualified it
+# is skipped.
+# .IP "\fB%[SUD1-9]\fR"
+# The upper-case and decimal digit expansions interpolate
+# the parts of the input key rather than the result. Their
+# behavior is identical to that described with \fBquery\fR,
+# and in fact because the input key is known in advance, queries
+# whose key does not contain all the information specified in
+# the result template are suppressed and return no results.
+# .RE
+# .IP
+# For example, using "result_format = smtp:[%s]" allows one
+# to use a mailHost attribute as the basis of a transport(5)
+# table. After applying the result format, multiple values
+# are concatenated as comma separated strings. The expansion_limit
+# and parameter explained below allows one to restrict the number
+# of values in the result, which is especially useful for maps that
+# must return at most one value.
+#
+# The default value \fB%s\fR specifies that each result value should
+# be used as is.
+#
+# This parameter is available with Postfix 2.2 and later.
+#
+# NOTE: DO NOT put quotes around the result format!
+# .IP "\fBdomain (default: no domain list)\fR"
+# This is a list of domain names, paths to files, or "type:table"
+# databases. When specified, only fully qualified search keys
+# with a *non-empty* localpart and a matching domain are
+# eligible for lookup: 'user' lookups, bare domain lookups
+# and "@domain" lookups are not performed. This can significantly
+# reduce the query load on the MySQL server.
+# .nf
+# domain = postfix.org, hash:/etc/postfix/searchdomains
+# .fi
+#
+# It is best not to use SQL to store the domains eligible
+# for SQL lookups.
+#
+# This parameter is available with Postfix 2.2 and later.
+#
+# NOTE: DO NOT define this parameter for local(8) aliases,
+# because the input keys are always unqualified.
+# .IP "\fBexpansion_limit (default: 0)\fR"
+# A limit on the total number of result elements returned
+# (as a comma separated list) by a lookup against the map.
+# A setting of zero disables the limit. Lookups fail with a
+# temporary error if the limit is exceeded. Setting the
+# limit to 1 ensures that lookups do not return multiple
+# values.
+# .IP "\fBoption_file\fR"
+# Read options from the given file instead of the default my.cnf
+# location. This reads options from the \fB[client]\fR option
+# group, optionally followed by options from the group given
+# with \fBoption_group\fR.
+# .sp
+# This parameter is available with Postfix 2.11 and later.
+# .IP "\fBoption_group (default: Postfix >=3.2: client, <= 3.1: empty)\fR"
+# Read options from the given group of the mysql options file,
+# after reading options from the \fB[client]\fR group.
+# .sp
+# Postfix 3.2 and later read \fB[client]\fR option group
+# settings by default. To disable this specify no \fBoption_file\fR
+# and specify "\fBoption_group =\fR" (i.e. an empty value).
+# .sp
+# Postfix 3.1 and earlier don't read \fB[client]\fR option
+# group settings unless a non-empty \fBoption_file\fR or
+# \fBoption_group\fR value are specified. To enable this,
+# specify, for example, "\fBoption_group = client\fR".
+# .sp
+# This parameter is available with Postfix 2.11 and later.
+# .IP "\fBrequire_result_set (default: yes)\fR"
+# If "\fByes\fR", require that every query returns a result
+# set. If "\fBno\fR", treat the absence of a result set as
+# "not found".
+# .sp
+# This parameter is available with Postfix 3.2 and later.
+# .IP "\fBtls_cert_file\fR"
+# File containing client's X509 certificate.
+# .sp
+# This parameter is available with Postfix 2.11 and later.
+# .IP "\fBtls_key_file\fR"
+# File containing the private key corresponding to \fBtls_cert_file\fR.
+# .sp
+# This parameter is available with Postfix 2.11 and later.
+# .IP "\fBtls_CAfile\fR"
+# File containing certificates for all of the X509 Certification
+# Authorities the client will recognize. Takes precedence over
+# \fBtls_CApath\fR.
+# .sp
+# This parameter is available with Postfix 2.11 and later.
+# .IP "\fBtls_CApath\fR"
+# Directory containing X509 Certification Authority certificates
+# in separate individual files.
+# .sp
+# This parameter is available with Postfix 2.11 and later.
+# .IP "\fBtls_verify_cert (default: no)\fR"
+# Verify that the server's name matches the common name in the
+# certificate.
+# .sp
+# This parameter is available with Postfix 2.11 and later.
+# USING MYSQL STORED PROCEDURES
+# .ad
+# .fi
+# Postfix 3.2 and later support calling a stored procedure
+# instead of using a SELECT statement in the query, e.g.
+#
+# .nf
+# \fBquery\fR = CALL lookup('%s')
+# .fi
+#
+# The previously described '%' expansions can be used in the
+# parameter(s) to the stored procedure.
+#
+# By default, every stored procedure call must return a result
+# set, i.e. every code path must execute a SELECT statement
+# that returns a result set (instead of storing its results
+# in a table). With "\fBrequire_result_set = no\fR", the
+# absence of a result set is treated as "not found".
+#
+# A stored procedure must not return multiple result sets.
+# That is, there must be no code path that executes multiple
+# SELECT statements that return a result (instead of storing
+# their results in a table).
+#
+# The following is an example of a stored procedure returning
+# a single result set:
+#
+# .nf
+# CREATE [DEFINER=`user`@`host`] PROCEDURE
+# `lookup`(IN `param` VARCHAR(255))
+# READS SQL DATA
+# SQL SECURITY INVOKER
+# BEGIN
+# select goto from alias where address=param;
+# END
+# .fi
+# OBSOLETE MAIN.CF PARAMETERS
+# .ad
+# .fi
+# For compatibility with other Postfix lookup tables, MySQL
+# parameters can also be defined in main.cf. In order to do that,
+# specify as MySQL source a name that doesn't begin with a slash
+# or a dot. The MySQL parameters will then be accessible as the
+# name you've given the source in its definition, an underscore,
+# and the name of the parameter. For example, if the map is
+# specified as "mysql:\fImysqlname\fR", the parameter "hosts"
+# would be defined in main.cf as "\fImysqlname\fR_hosts".
+#
+# Note: with this form, the passwords for the MySQL sources are
+# written in main.cf, which is normally world-readable. Support
+# for this form will be removed in a future Postfix version.
+# OBSOLETE QUERY INTERFACE
+# .ad
+# .fi
+# This section describes an interface that is deprecated as
+# of Postfix 2.2. It is replaced by the more general \fBquery\fR
+# interface described above. If the \fBquery\fR parameter
+# is defined, the legacy parameters described here ignored.
+# Please migrate to the new interface as the legacy interface
+# may be removed in a future release.
+#
+# The following parameters can be used to fill in a
+# SELECT template statement of the form:
+#
+# .nf
+# SELECT [\fBselect_field\fR]
+# FROM [\fBtable\fR]
+# WHERE [\fBwhere_field\fR] = '%s'
+# [\fBadditional_conditions\fR]
+# .fi
+#
+# The specifier %s is replaced by the search string, and is
+# escaped so if it contains single quotes or other odd characters,
+# it will not cause a parse error, or worse, a security problem.
+# .IP "\fBselect_field\fR"
+# The SQL "select" parameter. Example:
+# .nf
+# \fBselect_field\fR = forw_addr
+# .fi
+# .IP "\fBtable\fR"
+# The SQL "select .. from" table name. Example:
+# .nf
+# \fBtable\fR = mxaliases
+# .fi
+# .IP "\fBwhere_field\fR
+# The SQL "select .. where" parameter. Example:
+# .nf
+# \fBwhere_field\fR = alias
+# .fi
+# .IP "\fBadditional_conditions\fR
+# Additional conditions to the SQL query. Example:
+# .nf
+# \fBadditional_conditions\fR = AND status = 'paid'
+# .fi
+# SEE ALSO
+# postmap(1), Postfix lookup table maintenance
+# postconf(5), configuration parameters
+# ldap_table(5), LDAP lookup tables
+# pgsql_table(5), PostgreSQL lookup tables
+# sqlite_table(5), SQLite lookup tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# MYSQL_README, Postfix MYSQL client guide
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# MySQL support was introduced with Postfix version 1.0.
+# AUTHOR(S)
+# Original implementation by:
+# Scott Cotton, Joshua Marcus
+# IC Group, Inc.
+#
+# Further enhancements by:
+# Liviu Daia
+# Institute of Mathematics of the Romanian Academy
+# P.O. BOX 1-764
+# RO-014700 Bucharest, ROMANIA
+#
+# Stored-procedure support by John Fawcett.
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/nisplus_table b/proto/nisplus_table
new file mode 100644
index 0000000..2c8aefc
--- /dev/null
+++ b/proto/nisplus_table
@@ -0,0 +1,89 @@
+#++
+# NAME
+# nisplus_table 5
+# SUMMARY
+# Postfix NIS+ client
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" "nisplus:[\fIname\fB=%s];\fIname.name.\fB"\fR
+#
+# \fBpostmap -q - "nisplus:[\fIname\fB=%s];\fIname.name.\fB" <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional lookup tables.
+# These tables are usually in \fBdbm\fR or \fBdb\fR format.
+# Alternatively, lookup tables can be specified as NIS+
+# databases.
+#
+# To find out what types of lookup tables your Postfix system
+# supports use the "\fBpostconf -m\fR" command.
+#
+# To test Postfix NIS+ lookup tables, use the "\fBpostmap -q\fR"
+# command as described in the SYNOPSIS above.
+# QUERY SYNTAX
+# .ad
+# .fi
+# Most of the NIS+ query is specified via the NIS+ map name. The
+# general format of a Postfix NIS+ map name is as follows:
+#
+# .fi
+# \fBnisplus:[\fIname\fB=%s];\fIname.name.name\fB.:\fIcolumn\fR
+# .fi
+#
+# Postfix NIS+ map names differ from what one normally
+# would use with commands such as \fBniscat\fR:
+# .IP \(bu
+# With each NIS+ table lookup, "\fB%s\fR" is replaced by a
+# version of the lookup string. There can be only one
+# "\fB%s\fR" instance in a Postfix NIS+ map name.
+# .IP \(bu
+# Postfix NIS+ map names use "\fB;\fR" instead of "\fB,\fR",
+# because the latter character is special in the Postfix
+# main.cf file. Postfix replaces "\fB;\fR" characters in
+# the map name by "\fB,\fR" before making NIS+ queries.
+# .IP \(bu
+# The ":\fIcolumn\fR" part in the NIS+ map name is not part
+# of the actual NIS+ query. Instead, it specifies the number
+# of the table column that provides the lookup result. When
+# no ":\fIcolumn\fR" is specified the first column (1) is used.
+# EXAMPLE
+# .ad
+# .fi
+# A NIS+ aliases map might be queried as follows:
+#
+# .nf
+# alias_maps = dbm:/etc/mail/aliases,
+# nisplus:[alias=%s];mail_aliases.org_dir.$mydomain.:1
+# .fi
+#
+# This queries the local aliases file before the NIS+ file.
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# AUTHOR(S)
+# Geoff Gibbs
+# UK-HGMP-RC
+# Hinxton
+# Cambridge
+# CB10 1SB, UK
+#
+# Adopted and adapted by:
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/pcre_table b/proto/pcre_table
new file mode 100644
index 0000000..0f58c2b
--- /dev/null
+++ b/proto/pcre_table
@@ -0,0 +1,248 @@
+#++
+# NAME
+# pcre_table 5
+# SUMMARY
+# format of Postfix PCRE tables
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" pcre:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+#
+# \fBpostmap -hmq - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+#
+# \fBpostmap -bmq - pcre:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting, mail routing, or access control. These tables
+# are usually in \fBdbm\fR or \fBdb\fR format.
+#
+# Alternatively, lookup tables can be specified in Perl Compatible
+# Regular Expression form. In this case, each input is compared
+# against a list of patterns. When a match is found, the
+# corresponding result is returned and the search is terminated.
+#
+# To find out what types of lookup tables your Postfix system
+# supports use the "\fBpostconf -m\fR" command.
+#
+# To test lookup tables, use the "\fBpostmap -q\fR" command
+# as described in the SYNOPSIS above. Use "\fBpostmap -hmq
+# -\fR <\fIfile\fR" for header_checks(5) patterns, and
+# "\fBpostmap -bmq -\fR <\fIfile\fR" for body_checks(5)
+# (Postfix 2.6 and later).
+#
+# This driver can be built with the pcre2 library (Postfix
+# 3.7 and later), or with the legacy pcre library (all Postfix
+# versions).
+# COMPATIBILITY
+# .ad
+# .fi
+# With Postfix version 2.2 and earlier specify "\fBpostmap
+# -fq\fR" to query a table that contains case sensitive
+# patterns. Patterns are case insensitive by default.
+# TABLE FORMAT
+# .ad
+# .fi
+# The general form of a PCRE table is:
+# .IP "\fB/\fIpattern\fB/\fIflags result\fR"
+# When \fIpattern\fR matches the input string, use
+# the corresponding \fIresult\fR value.
+# .IP "\fB!/\fIpattern\fB/\fIflags result\fR"
+# When \fIpattern\fR does \fBnot\fR match the input string, use
+# the corresponding \fIresult\fR value.
+# .IP "\fBif /\fIpattern\fB/\fIflags\fR"
+# .IP "\fBendif\fR"
+# If the input string matches /\fIpattern\fR/, then match that
+# input string against the patterns between \fBif\fR and
+# \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
+# .sp
+# Note: do not prepend whitespace to patterns inside
+# \fBif\fR..\fBendif\fR.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
+# .IP "\fBendif\fR"
+# If the input string does not match /\fIpattern\fR/, then
+# match that input string against the patterns between \fBif\fR
+# and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
+# .sp
+# Note: do not prepend whitespace to patterns inside
+# \fBif\fR..\fBendif\fR.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# .PP
+# Each pattern is a perl-like regular expression. The expression
+# delimiter can be any non-alphanumeric character, except
+# whitespace or characters
+# that have special meaning (traditionally the forward slash is used).
+# The regular expression can contain whitespace.
+#
+# By default, matching is case-insensitive, and newlines are not
+# treated as special characters. The behavior is controlled by flags,
+# which are toggled by appending one or more of the following
+# characters after the pattern:
+# .IP "\fBi\fR (default: on)"
+# Toggles the case sensitivity flag. By default, matching is case
+# insensitive.
+# .IP "\fBm\fR (default: off)"
+# Toggles the pcre MULTILINE flag. When this flag is on, the \fB^\fR
+# and \fB$\fR metacharacters match immediately after and immediately
+# before a newline character, respectively, in addition to
+# matching at the start and end of the subject string.
+# .IP "\fBs\fR (default: on)"
+# Toggles the pcre DOTALL flag. When this flag is on, the \fB.\fR
+# metacharacter matches the newline character. With
+# Postfix versions prior to 2.0, the flag is off by
+# default, which is inconvenient for multi-line message header
+# matching.
+# .IP "\fBx\fR (default: off)"
+# Toggles the pcre extended flag. When this flag is on, whitespace
+# characters in the pattern (other than in a character class)
+# are ignored. To include a whitespace character as part of
+# the pattern, escape it with backslash.
+# .sp
+# Note: do not use \fB#\fIcomment\fR after patterns.
+# .IP "\fBA\fR (default: off)"
+# Toggles the pcre ANCHORED flag. When this flag is on,
+# the pattern is forced to be "anchored", that is, it is
+# constrained to match only at the start of the string which
+# is being searched (the "subject string"). This effect can
+# also be achieved by appropriate constructs in the pattern
+# itself.
+# .IP "\fBE\fR (default: off)"
+# Toggles the pcre DOLLAR_ENDONLY flag. When this flag is on,
+# a \fB$\fR metacharacter in the pattern matches only at the
+# end of the subject string. Without this flag, a dollar also
+# matches immediately before the final character if it is a
+# newline character (but not before any other newline
+# characters). This flag is ignored if the pcre MULTILINE
+# flag is set.
+# .IP "\fBU\fR (default: off)"
+# Toggles the pcre UNGREEDY flag. When this flag is on,
+# the pattern matching engine inverts the "greediness" of
+# the quantifiers so that they are not greedy by default,
+# but become greedy if followed by "?". This flag can also
+# set by a (?U) modifier within the pattern.
+# .IP "\fBX\fR (default: off)"
+# Toggles the pcre EXTRA flag.
+# When this flag is on, any backslash in a pattern that is
+# followed by a letter that has no special meaning causes an
+# error, thus reserving these combinations for future expansion.
+#
+# This feature is not supported with PCRE2.
+# SEARCH ORDER
+# .ad
+# .fi
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the input string.
+#
+# Each pattern is applied to the entire input string.
+# Depending on the application, that string is an entire client
+# hostname, an entire client IP address, or an entire mail address.
+# Thus, no parent domain or parent network search is done, and
+# \fIuser@domain\fR mail addresses are not broken up into their
+# \fIuser\fR and \fIdomain\fR constituent parts, nor is \fIuser+foo\fR
+# broken up into \fIuser\fR and \fIfoo\fR.
+# TEXT SUBSTITUTION
+# .ad
+# .fi
+# Substitution of substrings (text that matches patterns
+# inside "()") from the matched expression into the result
+# string is requested with $1, $2, etc.; specify $$ to produce
+# a $ character as output.
+# The macros in the result string may need to be written as
+# ${n} or $(n) if they aren't followed by whitespace.
+# This feature does not support pcre2 substring names.
+#
+# Note: since negated patterns (those preceded by \fB!\fR) return a
+# result when the expression does not match, substitutions are not
+# available for negated patterns.
+# INLINE SPECIFICATION
+# .ad
+# .fi
+# The contents of a table may be specified in the table name
+# (Postfix 3.7 and later).
+# The basic syntax is:
+#
+# .nf
+# main.cf:
+# \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR
+#
+# master.cf:
+# \fB.. -o { \fIparameter\fR \fB= .. pcre:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
+# .fi
+#
+# Postfix ignores whitespace after '{' and before '}', and
+# writes each \fIrule\fR as one text line to an in-memory
+# file:
+#
+# .nf
+# in-memory file:
+# rule-1
+# rule-2
+# ..
+# .fi
+#
+# Postfix parses the result as if it is a file in /etc/postfix.
+#
+# Note: if a rule contains \fB$\fR, specify \fB$$\fR to keep
+# Postfix from trying to do \fI$name\fR expansion as it
+# evaluates a parameter value.
+# EXAMPLE SMTPD ACCESS MAP
+# # Protect your outgoing majordomo exploders
+# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
+#
+# # Bounce friend@whatever, except when whatever is our domain (you would
+# # be better just bouncing all friend@ mail - this is just an example).
+# /^(friend@(?!my\\.domain$).*)$/ 550 Stick this in your pipe $1
+#
+# # A multi-line entry. The text is sent as one line.
+# #
+# /^noddy@my\\.domain$/
+# \ 550 This user is a funny one. You really don't want to send mail to
+# \ them as it only makes their head spin.
+# EXAMPLE HEADER FILTER MAP
+# /^Subject: make money fast/ REJECT
+# /^To: friend@public\\.com/ REJECT
+# EXAMPLE BODY FILTER MAP
+# # First skip over base 64 encoded text to save CPU cycles.
+# # Requires PCRE version 3.
+# ~^[[:alnum:]+/]{60,}$~ OK
+#
+# # Put your own body patterns here.
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# regexp_table(5), format of POSIX regular expression tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# AUTHOR(S)
+# The PCRE table lookup code was originally written by:
+# Andrew McNamara
+# andrewm@connect.com.au
+# connect.com.au Pty. Ltd.
+# Level 3, 213 Miller St
+# North Sydney, NSW, Australia
+#
+# Adopted and adapted by:
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/pgsql_table b/proto/pgsql_table
new file mode 100644
index 0000000..f5d9683
--- /dev/null
+++ b/proto/pgsql_table
@@ -0,0 +1,319 @@
+#++
+# NAME
+# pgsql_table 5
+# SUMMARY
+# Postfix PostgreSQL client configuration
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" pgsql:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - pgsql:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting or mail routing. These tables are usually in
+# \fBdbm\fR or \fBdb\fR format.
+#
+# Alternatively, lookup tables can be specified as PostgreSQL
+# databases. In order to use PostgreSQL lookups, define a
+# PostgreSQL source as a lookup table in main.cf, for example:
+# .nf
+# alias_maps = pgsql:/etc/postfix/pgsql-aliases.cf
+# .fi
+#
+# The file /etc/postfix/pgsql-aliases.cf has the same format as
+# the Postfix main.cf file, and can specify the parameters
+# described below.
+# LIST MEMBERSHIP
+# .ad
+# .fi
+# When using SQL to store lists such as $mynetworks,
+# $mydestination, $relay_domains, $local_recipient_maps,
+# etc., it is important to understand that the table must
+# store each list member as a separate key. The table lookup
+# verifies the *existence* of the key. See "Postfix lists
+# versus tables" in the DATABASE_README document for a
+# discussion.
+#
+# Do NOT create tables that return the full list of domains
+# in $mydestination or $relay_domains etc., or IP addresses
+# in $mynetworks.
+#
+# DO create tables with each matching item as a key and with
+# an arbitrary value. With SQL databases it is not uncommon to
+# return the key itself or a constant value.
+# PGSQL PARAMETERS
+# .ad
+# .fi
+# .IP "\fBhosts\fR"
+# The hosts that Postfix will try to connect to and query
+# from. Besides a \fBpostgresql://\fR connection URI, this
+# setting supports the historical forms \fBunix:/\fIpathname\fR
+# for UNIX-domain sockets and \fBinet:\fIhost:port\fR for TCP
+# connections, where the \fBunix:\fR and \fBinet:\fR prefixes
+# are accepted and ignored for backwards compatibility.
+# Examples:
+# .nf
+# hosts = postgresql://username@example.com/tablename?sslmode=require
+# hosts = inet:host1.some.domain inet:host2.some.domain:port
+# hosts = host1.some.domain host2.some.domain:port
+# hosts = unix:/file/name
+# .fi
+#
+# The hosts are tried in random order. The connections are
+# automatically closed after being idle for about 1 minute,
+# and are re-opened as necessary.
+# .IP "\fBuser, password\fR"
+# The user name and password to log into the pgsql server.
+# Example:
+# .nf
+# user = someone
+# password = some_password
+# .fi
+# .IP "\fBdbname\fR"
+# The database name on the servers. Example:
+# .nf
+# dbname = customer_database
+# .fi
+# .IP "\fBquery\fR"
+# The SQL query template used to search the database, where \fB%s\fR
+# is a substitute for the address Postfix is trying to resolve,
+# e.g.
+# .nf
+# query = SELECT replacement FROM aliases WHERE mailbox = '%s'
+# .fi
+#
+# This parameter supports the following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character. (Postfix 2.2 and later)
+# .IP "\fB%s\fR"
+# This is replaced by the input key.
+# SQL quoting is used to make sure that the input key does not
+# add unexpected metacharacters.
+# .IP "\fB%u\fR"
+# When the input key is an address of the form user@domain, \fB%u\fR
+# is replaced by the SQL quoted local part of the address.
+# Otherwise, \fB%u\fR is replaced by the entire search string.
+# If the localpart is empty, the query is suppressed and returns
+# no results.
+# .IP "\fB%d\fR"
+# When the input key is an address of the form user@domain, \fB%d\fR
+# is replaced by the SQL quoted domain part of the address.
+# Otherwise, the query is suppressed and returns no results.
+# .IP "\fB%[SUD]\fR"
+# The upper-case equivalents of the above expansions behave in the
+# \fBquery\fR parameter identically to their lower-case counter-parts.
+# With the \fBresult_format\fR parameter (see below), they expand the
+# input key rather than the result value.
+# .IP
+# The above %S, %U and %D expansions are available with Postfix 2.2
+# and later
+# .IP "\fB%[1-9]\fR"
+# The patterns %1, %2, ... %9 are replaced by the corresponding
+# most significant component of the input key's domain. If the
+# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR,
+# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is
+# unqualified or does not have enough domain components to satisfy
+# all the specified patterns, the query is suppressed and returns
+# no results.
+# .IP
+# The above %1, ... %9 expansions are available with Postfix 2.2
+# and later
+# .RE
+# .IP
+# The \fBdomain\fR parameter described below limits the input
+# keys to addresses in matching domains. When the \fBdomain\fR
+# parameter is non-empty, SQL queries for unqualified addresses
+# or addresses in non-matching domains are suppressed
+# and return no results.
+#
+# The precedence of this parameter has changed with Postfix 2.2,
+# in prior releases the precedence was, from highest to lowest,
+# \fBselect_function\fR, \fBquery\fR, \fBselect_field\fR, ...
+#
+# With Postfix 2.2 the \fBquery\fR parameter has highest precedence,
+# see OBSOLETE QUERY INTERFACES below.
+#
+# NOTE: DO NOT put quotes around the \fBquery\fR parameter.
+# .IP "\fBresult_format (default: \fB%s\fR)\fR"
+# Format template applied to result attributes. Most commonly used
+# to append (or prepend) text to the result. This parameter supports
+# the following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character.
+# .IP "\fB%s\fR"
+# This is replaced by the value of the result attribute. When
+# result is empty it is skipped.
+# .IP "\fB%u\fR
+# When the result attribute value is an address of the form
+# user@domain, \fB%u\fR is replaced by the local part of the
+# address. When the result has an empty localpart it is skipped.
+# .IP "\fB%d\fR"
+# When a result attribute value is an address of the form
+# user@domain, \fB%d\fR is replaced by the domain part of
+# the attribute value. When the result is unqualified it
+# is skipped.
+# .IP "\fB%[SUD1-9]\fR"
+# The upper-case and decimal digit expansions interpolate
+# the parts of the input key rather than the result. Their
+# behavior is identical to that described with \fBquery\fR,
+# and in fact because the input key is known in advance, queries
+# whose key does not contain all the information specified in
+# the result template are suppressed and return no results.
+# .RE
+# .IP
+# For example, using "result_format = smtp:[%s]" allows one
+# to use a mailHost attribute as the basis of a transport(5)
+# table. After applying the result format, multiple values
+# are concatenated as comma separated strings. The expansion_limit
+# and parameter explained below allows one to restrict the number
+# of values in the result, which is especially useful for maps that
+# must return at most one value.
+#
+# The default value \fB%s\fR specifies that each result value should
+# be used as is.
+#
+# This parameter is available with Postfix 2.2 and later.
+#
+# NOTE: DO NOT put quotes around the result format!
+# .IP "\fBdomain (default: no domain list)\fR"
+# This is a list of domain names, paths to files, or "type:table"
+# databases. When specified, only fully qualified search
+# keys with a *non-empty* localpart and a matching domain
+# are eligible for lookup: 'user' lookups, bare domain lookups
+# and "@domain" lookups are not performed. This can significantly
+# reduce the query load on the PostgreSQL server.
+# .nf
+# domain = postfix.org, hash:/etc/postfix/searchdomains
+# .fi
+#
+# It is best not to use SQL to store the domains eligible
+# for SQL lookups.
+#
+# This parameter is available with Postfix 2.2 and later.
+#
+# NOTE: DO NOT define this parameter for local(8) aliases,
+# because the input keys are always unqualified.
+# .IP "\fBexpansion_limit (default: 0)\fR"
+# A limit on the total number of result elements returned
+# (as a comma separated list) by a lookup against the map.
+# A setting of zero disables the limit. Lookups fail with a
+# temporary error if the limit is exceeded. Setting the
+# limit to 1 ensures that lookups do not return multiple
+# values.
+# OBSOLETE MAIN.CF PARAMETERS
+# .ad
+# .fi
+# For compatibility with other Postfix lookup tables, PostgreSQL
+# parameters can also be defined in main.cf. In order to do
+# that, specify as PostgreSQL source a name that doesn't begin
+# with a slash or a dot. The PostgreSQL parameters will then
+# be accessible as the name you've given the source in its
+# definition, an underscore, and the name of the parameter. For
+# example, if the map is specified as "pgsql:\fIpgsqlname\fR",
+# the parameter "hosts" would be defined in main.cf as
+# "\fIpgsqlname\fR_hosts".
+#
+# Note: with this form, the passwords for the PostgreSQL sources
+# are written in main.cf, which is normally world-readable.
+# Support for this form will be removed in a future Postfix
+# version.
+# OBSOLETE QUERY INTERFACES
+# .ad
+# .fi
+# This section describes query interfaces that are deprecated
+# as of Postfix 2.2. Please migrate to the new \fBquery\fR
+# interface as the old interfaces are slated to be phased
+# out.
+# .IP "\fBselect_function\fR"
+# This parameter specifies a database function name. Example:
+# .nf
+# select_function = my_lookup_user_alias
+# .fi
+#
+# This is equivalent to:
+# .nf
+# query = SELECT my_lookup_user_alias('%s')
+# .fi
+#
+# This parameter overrides the legacy table-related fields (described
+# below). With Postfix versions prior to 2.2, it also overrides the
+# \fBquery\fR parameter. Starting with Postfix 2.2, the \fBquery\fR
+# parameter has highest precedence, and the \fBselect_function\fR
+# parameter is deprecated.
+# .PP
+# The following parameters (with lower precedence than the
+# \fBselect_function\fR interface described above) can be used to
+# build the SQL select statement as follows:
+#
+# .nf
+# SELECT [\fBselect_field\fR]
+# FROM [\fBtable\fR]
+# WHERE [\fBwhere_field\fR] = '%s'
+# [\fBadditional_conditions\fR]
+# .fi
+#
+# The specifier %s is replaced with each lookup by the lookup key
+# and is escaped so if it contains single quotes or other odd
+# characters, it will not cause a parse error, or worse, a security
+# problem.
+#
+# Starting with Postfix 2.2, this interface is obsoleted by the more
+# general \fBquery\fR interface described above. If higher precedence
+# the \fBquery\fR or \fBselect_function\fR parameters described above
+# are defined, the parameters described here are ignored.
+# .IP "\fBselect_field\fR"
+# The SQL "select" parameter. Example:
+# .nf
+# \fBselect_field\fR = forw_addr
+# .fi
+# .IP "\fBtable\fR"
+# The SQL "select .. from" table name. Example:
+# .nf
+# \fBtable\fR = mxaliases
+# .fi
+# .IP "\fBwhere_field\fR
+# The SQL "select .. where" parameter. Example:
+# .nf
+# \fBwhere_field\fR = alias
+# .fi
+# .IP "\fBadditional_conditions\fR
+# Additional conditions to the SQL query. Example:
+# .nf
+# \fBadditional_conditions\fR = AND status = 'paid'
+# .fi
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# ldap_table(5), LDAP lookup tables
+# mysql_table(5), MySQL lookup tables
+# sqlite_table(5), SQLite lookup tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# PGSQL_README, Postfix PostgreSQL client guide
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# PgSQL support was introduced with Postfix version 2.1.
+# AUTHOR(S)
+# Based on the MySQL client by:
+# Scott Cotton, Joshua Marcus
+# IC Group, Inc.
+#
+# Ported to PostgreSQL by:
+# Aaron Sethman
+#
+# Further enhanced by:
+# Liviu Daia
+# Institute of Mathematics of the Romanian Academy
+# P.O. BOX 1-764
+# RO-014700 Bucharest, ROMANIA
+#--
diff --git a/proto/postconf.html.epilog b/proto/postconf.html.epilog
new file mode 100644
index 0000000..46a20e9
--- /dev/null
+++ b/proto/postconf.html.epilog
@@ -0,0 +1,5 @@
+</dl>
+
+</body>
+
+</html>
diff --git a/proto/postconf.html.prolog b/proto/postconf.html.prolog
new file mode 100644
index 0000000..530d7b4
--- /dev/null
+++ b/proto/postconf.html.prolog
@@ -0,0 +1,105 @@
+<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
+ "http://www.w3.org/TR/html4/loose.dtd">
+
+<html>
+
+<head>
+
+<title>Postfix Configuration Parameters </title>
+
+<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+
+</head>
+
+<body>
+
+<h1><img src="postfix-logo.jpg" width="203" height="98" alt="">Postfix Configuration Parameters </h1>
+
+<hr>
+
+<h2> Postfix main.cf file format </h2>
+
+<p> The Postfix main.cf configuration file specifies a very small
+subset of all the parameters that control the operation of the
+Postfix mail system. Parameters not explicitly specified are left
+at their default values. </p>
+
+<p> The general format of the main.cf file is as follows: </p>
+
+<ul>
+
+<li> <p> Each logical line is in the form "parameter = value".
+Whitespace around the "=" is ignored, as is whitespace at the end
+of a logical line. </p>
+
+<li> <p> Empty lines and whitespace-only lines are ignored, as are
+lines whose first non-whitespace character is a `#'. </p>
+
+<li> <p> A logical line starts with non-whitespace text. A line
+that starts with whitespace continues a logical line. </p>
+
+<li> <p> A parameter value may refer to other parameters. </p>
+
+<ul>
+
+<li> <p> The expressions "$name" and "${name}" are recursively
+replaced with the value of the named parameter. The parameter name
+must contain only characters from the set [a-zA-Z0-9_].
+An undefined parameter value is replaced with the empty value. </p>
+
+<li> <p> The expressions "${name?value}" and "${name?{value}}" are
+replaced with "value" when "$name" is non-empty. The parameter name
+must contain only characters from the set [a-zA-Z0-9_]. These forms are
+supported with Postfix versions &ge; 2.2 and &ge; 3.0, respectively.
+</p>
+
+<li> <p> The expressions "${name:value}" and "${name:{value}}" are
+replaced with "value" when "$name" is empty. The parameter name must
+contain only characters from the set [a-zA-Z0-9_]. These forms are
+supported with Postfix versions &ge; 2.2 and &ge; 3.0, respectively.
+</p>
+
+<li> <p> The expression "${name?{value1}:{value2}}" is replaced
+with "value1" when "$name" is non-empty, and with "value2" when
+"$name" is empty. The "{}" is required for "value1", optional for
+"value2". The parameter name must contain only characters from the
+set [a-zA-Z0-9_]. This form is supported with Postfix versions
+&ge; 3.0. </p>
+
+<li> <p> The first item inside "${...}" may be a relational expression
+of the form: "{value3} == {value4}". Besides the "==" (equality)
+operator Postfix supports "!=" (inequality), "&lt;", "&le;", "&ge;",
+and "&gt;". The comparison is numerical when both operands are all
+digits, otherwise the comparison is lexicographical. These forms
+are supported with Postfix versions &ge; 3.0. </p>
+
+<li> <p> Each "value" is subject to recursive named parameter and
+relational expression evaluation, except where noted. </p>
+
+<li> <p> Whitespace before or after each "{value}" is ignored. </p>
+
+<li> <p> Specify "$$" to produce a single "$" character. </p>
+
+<li> <p> The legacy form "$(...)" is equivalent to the preferred
+form "${...}". </p>
+
+</ul>
+
+<li> <p> When the same parameter is defined multiple times, only
+the last instance is remembered. </p>
+
+<li> <p> Otherwise, the order of main.cf parameter definitions does
+not matter. </p>
+
+</ul>
+
+<p> The remainder of this document is a description of all Postfix
+configuration parameters. Default values are shown after the
+parameter name in parentheses, and can be looked up with the
+"<b>postconf -d</b>" command. </p>
+
+<p> Note: this is not an invitation to make changes to Postfix
+configuration parameters. Unnecessary changes are likely to impair
+the operation of the mail system. </p>
+
+<dl>
diff --git a/proto/postconf.man.epilog b/proto/postconf.man.epilog
new file mode 100644
index 0000000..1392615
--- /dev/null
+++ b/proto/postconf.man.epilog
@@ -0,0 +1,23 @@
+.SH SEE ALSO
+.na
+.nf
+postconf(1), Postfix configuration parameter maintenance
+master(5), Postfix daemon configuration maintenance
+.SH LICENSE
+.ad
+.fi
+The Secure Mailer license must be distributed with this software.
+.SH AUTHOR(S)
+.na
+.nf
+Wietse Venema
+IBM T.J. Watson Research
+P.O. Box 704
+Yorktown Heights, NY 10598, USA
+.sp
+Wietse Venema
+Google, Inc.
+111 8th Avenue
+New York, NY 10011, USA
+.sp
+Viktor Dukhovni
diff --git a/proto/postconf.man.prolog b/proto/postconf.man.prolog
new file mode 100644
index 0000000..64b1e97
--- /dev/null
+++ b/proto/postconf.man.prolog
@@ -0,0 +1,85 @@
+.TH POSTCONF 5
+.SH NAME
+postconf
+\-
+Postfix configuration parameters
+.SH SYNOPSIS
+.na
+.nf
+\fBpostconf\fR \fIparameter\fR ...
+
+\fBpostconf \-e\fR "\fIparameter=value\fR" ...
+.SH DESCRIPTION
+.ad
+.fi
+The Postfix main.cf configuration file specifies parameters that
+control the operation of the Postfix mail system. Typically the
+file contains only a small subset of all parameters; parameters
+not specified are left at their default values.
+.PP
+The general format of the main.cf file is as follows:
+.IP \(bu
+Each logical line has the form "parameter = value".
+Whitespace around the "=" is ignored, as is whitespace at the
+end of a logical line.
+.IP \(bu
+Empty lines and whitespace-only lines are ignored, as are lines
+whose first non-whitespace character is a `#'.
+.IP \(bu
+A logical line starts with non-whitespace text. A line that starts
+with whitespace continues a logical line.
+.IP \(bu
+A parameter value may refer to other parameters.
+.RS
+.IP \(bu
+The expressions "$name" and "${name}" are recursively replaced with
+the value of the named parameter. The parameter name must contain
+only characters from the set [a-zA-Z0-9_]. An undefined parameter
+value is replaced with the empty value.
+.IP \(bu
+The expressions "${name?value}" and "${name?{value}}" are replaced
+with "value" when "$name" is non-empty. The parameter name must
+contain only characters from the set [a-zA-Z0-9_]. These forms are
+supported with Postfix versions >= 2.2 and >= 3.0, respectively.
+.IP \(bu
+The expressions "${name:value}" and "${name:{value}}" are replaced
+with "value" when "$name" is empty. The parameter name must contain
+only characters from the set [a-zA-Z0-9_]. These forms are supported
+with Postfix versions >= 2.2 and >= 3.0, respectively.
+.IP \(bu
+The expression "${name?{value1}:{value2}}" is replaced with "value1"
+when "$name" is non-empty, and with "value2" when "$name" is empty.
+The "{}" is required for "value1", optional for "value2". The
+parameter name must contain only characters from the set [a-zA-Z0-9_].
+This form is supported with Postfix versions >= 3.0.
+.IP \(bu
+The first item inside "${...}" may be a relational expression of the
+form: "{value3} == {value4}". Besides the "==" (equality) operator
+Postfix supports "!=" (inequality), "<", "<=", ">=", and ">". The
+comparison is numerical when both operands are all digits, otherwise
+the comparison is lexicographical. These forms are supported with
+Postfix versions >= 3.0.
+.IP \(bu
+Each "value" is subject to recursive named parameter and relational
+expression evaluation, except where noted.
+.IP \(bu
+Whitespace before or after each "{value}" is ignored.
+.IP \(bu
+Specify "$$" to produce a single "$" character.
+.IP \(bu
+The legacy form "$(...)" is equivalent to the preferred form "${...}".
+.RE
+.IP \(bu
+When the same parameter is defined multiple times, only the last
+instance is remembered.
+.IP \(bu
+Otherwise, the order of main.cf parameter definitions does not matter.
+.PP
+The remainder of this document is a description of all Postfix
+configuration parameters. Default values are shown after the
+parameter name in parentheses, and can be looked up with the
+"\fBpostconf \-d\fR" command.
+.PP
+Note: this is not an invitation to make changes to Postfix
+configuration parameters. Unnecessary changes can impair the
+operation of the mail system.
diff --git a/proto/postconf.proto b/proto/postconf.proto
new file mode 100644
index 0000000..10b47cf
--- /dev/null
+++ b/proto/postconf.proto
@@ -0,0 +1,18715 @@
+# This is the input file for automatically generating the postconf(5)
+# manual page, the summaries of parameters in on-line manual pages,
+# and for the postconf.5.html hyperlinked document.
+#
+# The following tools operate on information from this file:
+#
+# xpostconf
+# Extracts specific parameter definitions from this file, or
+# produces a sorted version of all the information in this
+# document.
+#
+# postconf2html
+# Adds parameter name +default headers. The result can be embedded
+# into the postconf.5.html hyperlinked document.
+#
+# postconf2man
+# Converts this file into something that can be embedded into
+# the postconf(5) UNIX-style manual page. This tool knows only
+# a limited subset of HTML as described below.
+#
+# postconf2src
+# Converts this file result into something that can be embedded
+# into Postfix source code files.
+#
+# The subset of HTML that you can use is limited by the postconf2man
+# tool:
+#
+# * Supported HTML elements are: blockquote, ul, li, dl, dt, dd,
+# p, pre, b, i, h, and the escapes for < <= >= >. Sorry, no
+# tables.
+#
+# * HTML elements must be specified in lower case.
+#
+# * Lists cannot be nested.
+#
+# * The postconf2man tool leaves unrecognized HTML in place as a
+# reminder that it is not supported.
+#
+# * Text between <!-- and --> is stripped out. The <!-- and -->
+# must appear on separate lines.
+#
+# * Use <nroffescape .sp> to request an empty line in the middle
+# of a block of text. This is needed with indented lists.
+#
+# * 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:
+#
+# * All <dt> and <dd>text must be closed with </dt> and </dd>.
+#
+# * Use <blockquote><pre>..</pre></blockquote> for examples
+# between narrative text, instead of indenting examples by hand.
+#
+# * Use <pre>..</pre> for the "Examples:" section at the end
+# of a parameter description.
+#
+# The postlink tool automatically inserts hyperlinks for the following,
+# so you must not hyperlink that information yourself:
+#
+# * Postfix manual pages
+# * URLs
+# * RFCs
+# * Postfix configuration parameters
+# * Postfix README files
+# * Address classes and other terminology.
+#
+# The xpostconf and postconf2html tools expect the file format described
+# in the comments below. The description includes the transformation
+# that is done by the postconf2html tool.
+#
+# * The format of this file is blocks of text separated by one or
+# more empty (or all whitespace) lines.
+#
+# * A text block that begins with %PARAM specifies a parameter name
+# and its default value, separated by whitespace. The text in
+# the blocks that follow is the parameter description.
+#
+# * The first line (text up to the first ". ") is used in Postfix
+# on-line manual pages, in the one-line configuration parameter
+# summaries.
+#
+# * A text block that begins with the "<" character is treated as
+# literal HTML. For example, to specify a "dl" list element one
+# would write:
+#
+# |<dt><b>name</b></dt> <dd>
+# |
+# |text that describes "name".
+# |
+# |</dd> ...
+#
+# As described below, the text that describes "name" will be
+# enclosed with <p> and </p>.
+#
+# An "ul" list element would be written like this:
+#
+# |<li> text for this list element.
+#
+# * Any text block that does not begin with < is an error.
+
+%CLASS address-verification Address verification (Postfix 2.1 and later)
+
+<p>
+Sender/recipient address verification is implemented by sending
+probe email messages that are not actually delivered. This feature
+is requested via the reject_unverified_sender and
+reject_unverified_recipient access restrictions. The status of
+verification probes is maintained by the address verification
+service. See the file ADDRESS_VERIFICATION_README for information
+about how to configure and operate the Postfix sender/recipient
+address verification service.
+</p>
+
+%CLASS smtpd-compatibility Compatibility controls
+
+%CLASS resource-control Resource controls
+
+%CLASS after-queue-filter After-queue content filter
+
+<p>
+As of version 1.0, Postfix can be configured to send new mail to
+an external content filter AFTER the mail is queued. This content
+filter is expected to inject mail back into a (Postfix or other)
+MTA for further delivery. See the FILTER_README document for
+details.
+</p>
+
+%CLASS before-queue-filter Before-queue content filter
+
+<p>
+The Postfix SMTP server can be configured to send incoming mail to
+a real-time SMTP-based content filter BEFORE mail is queued. This
+content filter is expected to inject mail back into Postfix. See
+the SMTPD_PROXY_README document for details on how to configure
+and operate this feature.
+</p>
+
+%CLASS basic-config Basic configuration parameters
+
+%CLASS smtpd-access-relay SMTP server access and relay control
+
+%CLASS smtpd-sasl SMTP server SASL authentication
+
+%CLASS unknown-recipients Rejecting mail for unknown recipients
+
+%CLASS smtpd-reply-code SMTP server response codes
+
+%CLASS other Other configuration parameters
+
+%PARAM access_map_reject_code 554
+
+<p>
+The numerical Postfix SMTP server response code for
+an access(5) map "reject" action.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM access_map_defer_code 450
+
+<p>
+The numerical Postfix SMTP server response code for
+an access(5) map "defer" action, including "defer_if_permit"
+or "defer_if_reject". Prior to Postfix 2.6, the response
+is hard-coded as "450".
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+<p>
+This feature is available in Postfix 2.6 and later.
+</p>
+
+%PARAM address_verify_default_transport $default_transport
+
+<p>
+Overrides the default_transport parameter setting for address
+verification probes.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_local_transport $local_transport
+
+<p>
+Overrides the local_transport parameter setting for address
+verification probes.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_map see "postconf -d" output
+
+<p>
+Lookup table for persistent address verification status
+storage. The table is maintained by the verify(8) service, and
+is opened before the process releases privileges.
+</p>
+
+<p>
+The lookup table is persistent by default (Postfix 2.7 and later).
+Specify an empty table name to keep the information in volatile
+memory which is lost after "<b>postfix reload</b>" or "<b>postfix
+stop</b>". This is the default with Postfix version 2.6 and earlier.
+</p>
+
+<p>
+Specify a location in a file system that will not fill up. If the
+database becomes corrupted, the world comes to an end. To recover,
+delete (NOT: truncate) the file and do "<b>postfix reload</b>".
+</p>
+
+<p> Postfix daemon processes do not use root privileges when opening
+this file (Postfix 2.5 and later). The file must therefore be
+stored under a Postfix-owned directory such as the data_directory.
+As a migration aid, an attempt to open the file under a non-Postfix
+directory is redirected to the Postfix-owned data_directory, and a
+warning is logged. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+address_verify_map = hash:/var/lib/postfix/verify
+address_verify_map = btree:/var/lib/postfix/verify
+</pre>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_negative_cache yes
+
+<p>
+Enable caching of failed address verification probe results. When
+this feature is enabled, the cache may pollute quickly with garbage.
+When this feature is disabled, Postfix will generate an address
+probe for every lookup.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_negative_expire_time 3d
+
+<p>
+The time after which a failed probe expires from the address
+verification cache.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_negative_refresh_time 3h
+
+<p>
+The time after which a failed address verification probe needs to
+be refreshed.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is h (hours). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_cache_cleanup_interval 12h
+
+<p> The amount of time between verify(8) address verification
+database cleanup runs. This feature requires that the database
+supports the "delete" and "sequence" operators. Specify a zero
+interval to disable database cleanup. </p>
+
+<p> After each database cleanup run, the verify(8) daemon logs the
+number of entries that were retained and dropped. A cleanup run is
+logged as "partial" when the daemon terminates early after "<b>postfix
+reload</b>", "<b>postfix stop</b>", or no requests for $max_idle
+seconds. </p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is h (hours). </p>
+
+<p> This feature is available in Postfix 2.7. </p>
+
+%PARAM address_verify_poll_count normal: 3, overload: 1
+
+<p>
+How many times to query the verify(8) service for the completion
+of an address verification request in progress.
+</p>
+
+<p> By default, the Postfix SMTP server polls the verify(8) service
+up to three times under non-overload conditions, and only once when
+under overload. With Postfix version 2.5 and earlier, the SMTP
+server always polls the verify(8) service up to three times by
+default. </p>
+
+<p>
+Specify 1 to implement a crude form of greylisting, that is, always
+defer the first delivery request for a new address.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+# Postfix &le; 2.6 default
+address_verify_poll_count = 3
+# Poor man's greylisting
+address_verify_poll_count = 1
+</pre>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_poll_delay 3s
+
+<p>
+The delay between queries for the completion of an address
+verification request in progress.
+</p>
+
+<p>
+The default polling delay is 3 seconds.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_positive_expire_time 31d
+
+<p>
+The time after which a successful probe expires from the address
+verification cache.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_positive_refresh_time 7d
+
+<p>
+The time after which a successful address verification probe needs
+to be refreshed. The address verification status is not updated
+when the probe fails (optimistic caching).
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_relay_transport $relay_transport
+
+<p>
+Overrides the relay_transport parameter setting for address
+verification probes.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_relayhost $relayhost
+
+<p>
+Overrides the relayhost parameter setting for address verification
+probes. This information can be overruled with the transport(5) table.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_sender $double_bounce_sender
+
+<p> The sender address to use in address verification probes; prior
+to Postfix 2.5 the default was "postmaster". To
+avoid problems with address probes that are sent in response to
+address probes, the Postfix SMTP server excludes the probe sender
+address from all SMTPD access blocks. </p>
+
+<p>
+Specify an empty value (address_verify_sender =) or &lt;&gt; if you want
+to use the null sender address. Beware, some sites reject mail from
+&lt;&gt;, even though RFCs require that such addresses be accepted.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+address_verify_sender = &lt;&gt;
+address_verify_sender = postmaster@my.domain
+</pre>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_transport_maps $transport_maps
+
+<p>
+Overrides the transport_maps parameter setting for address verification
+probes.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM address_verify_virtual_transport $virtual_transport
+
+<p>
+Overrides the virtual_transport parameter setting for address
+verification probes.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM alias_database see "postconf -d" output
+
+<p>
+The alias databases for local(8) delivery that are updated with
+"<b>newaliases</b>" or with "<b>sendmail -bi</b>".
+</p>
+
+<p>
+This is a separate configuration parameter because not all the
+tables specified with $alias_maps have to be local files.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+alias_database = hash:/etc/aliases
+alias_database = hash:/etc/mail/aliases
+</pre>
+
+%PARAM alias_maps see "postconf -d" output
+
+<p>
+The alias databases that are used for local(8) delivery. See
+aliases(5) for syntax details.
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+Note: these lookups are recursive.
+</p>
+
+<p>
+The default list is system dependent. On systems with NIS, the
+default is to search the local alias database, then the NIS alias
+database.
+</p>
+
+<p>
+If you change the alias database, run "<b>postalias /etc/aliases</b>"
+(or wherever your system stores the mail alias file), or simply
+run "<b>newaliases</b>" to build the necessary DBM or DB file.
+</p>
+
+<p>
+The local(8) delivery agent disallows regular expression substitution
+of $1 etc. in alias_maps, because that would open a security hole.
+</p>
+
+<p>
+The local(8) delivery agent will silently ignore requests to use
+the proxymap(8) server within alias_maps. Instead it will open the
+table directly. Before Postfix version 2.2, the local(8) delivery
+agent will terminate with a fatal error.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+alias_maps = hash:/etc/aliases, nis:mail.aliases
+alias_maps = hash:/etc/aliases
+</pre>
+
+%PARAM allow_mail_to_commands alias, forward
+
+<p>
+Restrict local(8) mail delivery to external commands. The default
+is to disallow delivery to "|command" in :include: files (see
+aliases(5) for the text that defines this terminology).
+</p>
+
+<p>
+Specify zero or more of: <b>alias</b>, <b>forward</b> or <b>include</b>,
+in order to allow commands in aliases(5), .forward files or in
+:include: files, respectively.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+allow_mail_to_commands = alias,forward,include
+</pre>
+
+%PARAM allow_mail_to_files alias, forward
+
+<p>
+Restrict local(8) mail delivery to external files. The default is
+to disallow "/file/name" destinations in :include: files (see
+aliases(5) for the text that defines this terminology).
+</p>
+
+<p>
+Specify zero or more of: <b>alias</b>, <b>forward</b> or <b>include</b>,
+in order to allow "/file/name" destinations in aliases(5), .forward
+files and in :include: files, respectively.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+allow_mail_to_files = alias,forward,include
+</pre>
+
+%PARAM allow_min_user no
+
+<p>
+Allow a sender or recipient address to have `-' as the first
+character. By
+default, this is not allowed, to avoid accidents with software that
+passes email addresses via the command line. Such software
+would not be able to distinguish a malicious address from a
+bona fide command-line option. Although this can be prevented by
+inserting a "--" option terminator into the command line, this is
+difficult to enforce consistently and globally. </p>
+
+<p> As of Postfix version 2.5, this feature is implemented by
+trivial-rewrite(8). With earlier versions this feature was implemented
+by qmgr(8) and was limited to recipient addresses only. </p>
+
+%PARAM allow_percent_hack yes
+
+<p>
+Enable the rewriting of the form "user%domain" to "user@domain".
+This is enabled by default.
+</p>
+
+<p> Note: as of Postfix version 2.2, message header address rewriting
+happens only when one of the following conditions is true: </p>
+
+<ul>
+
+<li> The message is received with the Postfix sendmail(1) command,
+
+<li> The message is received from a network client that matches
+$local_header_rewrite_clients,
+
+<li> The message is received from the network, and the
+remote_header_rewrite_domain parameter specifies a non-empty value.
+
+</ul>
+
+<p> To get the behavior before Postfix version 2.2, specify
+"local_header_rewrite_clients = static:all". </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+allow_percent_hack = no
+</pre>
+
+%PARAM allow_untrusted_routing no
+
+<p>
+Forward mail with sender-specified routing (user[@%!]remote[@%!]site)
+from untrusted clients to destinations matching $relay_domains.
+</p>
+
+<p>
+By default, this feature is turned off. This closes a nasty open
+relay loophole where a backup MX host can be tricked into forwarding
+junk mail to a primary MX host which then spams it out to the world.
+</p>
+
+<p>
+This parameter also controls if non-local addresses with sender-specified
+routing can match Postfix access tables. By default, such addresses
+cannot match Postfix access tables, because the address is ambiguous.
+</p>
+
+%PARAM always_bcc
+
+<p>
+Optional address that receives a "blind carbon copy" of each message
+that is received by the Postfix mail system.
+</p>
+
+<p>
+Note: with Postfix 2.3 and later the BCC address is added as if it
+was specified with NOTIFY=NONE. The sender will not be notified
+when the BCC address is undeliverable, as long as all down-stream
+software implements RFC 3461.
+</p>
+
+<p>
+Note: with Postfix 2.2 and earlier the sender will be notified
+when the BCC address is undeliverable.
+</p>
+
+<p> Note: automatic BCC recipients are produced only for new mail.
+To avoid mailer loops, automatic BCC recipients are not generated
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
+
+%PARAM berkeley_db_create_buffer_size 16777216
+
+<p>
+The per-table I/O buffer size for programs that create Berkeley DB
+hash or btree tables. Specify a byte count.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM berkeley_db_read_buffer_size 131072
+
+<p>
+The per-table I/O buffer size for programs that read Berkeley DB
+hash or btree tables. Specify a byte count.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM best_mx_transport
+
+<p>
+Where the Postfix SMTP client should deliver mail when it detects
+a "mail loops back to myself" error condition. This happens when
+the local MTA is the best SMTP mail exchanger for a destination
+not listed in $mydestination, $inet_interfaces, $proxy_interfaces,
+$virtual_alias_domains, or $virtual_mailbox_domains. By default,
+the Postfix SMTP client returns such mail as undeliverable.
+</p>
+
+<p>
+Specify, for example, "best_mx_transport = local" to pass the mail
+from the Postfix SMTP client to the local(8) delivery agent. You
+can specify
+any message delivery "transport" or "transport:nexthop" that is
+defined in the master.cf file. See the transport(5) manual page
+for the syntax and meaning of "transport" or "transport:nexthop".
+</p>
+
+<p>
+However, this feature is expensive because it ties up a Postfix
+SMTP client process while the local(8) delivery agent is doing its
+work. It is more efficient (for Postfix) to list all hosted domains
+in a table or database.
+</p>
+
+%PARAM biff yes
+
+<p>
+Whether or not to use the local biff service. This service sends
+"new mail" notifications to users who have requested new mail
+notification with the UNIX command "biff y".
+</p>
+
+<p>
+For compatibility reasons this feature is on by default. On systems
+with lots of interactive users, the biff service can be a performance
+drain. Specify "biff = no" in main.cf to disable.
+</p>
+
+%PARAM body_checks
+
+<p> Optional lookup tables for content inspection as specified in
+the body_checks(5) manual page. </p>
+
+<p> Note: with Postfix versions before 2.0, these rules inspect
+all content after the primary message headers. </p>
+
+%PARAM body_checks_size_limit 51200
+
+<p>
+How much text in a message body segment (or attachment, if you
+prefer to use that term) is subjected to body_checks inspection.
+The amount of text is limited to avoid scanning huge attachments.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM bounce_queue_lifetime 5d
+
+<p>
+Consider a bounce message as undeliverable, when delivery fails
+with a temporary error, and the time in the queue has reached the
+bounce_queue_lifetime limit. By default, this limit is the same
+as for regular mail.
+</p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p>
+Specify 0 when mail delivery should be tried only once.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM bounce_size_limit 50000
+
+<p> The maximal amount of original message text that is sent in a
+non-delivery notification. Specify a byte count. A message is
+returned as either message/rfc822 (the complete original) or as
+text/rfc822-headers (the headers only). With Postfix version 2.4
+and earlier, a message is always returned as message/rfc822 and is
+truncated when it exceeds the size limit.
+</p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> If you increase this limit, then you should increase the
+mime_nesting_limit value proportionally. </p>
+
+<li> <p> Be careful when making changes. Excessively large values
+will result in the loss of non-delivery notifications, when a bounce
+message size exceeds a local or remote MTA's message size limit.
+</p>
+
+</ul>
+
+%PARAM canonical_maps
+
+<p>
+Optional address mapping lookup tables for message headers and
+envelopes. The mapping is applied to both sender and recipient
+addresses, in both envelopes and in headers, as controlled
+with the canonical_classes parameter. This is typically used
+to clean up dirty addresses from legacy mail systems, or to replace
+login names by Firstname.Lastname. The table format and lookups
+are documented in canonical(5). For an overview of Postfix address
+manipulations see the ADDRESS_REWRITING_README document.
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+Note: these lookups are recursive.
+</p>
+
+<p>
+If you use this feature, run "<b>postmap /etc/postfix/canonical</b>" to
+build the necessary DBM or DB file after every change. The changes
+will become visible after a minute or so. Use "<b>postfix reload</b>"
+to eliminate the delay.
+</p>
+
+<p> Note: with Postfix version 2.2, message header address mapping
+happens only when message header address rewriting is enabled: </p>
+
+<ul>
+
+<li> The message is received with the Postfix sendmail(1) command,
+
+<li> The message is received from a network client that matches
+$local_header_rewrite_clients,
+
+<li> The message is received from the network, and the
+remote_header_rewrite_domain parameter specifies a non-empty value.
+
+</ul>
+
+<p> To get the behavior before Postfix version 2.2, specify
+"local_header_rewrite_clients = static:all". </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+canonical_maps = dbm:/etc/postfix/canonical
+canonical_maps = hash:/etc/postfix/canonical
+</pre>
+
+%PARAM canonical_classes envelope_sender, envelope_recipient, header_sender, header_recipient
+
+<p> What addresses are subject to canonical_maps address mapping.
+By default, canonical_maps address mapping is applied to envelope
+sender and recipient addresses, and to header sender and header
+recipient addresses. </p>
+
+<p> Specify one or more of: envelope_sender, envelope_recipient,
+header_sender, header_recipient </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM sender_canonical_classes envelope_sender, header_sender
+
+<p> What addresses are subject to sender_canonical_maps address
+mapping. By default, sender_canonical_maps address mapping is
+applied to envelope sender addresses, and to header sender addresses.
+</p>
+
+<p> Specify one or more of: envelope_sender, header_sender </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM recipient_canonical_classes envelope_recipient, header_recipient
+
+<p> What addresses are subject to recipient_canonical_maps address
+mapping. By default, recipient_canonical_maps address mapping is
+applied to envelope recipient addresses, and to header recipient
+addresses. </p>
+
+<p> Specify one or more of: envelope_recipient, header_recipient
+</p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM command_directory see "postconf -d" output
+
+<p>
+The location of all postfix administrative commands.
+</p>
+
+%PARAM command_time_limit 1000s
+
+<p>
+Time limit for delivery to external commands. This limit is used
+by the local(8) delivery agent, and is the default time limit for
+delivery by the pipe(8) delivery agent.
+</p>
+
+<p>
+Note: if you set this time limit to a large value you must update the
+global ipc_timeout parameter as well.
+</p>
+
+%PARAM daemon_directory see "postconf -d" output
+
+<p>
+The directory with Postfix support programs and daemon programs.
+These should not be invoked directly by humans. The directory must
+be owned by root.
+</p>
+
+%PARAM daemon_timeout 18000s
+
+<p> How much time a Postfix daemon process may take to handle a
+request before it is terminated by a built-in watchdog timer. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM debug_peer_level 2
+
+<p> The increment in verbose logging level when a nexthop destination,
+remote client or server name or network address matches a pattern
+given with the debug_peer_list parameter. </p>
+
+<p> Per-nexthop debug logging is available in Postfix 3.6 and later. </p>
+
+%PARAM debug_peer_list
+
+<p> Optional list of nexthop destination, remote client or server
+name or network address patterns that, if matched, cause the verbose
+logging level to increase by the amount specified in $debug_peer_level.
+</p>
+
+<p> Per-nexthop debug logging is available in Postfix 3.6 and later. </p>
+
+<p> Specify domain names, network/netmask patterns, "/file/name"
+patterns or "type:table" lookup tables. The right-hand side result
+from "type:table" lookups is ignored. </p>
+
+<p> Pattern matching of domain names is controlled by the presence
+or absence of "debug_peer_list" in the parent_domain_matches_subdomains
+parameter value. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+debug_peer_list = 127.0.0.1
+debug_peer_list = example.com
+</pre>
+
+%PARAM default_database_type see "postconf -d" output
+
+<p>
+The default database type for use in newaliases(1), postalias(1)
+and postmap(1) commands. On many UNIX systems the default type is
+either <b>dbm</b> or <b>hash</b>. The default setting is frozen
+when the Postfix system is built.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+default_database_type = hash
+default_database_type = dbm
+</pre>
+
+%PARAM default_delivery_slot_cost 5
+
+<p>
+How often the Postfix queue manager's scheduler is allowed to
+preempt delivery of one message with another.
+</p>
+
+<p>
+Each transport maintains a so-called "available delivery slot counter"
+for each message. One message can be preempted by another one when
+the other message can be delivered using no more delivery slots
+(i.e., invocations of delivery agents) than the current message
+counter has accumulated (or will eventually accumulate - see about
+slot loans below). This parameter controls how often the counter is
+incremented - it happens after each default_delivery_slot_cost
+recipients have been delivered.
+</p>
+
+<p>
+The cost of 0 is used to disable the preempting scheduling completely.
+The minimum value the scheduling algorithm can use is 2 - use it
+if you want to maximize the message throughput rate. Although there
+is no maximum, it doesn't make much sense to use values above say
+50.
+</p>
+
+<p>
+The only reason why the value of 2 is not the default is the way
+this parameter affects the delivery of mailing-list mail. In the
+worst case, delivery can take somewhere between (cost+1/cost)
+and (cost/cost-1) times more than if the preemptive scheduler was
+disabled. The default value of 5 turns out to provide reasonable
+message response times while making sure the mailing-list deliveries
+are not extended by more than 20-25 percent even in the worst case.
+</p>
+
+<p> Use <i>transport</i>_delivery_slot_cost to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+default_delivery_slot_cost = 0
+default_delivery_slot_cost = 2
+</pre>
+
+%PARAM default_destination_concurrency_limit 20
+
+<p>
+The default maximal number of parallel deliveries to the same
+destination. This is the default limit for delivery via the lmtp(8),
+pipe(8), smtp(8) and virtual(8) delivery agents.
+With a per-destination recipient limit &gt; 1, a destination is a domain,
+otherwise it is a recipient.
+</p>
+
+<p> Use <i>transport</i>_destination_concurrency_limit to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+%PARAM default_destination_recipient_limit 50
+
+<p>
+The default maximal number of recipients per message delivery.
+This is the default limit for delivery via the lmtp(8), pipe(8),
+smtp(8) and virtual(8) delivery agents.
+</p>
+
+<p> Setting this parameter to a value of 1 affects email deliveries
+as follows:</p>
+
+<ul>
+
+<li> <p> It changes the meaning of the corresponding per-destination
+concurrency limit, from concurrency of deliveries to the <i>same
+domain</i> into concurrency of deliveries to the <i>same recipient</i>.
+Different recipients are delivered in parallel, subject to the
+process limits specified in master.cf. </p>
+
+<li> <p> It changes the meaning of the corresponding per-destination
+rate delay, from the delay between deliveries to the <i>same
+domain</i> into the delay between deliveries to the <i>same
+recipient</i>. Again, different recipients are delivered in parallel,
+subject to the process limits specified in master.cf. </p>
+
+<li> <p> It changes the meaning of other corresponding per-destination
+settings in a similar manner, from settings for delivery to the
+<i>same domain</i> into settings for delivery to the <i>same
+recipient</i>.
+
+</ul>
+
+<p> Use <i>transport</i>_destination_recipient_limit to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+%PARAM default_extra_recipient_limit 1000
+
+<p>
+The default value for the extra per-transport limit imposed on the
+number of in-memory recipients. This extra recipient space is
+reserved for the cases when the Postfix queue manager's scheduler
+preempts one message with another and suddenly needs some extra
+recipient slots for the chosen message in order to avoid performance
+degradation.
+</p>
+
+<p> Use <i>transport</i>_extra_recipient_limit to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+%PARAM default_minimum_delivery_slots 3
+
+<p>
+How many recipients a message must have in order to invoke the
+Postfix queue manager's scheduling algorithm at all. Messages
+which would never accumulate at least this many delivery slots
+(subject to slot cost parameter as well) are never preempted.
+</p>
+
+<p> Use <i>transport</i>_minimum_delivery_slots to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+%PARAM default_privs nobody
+
+<p>
+The default rights used by the local(8) delivery agent for delivery
+to an external file or command. These rights are used when delivery
+is requested from an aliases(5) file that is owned by <b>root</b>, or
+when delivery is done on behalf of <b>root</b>. <b>DO NOT SPECIFY A
+PRIVILEGED USER OR THE POSTFIX OWNER</b>.
+</p>
+
+%PARAM default_process_limit 100
+
+<p>
+The default maximal number of Postfix child processes that provide
+a given service. This limit can be overruled for specific services
+in the master.cf file.
+</p>
+
+%PARAM default_rbl_reply see "postconf -d" output
+
+<p>
+The default Postfix SMTP server response template for a request that is
+rejected by an RBL-based restriction. This template can be overruled
+by specific entries in the optional rbl_reply_maps lookup table.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+<p>
+The template does not support Postfix configuration parameter $name
+substitution. Instead, it supports exactly one level of $name
+substitution for the following attributes:
+</p>
+
+<dl>
+
+<dt><b>$client</b></dt>
+
+<dd>The client hostname and IP address, formatted as name[address]. </dd>
+
+<dt><b>$client_address</b></dt>
+
+<dd>The client IP address. </dd>
+
+<dt><b>$client_name</b></dt>
+
+<dd>The client hostname or "unknown". See reject_unknown_client_hostname
+for more details. </dd>
+
+<dt><b>$reverse_client_name</b></dt>
+
+<dd>The client hostname from address-&gt;name lookup, or "unknown".
+See reject_unknown_reverse_client_hostname for more details. </dd>
+
+#<dt><b>$forward_client_name</b></dt>
+#
+#<dd>The client hostname from address-&gt;name lookup followed by
+#name-&gt;address lookup, or "unknown". See
+#reject_unknown_forward_client_hostname for more details. </dd>
+
+<dt><b>$helo_name</b></dt>
+
+<dd>The hostname given in HELO or EHLO command or empty string. </dd>
+
+<dt><b>$rbl_class</b></dt>
+
+<dd>The denylisted entity type: Client host, Helo command, Sender
+address, or Recipient address. </dd>
+
+<dt><b>$rbl_code</b></dt>
+
+<dd>The numerical SMTP response code, as specified with the
+maps_rbl_reject_code configuration parameter. Note: The numerical
+SMTP response code is required, and must appear at the start of the
+reply. With Postfix version 2.3 and later this information may be followed
+by an RFC 3463 enhanced status code. </dd>
+
+<dt><b>$rbl_domain</b></dt>
+
+<dd>The RBL domain where $rbl_what is denylisted. </dd>
+
+<dt><b>$rbl_reason</b></dt>
+
+<dd>The reason why $rbl_what is denylisted, or an empty string. </dd>
+
+<dt><b>$rbl_what</b></dt>
+
+<dd>The entity that is denylisted (an IP address, a hostname, a domain
+name, or an email address whose domain was denylisted). </dd>
+
+<dt><b>$recipient</b></dt>
+
+<dd>The recipient address or &lt;&gt; in case of the null address. </dd>
+
+<dt><b>$recipient_domain</b></dt>
+
+<dd>The recipient domain or empty string. </dd>
+
+<dt><b>$recipient_name</b></dt>
+
+<dd>The recipient address localpart or &lt;&gt; in case of null address. </dd>
+
+<dt><b>$sender</b></dt>
+
+<dd>The sender address or &lt;&gt; in case of the null address. </dd>
+
+<dt><b>$sender_domain</b></dt>
+
+<dd>The sender domain or empty string. </dd>
+
+<dt><b>$sender_name</b></dt>
+
+<dd>The sender address localpart or &lt;&gt; in case of the null address. </dd>
+
+<dt><b>${name?value}</b></dt>
+
+<dt><b>${name?{value}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd>
+
+<dt><b>${name:value}</b></dt>
+
+<dt><b>${name:{value}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd>
+
+<dt><b>${name?{value1}:{value2}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value1</i> when <i>$name</i> is non-empty,
+<i>value2</i> otherwise. </dd>
+
+</dl>
+
+<p>
+Instead of $name you can also specify ${name} or $(name).
+</p>
+
+<p> Note: when an enhanced status code is specified in an RBL reply
+template, it is subject to modification. The following transformations
+are needed when the same RBL reply template is used for client,
+helo, sender, or recipient access restrictions. </p>
+
+<ul>
+
+<li> <p> When rejecting a sender address, the Postfix SMTP server
+will transform a recipient DSN status (e.g., 4.1.1-4.1.6) into the
+corresponding sender DSN status, and vice versa. </p>
+
+<li> <p> When rejecting non-address information (such as the HELO
+command argument or the client hostname/address), the Postfix SMTP
+server will transform a sender or recipient DSN status into a generic
+non-address DSN status (e.g., 4.0.0). </p>
+
+</ul>
+
+%PARAM default_recipient_limit 20000
+
+<p>
+The default per-transport upper limit on the number of in-memory
+recipients. These limits take priority over the global
+qmgr_message_recipient_limit after the message has been assigned
+to the respective transports. See also default_extra_recipient_limit
+and qmgr_message_recipient_minimum.
+</p>
+
+<p> Use <i>transport</i>_recipient_limit to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+%PARAM default_recipient_refill_limit 100
+
+<p>
+The default per-transport limit on the number of recipients refilled at
+once. When not all message recipients fit into memory at once, keep
+loading more of them in batches of at least this many at a time. See also
+$default_recipient_refill_delay, which may result in recipient batches
+lower than this when this limit is too high for too slow deliveries.
+</p>
+
+<p> Use <i>transport</i>_recipient_refill_limit to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+<p> This feature is available in Postfix 2.4 and later. </p>
+
+%PARAM default_recipient_refill_delay 5s
+
+<p>
+The default per-transport maximum delay between refilling recipients.
+When not all message recipients fit into memory at once, keep loading
+more of them at least once every this many seconds. This is used to
+make sure the recipients are refilled in a timely manner even when
+$default_recipient_refill_limit is too high for too slow deliveries.
+</p>
+
+<p> Use <i>transport</i>_recipient_refill_delay to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+<p> This feature is available in Postfix 2.4 and later. </p>
+
+%PARAM default_transport smtp
+
+<p>
+The default mail delivery transport and next-hop destination for
+destinations that do not match $mydestination, $inet_interfaces,
+$proxy_interfaces, $virtual_alias_domains, $virtual_mailbox_domains,
+or $relay_domains. This information can be overruled with the
+sender_dependent_default_transport_maps parameter and with the
+transport(5) table. </p>
+
+<p>
+In order of decreasing precedence, the nexthop destination is taken
+from $sender_dependent_default_transport_maps, $default_transport,
+$sender_dependent_relayhost_maps, $relayhost, or from the recipient
+domain.
+</p>
+
+<p>
+Specify a string of the form <i>transport:nexthop</i>, where <i>transport</i>
+is the name of a mail delivery transport defined in master.cf.
+The <i>:nexthop</i> destination is optional; its syntax is documented
+in the manual page of the corresponding delivery agent. In the case of
+SMTP or LMTP, specify one or more destinations separated by comma or
+whitespace (with Postfix 3.5 and later).
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+default_transport = uucp:relayhostname
+</pre>
+
+%PARAM defer_code 450
+
+<p>
+The numerical Postfix SMTP server response code when a remote SMTP
+client request is rejected by the "defer" restriction.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM defer_transports
+
+<p>
+The names of message delivery transports that should not deliver mail
+unless someone issues "<b>sendmail -q</b>" or equivalent. Specify zero
+or more mail delivery transport names that appear in the
+first field of master.cf.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+defer_transports = smtp
+</pre>
+
+%PARAM deliver_lock_attempts 20
+
+<p>
+The maximal number of attempts to acquire an exclusive lock on a
+mailbox file or bounce(8) logfile.
+</p>
+
+%PARAM deliver_lock_delay 1s
+
+<p>
+The time between attempts to acquire an exclusive lock on a mailbox
+file or bounce(8) logfile.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM disable_vrfy_command no
+
+<p>
+Disable the SMTP VRFY command. This stops some techniques used to
+harvest email addresses.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+disable_vrfy_command = no
+</pre>
+
+%PARAM double_bounce_sender double-bounce
+
+<p> The sender address of postmaster notifications that are generated
+by the mail system. All mail to this address is silently discarded,
+in order to terminate mail bounce loops. </p>
+
+%PARAM duplicate_filter_limit 1000
+
+<p> The maximal number of addresses remembered by the address
+duplicate filter for aliases(5) or virtual(5) alias expansion, or
+for showq(8) queue displays. </p>
+
+%PARAM enable_original_recipient yes
+
+<p> Enable support for the original recipient address after an
+address is rewritten to a different address (for example with
+aliasing or with canonical mapping). </p>
+
+<p> The original recipient address is used as follows: </p>
+
+<dl>
+
+<dt> Final delivery </dt> <dd> With "enable_original_recipient =
+yes", the original recipient address is stored in the <b>X-Original-To</b>
+message header. This header may be used to distinguish between
+different recipients that share the same mailbox. </dd>
+
+<dt> Recipient deduplication </dt> <dd> With "enable_original_recipient
+= yes", the cleanup(8) daemon performs duplicate recipient elimination
+based on the content of (original recipient, maybe-rewritten
+recipient) pairs. Otherwise, the cleanup(8) daemon performs duplicate
+recipient elimination based only on the maybe-rewritten recipient
+address. </dd>
+
+</dl>
+
+<p> Note: with Postfix &le; 3.2 the "setting enable_original_recipient
+= <b>no</b>" breaks address verification for addresses that are
+aliased or otherwise rewritten (Postfix is unable to store the
+address verification result under the original probe destination
+address; instead, it can store the result only under the rewritten
+address). </p>
+
+<p> This feature is available in Postfix 2.1 and later. Postfix
+version 2.0 behaves as if this parameter is always set to <b>yes</b>.
+Postfix versions before 2.0 have no support for the original recipient
+address. </p>
+
+%PARAM export_environment see "postconf -d" output
+
+<p>
+The list of environment variables that a Postfix process will export
+to non-Postfix processes. The TZ variable is needed for sane
+time keeping on System-V-ish systems.
+</p>
+
+<p>
+Specify a list of names and/or name=value pairs, separated by
+whitespace or comma. Specify "{ name=value }" to protect whitespace
+or comma in parameter values (whitespace after the opening "{" and
+before the closing "}"
+is ignored). The form name=value is supported with Postfix version
+2.1 and later; the use of {} is supported with Postfix 3.0 and
+later. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+export_environment = TZ PATH=/bin:/usr/bin
+</pre>
+
+%PARAM smtp_fallback_relay $fallback_relay
+
+<p>
+Optional list of relay hosts for SMTP destinations that can't be
+found or that are unreachable. With Postfix 2.2 and earlier this
+parameter is called fallback_relay. </p>
+
+<p>
+By default, mail is returned to the sender when a destination is
+not found, and delivery is deferred when a destination is unreachable.
+</p>
+
+<p> With bulk email deliveries, it can be beneficial to run the
+fallback relay MTA on the same host, so that it can reuse the sender
+IP address. This speeds up deliveries that are delayed by IP-based
+reputation systems (greylist, etc.). </p>
+
+<p> The fallback relays must be SMTP destinations. Specify a domain,
+host, host:port, [host]:port, [address] or [address]:port; the form
+[host] turns off MX lookups. If you specify multiple SMTP
+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.2 and later will not use the fallback relays for
+destinations that it is MX host for (assuming DNS lookup is turned on).
+</p>
+
+%PARAM fallback_relay
+
+<p>
+Optional list of relay hosts for SMTP destinations that can't be
+found or that are unreachable. With Postfix 2.3 this parameter
+is renamed to smtp_fallback_relay. </p>
+
+<p>
+By default, mail is returned to the sender when a destination is
+not found, and delivery is deferred when a destination is unreachable.
+</p>
+
+<p> The fallback relays must be SMTP destinations. Specify a domain,
+host, host:port, [host]:port, [address] or [address]:port; the form
+[host] turns off MX lookups. If you specify multiple SMTP
+destinations, Postfix will try them in the specified order. </p>
+
+<p> Note: before Postfix 2.2, do not use the fallback_relay feature
+when relaying mail
+for a backup or primary MX domain. Mail would loop between the
+Postfix MX host and the fallback_relay host when the final destination
+is unavailable. </p>
+
+<ul>
+
+<li> In main.cf specify "relay_transport = relay",
+
+<li> In master.cf specify "-o fallback_relay =" (i.e., empty) at
+the end of the <tt>relay</tt> entry.
+
+<li> In transport maps, specify "relay:<i>nexthop...</i>"
+as the right-hand side for backup or primary MX domain entries.
+
+</ul>
+
+<p> Postfix version 2.2 and later will not use the fallback_relay feature
+for destinations that it is MX host for.
+</p>
+
+%PARAM lmtp_fallback_relay
+
+<p> Optional list of relay hosts for LMTP destinations that can't be
+found or that are unreachable. In main.cf elements are separated by
+whitespace or commas. </p>
+
+<p> By default, mail is returned to the sender when a destination is not
+found, and delivery is deferred when a destination is unreachable. </p>
+
+<p> The fallback relays must be TCP destinations, specified without
+a leading "inet:" prefix. Specify a host or host:port. Since MX
+lookups do not apply with LMTP, there is no need to use the "[host]" or
+"[host]:port" forms. If you specify multiple LMTP destinations, Postfix
+will try them in the specified order. </p>
+
+<p>
+This feature is available in Postfix 3.1 and later.
+</p>
+
+%PARAM fast_flush_domains $relay_domains
+
+<p>
+Optional list of destinations that are eligible for per-destination
+logfiles with mail that is queued to those destinations.
+</p>
+
+<p>
+By default, Postfix maintains "fast flush" logfiles only for
+destinations that the Postfix SMTP server is willing to relay to
+(i.e. the default is: "fast_flush_domains = $relay_domains"; see
+the relay_domains parameter in the postconf(5) manual).
+</p>
+
+<p> Specify a list of hosts or domains, "/file/name" patterns or
+"type:table" lookup tables, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace. A
+"/file/name" pattern is replaced by its contents; a "type:table"
+lookup table is matched when the domain or its parent domain appears
+as lookup key. </p>
+
+<p> Pattern matching of domain names is controlled by the presence
+or absence of "fast_flush_domains" in the parent_domain_matches_subdomains
+parameter value. </p>
+
+<p>
+Specify "fast_flush_domains =" (i.e., empty) to disable the feature
+altogether.
+</p>
+
+%PARAM fast_flush_purge_time 7d
+
+<p>
+The time after which an empty per-destination "fast flush" logfile
+is deleted.
+</p>
+
+<p>
+You can specify the time as a number, or as a number followed by
+a letter that indicates the time unit: s=seconds, m=minutes, h=hours,
+d=days, w=weeks. The default time unit is days.
+</p>
+
+%PARAM fast_flush_refresh_time 12h
+
+<p>
+The time after which a non-empty but unread per-destination "fast
+flush" logfile needs to be refreshed. The contents of a logfile
+are refreshed by requesting delivery of all messages listed in the
+logfile.
+</p>
+
+<p>
+You can specify the time as a number, or as a number followed by
+a letter that indicates the time unit: s=seconds, m=minutes, h=hours,
+d=days, w=weeks. The default time unit is hours.
+</p>
+
+%PARAM fork_attempts 5
+
+<p> The maximal number of attempts to fork() a child process. </p>
+
+%PARAM fork_delay 1s
+
+<p> The delay between attempts to fork() a child process. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM execution_directory_expansion_filter see "postconf -d" output
+
+<p> Restrict the characters that the local(8) delivery agent allows
+in $name expansions of $command_execution_directory. Characters
+outside the allowed set are replaced by underscores. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM command_execution_directory
+
+<p> The local(8) delivery agent working directory for delivery to
+external commands. Failure to change directory causes the delivery
+to be deferred. </p>
+
+<p> The command_execution_directory value is not subject to Postfix
+configuration parameter $name expansion. Instead, the following
+$name expansions are done on command_execution_directory before the
+directory is used. Expansion happens in the context
+of the delivery request. The result of $name expansion is filtered
+with the character set that is specified with the
+execution_directory_expansion_filter parameter. </p>
+
+<dl>
+
+<dt><b>$user</b></dt>
+
+<dd>The recipient's username. </dd>
+
+<dt><b>$shell</b></dt>
+
+<dd>The recipient's login shell pathname. </dd>
+
+<dt><b>$home</b></dt>
+
+<dd>The recipient's home directory. </dd>
+
+<dt><b>$recipient</b></dt>
+
+<dd>The full recipient address. </dd>
+
+<dt><b>$extension</b></dt>
+
+<dd>The optional recipient address extension. </dd>
+
+<dt><b>$domain</b></dt>
+
+<dd>The recipient domain. </dd>
+
+<dt><b>$local</b></dt>
+
+<dd>The entire recipient localpart. </dd>
+
+<dt><b>$recipient_delimiter</b></dt>
+
+<dd>The address extension delimiter that was found in the recipient
+address (Postfix 2.11 and later), or the system-wide recipient
+address extension delimiter (Postfix 2.10 and earlier). </dd>
+
+<dt><b>${name?value}</b></dt>
+
+<dt><b>${name?{value}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd>
+
+<dt><b>${name:value}</b></dt>
+
+<dt><b>${name:{value}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd>
+
+<dt><b>${name?{value1}:{value2}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value1</i> when <i>$name</i> is non-empty,
+<i>value2</i> otherwise. </dd>
+
+</dl>
+
+<p>
+Instead of $name you can also specify ${name} or $(name).
+</p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM forward_path see "postconf -d" output
+
+<p> The local(8) delivery agent search list for finding a .forward
+file with user-specified delivery methods. The first file that is
+found is used. </p>
+
+<p> The forward_path value is not subject to Postfix configuration
+parameter $name expansion. Instead, the following $name expansions
+are done on forward_path before the search actually happens.
+The result of $name expansion is
+filtered with the character set that is specified with the
+forward_expansion_filter parameter. </p>
+
+<dl>
+
+<dt><b>$user</b></dt>
+
+<dd>The recipient's username. </dd>
+
+<dt><b>$shell</b></dt>
+
+<dd>The recipient's login shell pathname. </dd>
+
+<dt><b>$home</b></dt>
+
+<dd>The recipient's home directory. </dd>
+
+<dt><b>$recipient</b></dt>
+
+<dd>The full recipient address. </dd>
+
+<dt><b>$extension</b></dt>
+
+<dd>The optional recipient address extension. </dd>
+
+<dt><b>$domain</b></dt>
+
+<dd>The recipient domain. </dd>
+
+<dt><b>$local</b></dt>
+
+<dd>The entire recipient localpart. </dd>
+
+<dt><b>$recipient_delimiter</b></dt>
+
+<dd>The address extension delimiter that was found in the recipient
+address (Postfix 2.11 and later), or the 'first' delimiter specified
+with the system-wide recipient address extension delimiter (Postfix
+3.5.22, 3.5.12, 3.7.8, 3.8.3 and later). Historically, this was
+always the system-wide recipient
+address extension delimiter (Postfix 2.10 and earlier). </dd>
+
+<dt><b>${name?value}</b></dt>
+
+<dt><b>${name?{value}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd>
+
+<dt><b>${name:value}</b></dt>
+
+<dt><b>${name:{value}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd>
+
+<dt><b>${name?{value1}:{value2}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value1</i> when <i>$name</i> is non-empty,
+<i>value2</i> otherwise. </dd>
+
+</dl>
+
+<p>
+Instead of $name you can also specify ${name} or $(name).
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+forward_path = /var/forward/$user
+forward_path =
+ /var/forward/$user/.forward$recipient_delimiter$extension,
+ /var/forward/$user/.forward
+</pre>
+
+%CLASS queue-hashing Queue directory hashing
+
+<p>
+Queue directory hashing is a performance feature. Splitting one
+queue directory across multiple subdirectory levels can speed up
+file access by reducing the number of files per directory.
+</p>
+
+<p>
+Unfortunately, deeply hashing the incoming or deferred queue can
+actually slow down the mail system (with a depth of 2, mailq with
+an empty queue can take several seconds).
+</p>
+
+<p>
+Hashing must NOT be used with a world-writable maildrop directory.
+Hashing MUST be used for the defer logfile directory, to avoid poor
+performance when handling lots of deferred mail.
+</p>
+
+%PARAM hash_queue_depth 1
+
+<p>
+The number of subdirectory levels for queue directories listed with
+the hash_queue_names parameter. Queue hashing is implemented by
+creating one or more levels of directories with one-character names.
+Originally, these directory names were equal to the first characters
+of the queue file name, with the hexadecimal representation of the
+file creation time in microseconds. </p>
+
+<p> With long queue file names, queue hashing produces the same
+results as with short names. The file creation time in microseconds
+is converted into hexadecimal form before the result is used for
+queue hashing. The base 16 encoding gives finer control over the
+number of subdirectories than is possible with the base 52 encoding
+of long queue file names. </p>
+
+<p>
+After changing the hash_queue_names or hash_queue_depth parameter,
+execute the command "<b>postfix reload</b>".
+</p>
+
+%PARAM hash_queue_names deferred, defer
+
+<p>
+The names of queue directories that are split across multiple
+subdirectory levels.
+</p>
+
+<p> Before Postfix version 2.2, the default list of hashed queues
+was significantly larger. Claims about improvements in file system
+technology suggest that hashing of the incoming and active queues
+is no longer needed. Fewer hashed directories speed up the time
+needed to restart Postfix. </p>
+
+<p>
+After changing the hash_queue_names or hash_queue_depth parameter,
+execute the command "<b>postfix reload</b>".
+</p>
+
+%CLASS headerbody-checks Content inspection built-in features
+
+<p>
+The Postfix cleanup(8) server has a limited ability to inspect
+message headers and body content for signs of trouble. This is not
+meant to be a substitute for content filters that do complex
+processing such attachment decoding and unzipping.
+</p>
+
+%PARAM header_checks
+
+<p>
+Optional lookup tables for content inspection of primary non-MIME
+message headers, as specified in the header_checks(5) manual page.
+</p>
+
+%PARAM header_size_limit 102400
+
+<p>
+The maximal amount of memory in bytes for storing a message header.
+If a header is larger, the excess is discarded. The limit is
+enforced by the cleanup(8) server.
+</p>
+
+%PARAM home_mailbox
+
+<p>
+Optional pathname of a mailbox file relative to a local(8) user's
+home directory.
+</p>
+
+<p>
+Specify a pathname ending in "/" for qmail-style delivery.
+</p>
+
+<p> The precedence of local(8) delivery features from high to low
+is: aliases, .forward files, mailbox_transport_maps, mailbox_transport,
+mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory,
+fallback_transport_maps, fallback_transport and luser_relay. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+home_mailbox = Mailbox
+home_mailbox = Maildir/
+</pre>
+
+%PARAM hopcount_limit 50
+
+<p>
+The maximal number of Received: message headers that is allowed
+in the primary message headers. A message that exceeds the limit
+is bounced, in order to stop a mailer loop.
+</p>
+
+%PARAM ignore_mx_lookup_error no
+
+<p> Ignore DNS MX lookups that produce no response. By default,
+the Postfix SMTP client defers delivery and tries again after some
+delay. This behavior is required by the SMTP standard. </p>
+
+<p>
+Specify "ignore_mx_lookup_error = yes" to force a DNS A record
+lookup instead. This violates the SMTP standard and can result in
+mis-delivery of mail.
+</p>
+
+%PARAM import_environment see "postconf -d" output
+
+<p> The list of environment variables that a privileged Postfix
+process will import from a non-Postfix parent process, or name=value
+environment overrides. Unprivileged utilities will enforce the
+name=value overrides, but otherwise will not change their process
+environment. Examples of relevant environment variables: </p>
+
+<dl>
+
+<dt><b>TZ</b></dt>
+
+<dd>May be needed for sane time keeping on most System-V-ish systems.
+</dd>
+
+<dt><b>DISPLAY</b></dt>
+
+<dd>Needed for debugging Postfix daemons with an X-windows debugger. </dd>
+
+<dt><b>XAUTHORITY</b></dt>
+
+<dd>Needed for debugging Postfix daemons with an X-windows debugger. </dd>
+
+<dt><b>MAIL_CONFIG</b></dt>
+
+<dd>Needed to make "<b>postfix -c</b>" work. </dd>
+
+</dl>
+
+<p> Specify a list of names and/or name=value pairs, separated by
+whitespace or comma. Specify "{ name=value }" to protect whitespace
+or comma in environment variable values (whitespace after the opening "{" and
+before the closing "}"
+is ignored). The form name=value is supported with Postfix version
+2.1 and later; the use of {} is supported with Postfix 3.0 and
+later. </p>
+
+%PARAM in_flow_delay 1s
+
+<p> Time to pause before accepting a new message, when the message
+arrival rate exceeds the message delivery rate. This feature is
+turned on by default (it's disabled on SCO UNIX due to an SCO bug).
+</p>
+
+<p>
+With the default 100 Postfix SMTP server process limit, "in_flow_delay
+= 1s" limits the mail inflow to 100 messages per second above the
+number of messages delivered per second.
+</p>
+
+<p>
+Specify 0 to disable the feature. Valid delays are 0..10.
+</p>
+
+%PARAM inet_interfaces all
+
+<p> The network interface addresses that this mail system receives
+mail on. Specify "all" to receive mail on all network
+interfaces (default), and "loopback-only" to receive mail
+on loopback network interfaces only (Postfix version 2.2 and later). The
+parameter also controls delivery of mail to <tt>user@[ip.address]</tt>.
+</p>
+
+<p>
+Note 1: you need to stop and start Postfix when this parameter changes.
+</p>
+
+<p> Note 2: address information may be enclosed inside <tt>[]</tt>,
+but this form is not required here. </p>
+
+<p> When inet_interfaces specifies just one IPv4 and/or IPv6 address
+that is not a loopback address, the Postfix SMTP client will use
+this address as the IP source address for outbound mail. Support
+for IPv6 is available in Postfix version 2.2 and later. </p>
+
+<p>
+On a multi-homed firewall with separate Postfix instances listening on the
+"inside" and "outside" interfaces, this can prevent each instance from
+being able to reach remote SMTP servers on the "other side" of the
+firewall. Setting
+smtp_bind_address to 0.0.0.0 avoids the potential problem for
+IPv4, and setting smtp_bind_address6 to :: solves the problem
+for IPv6. </p>
+
+<p>
+A better solution for multi-homed firewalls is to leave inet_interfaces
+at the default value and instead use explicit IP addresses in
+the master.cf SMTP server definitions. This preserves the Postfix
+SMTP client's
+loop detection, by ensuring that each side of the firewall knows that the
+other IP address is still the same host. Setting $inet_interfaces to a
+single IPv4 and/or IPV6 address is primarily useful with virtual
+hosting of domains on
+secondary IP addresses, when each IP address serves a different domain
+(and has a different $myhostname setting). </p>
+
+<p>
+See also the proxy_interfaces parameter, for network addresses that
+are forwarded to Postfix by way of a proxy or address translator.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+inet_interfaces = all (DEFAULT)
+inet_interfaces = loopback-only (Postfix version 2.2 and later)
+inet_interfaces = 127.0.0.1
+inet_interfaces = 127.0.0.1, [::1] (Postfix version 2.2 and later)
+inet_interfaces = 192.168.1.2, 127.0.0.1
+</pre>
+
+%PARAM inet_protocols see 'postconf -d output'
+
+<p> The Internet protocols Postfix will attempt to use when making
+or accepting connections. Specify one or more of "ipv4"
+or "ipv6", separated by whitespace or commas. The form
+"all" is equivalent to "ipv4, ipv6" or "ipv4", depending
+on whether the operating system implements IPv6. </p>
+
+<p> With Postfix 2.8 and earlier the default is "ipv4". For backwards
+compatibility with these releases, the Postfix 2.9 and later upgrade
+procedure appends an explicit "inet_protocols = ipv4" setting to
+main.cf when no explicit setting is present. This compatibility
+workaround will be phased out as IPv6 deployment becomes more common.
+</p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+<p> Note: you MUST stop and start Postfix after changing this
+parameter. </p>
+
+<p> On systems that pre-date IPV6_V6ONLY support (RFC 3493), an
+IPv6 server will also accept IPv4 connections, even when IPv4 is
+turned off with the inet_protocols parameter. On systems with
+IPV6_V6ONLY support, Postfix will use separate server sockets for
+IPv6 and IPv4, and each will accept only connections for the
+corresponding protocol. </p>
+
+<p> When IPv4 support is enabled via the inet_protocols parameter,
+Postfix will look up DNS type A records, and will convert
+IPv4-in-IPv6 client IP addresses (::ffff:1.2.3.4) to their original
+IPv4 form (1.2.3.4). The latter is needed on hosts that pre-date
+IPV6_V6ONLY support (RFC 3493). </p>
+
+<p> When IPv6 support is enabled via the inet_protocols parameter,
+Postfix will do DNS type AAAA record lookups. </p>
+
+<p> When both IPv4 and IPv6 support are enabled, the Postfix SMTP
+client will choose the protocol as specified with the
+smtp_address_preference parameter. Postfix versions before 2.8
+attempt to connect via IPv6 before attempting to use IPv4. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+inet_protocols = ipv4
+inet_protocols = all (DEFAULT)
+inet_protocols = ipv6
+inet_protocols = ipv4, ipv6
+</pre>
+
+%PARAM initial_destination_concurrency 5
+
+<p>
+The initial per-destination concurrency level for parallel delivery
+to the same destination.
+With per-destination recipient limit &gt; 1, a destination is a domain,
+otherwise it is a recipient.
+</p>
+
+<p> Use <i>transport</i>_initial_destination_concurrency to specify
+a transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport (Postfix 2.5 and later). </p>
+
+<p>
+Warning: with concurrency of 1, one bad message can be enough to
+block all mail to a site.
+</p>
+
+%PARAM invalid_hostname_reject_code 501
+
+<p>
+The numerical Postfix SMTP server response code when the client
+HELO or EHLO command parameter is rejected by the reject_invalid_helo_hostname
+restriction.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM ipc_idle version dependent
+
+<p>
+The time after which a client closes an idle internal communication
+channel. The purpose is to allow Postfix daemon processes to
+terminate voluntarily after they become idle. This is used, for
+example, by the Postfix address resolving and rewriting clients.
+</p>
+
+<p> With Postfix 2.4 the default value was reduced from 100s to 5s. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM ipc_timeout 3600s
+
+<p>
+The time limit for sending or receiving information over an internal
+communication channel. The purpose is to break out of deadlock
+situations. If the time limit is exceeded the software aborts with a
+fatal error.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM ipc_ttl 1000s
+
+<p>
+The time after which a client closes an active internal communication
+channel. The purpose is to allow Postfix daemon processes to
+terminate voluntarily
+after reaching their client limit. This is used, for example, by
+the Postfix address resolving and rewriting clients.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM line_length_limit 2048
+
+<p> Upon input, long lines are chopped up into pieces of at most
+this length; upon delivery, long lines are reconstructed. </p>
+
+%PARAM lmtp_connect_timeout 0s
+
+<p> The Postfix LMTP client time limit for completing a TCP connection, or
+zero (use the operating system built-in time limit). When no
+connection can be made within the deadline, the LMTP client tries
+the next address on the mail exchanger list. </p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+lmtp_connect_timeout = 30s
+</pre>
+
+%PARAM lmtp_data_done_timeout 600s
+
+<p> The Postfix LMTP client time limit for sending the LMTP ".",
+and for receiving the remote LMTP server response. When no response
+is received within the deadline, a warning is logged that the mail
+may be delivered multiple times. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM lmtp_data_init_timeout 120s
+
+<p>
+The Postfix LMTP client time limit for sending the LMTP DATA command,
+and
+for receiving the remote LMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM lmtp_data_xfer_timeout 180s
+
+<p>
+The Postfix LMTP client time limit for sending the LMTP message
+content.
+When the connection stalls for more than $lmtp_data_xfer_timeout
+the LMTP client terminates the transfer.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM lmtp_lhlo_timeout 300s
+
+<p> The Postfix LMTP client time limit for receiving the LMTP
+greeting banner. When the remote LMTP server drops the connection
+without sending a
+greeting banner, or when it sends no greeting banner within the
+deadline, the LMTP client tries the next address on the mail
+exchanger list. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM lmtp_mail_timeout 300s
+
+<p>
+The Postfix LMTP client time limit for sending the MAIL FROM command,
+and for receiving the remote LMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM lmtp_quit_timeout 300s
+
+<p>
+The Postfix LMTP client time limit for sending the QUIT command,
+and for receiving the remote LMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM lmtp_rcpt_timeout 300s
+
+<p>
+The Postfix LMTP client time limit for sending the RCPT TO command,
+and for receiving the remote LMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM lmtp_rset_timeout 20s
+
+<p> The Postfix LMTP client time limit for sending the RSET command,
+and for receiving the remote LMTP server response. The LMTP client
+sends RSET in
+order to finish a recipient address probe, or to verify that a
+cached connection is still alive. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM lmtp_send_xforward_command no
+
+<p>
+Send an XFORWARD command to the remote LMTP server when the LMTP LHLO
+server response announces XFORWARD support. This allows an lmtp(8)
+delivery agent, used for content filter message injection, to
+forward the name, address, protocol and HELO name of the original
+client to the content filter and downstream LMTP server.
+Before you change the value to yes, it is best to make sure that
+your content filter supports this command.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM lmtp_skip_quit_response no
+
+<p>
+Wait for the response to the LMTP QUIT command.
+</p>
+
+%PARAM lmtp_xforward_timeout 300s
+
+<p>
+The Postfix LMTP client time limit for sending the XFORWARD command,
+and for receiving the remote LMTP server response.
+</p>
+
+<p>
+In case of problems the client does NOT try the next address on
+the mail exchanger list.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM local_command_shell
+
+<p>
+Optional shell program for local(8) delivery to non-Postfix commands.
+By default, non-Postfix commands are executed directly; commands
+are given to the default shell (typically, /bin/sh) only when they
+contain shell meta characters or shell built-in commands.
+</p>
+
+<p> "sendmail's restricted shell" (smrsh) is what most people will
+use in order to restrict what programs can be run from e.g. .forward
+files (smrsh is part of the Sendmail distribution). </p>
+
+<p> Note: when a shell program is specified, it is invoked even
+when the command contains no shell built-in commands or meta
+characters. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+local_command_shell = /some/where/smrsh -c
+local_command_shell = /bin/bash -c
+</pre>
+
+%PARAM local_destination_concurrency_limit 2
+
+<p> The maximal number of parallel deliveries via the local mail
+delivery transport to the same recipient (when
+"local_destination_recipient_limit = 1") or the maximal number of
+parallel deliveries to the same local domain (when
+"local_destination_recipient_limit &gt; 1"). This limit is enforced by
+the queue manager. The message delivery transport name is the first
+field in the entry in the master.cf file. </p>
+
+<p> A low limit of 2 is recommended, just in case someone has an
+expensive shell command in a .forward file or in an alias (e.g.,
+a mailing list manager). You don't want to run lots of those at
+the same time. </p>
+
+%PARAM local_destination_recipient_limit 1
+
+<p> The maximal number of recipients per message delivery via the
+local mail delivery transport. This limit is enforced by the queue
+manager. The message delivery transport name is the first field in
+the entry in the master.cf file. </p>
+
+<p> Setting this parameter to a value &gt; 1 changes the meaning of
+local_destination_concurrency_limit from concurrency per recipient
+into concurrency per domain. </p>
+
+%PARAM local_recipient_maps proxy:unix:passwd.byname $alias_maps
+
+<p> Lookup tables with all names or addresses of local recipients:
+a recipient address is local when its domain matches $mydestination,
+$inet_interfaces or $proxy_interfaces. Specify @domain as a
+wild-card for domains that do not have a valid recipient list.
+Technically, tables listed with $local_recipient_maps are used as
+lists: Postfix needs to know only if a lookup string is found or
+not, but it does not use the result from table lookup. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p>
+If this parameter is non-empty (the default), then the Postfix SMTP
+server will reject mail for unknown local users.
+</p>
+
+<p>
+To turn off local recipient checking in the Postfix SMTP server,
+specify "local_recipient_maps =" (i.e. empty).
+</p>
+
+<p>
+The default setting assumes that you use the default Postfix local
+delivery agent for local delivery. You need to update the
+local_recipient_maps setting if:
+</p>
+
+<ul>
+
+<li>You redefine the local delivery agent in master.cf.
+
+<li>You redefine the "local_transport" setting in main.cf.
+
+<li>You use the "luser_relay", "mailbox_transport", or "fallback_transport"
+feature of the Postfix local(8) delivery agent.
+
+</ul>
+
+<p>
+Details are described in the LOCAL_RECIPIENT_README file.
+</p>
+
+<p>
+Beware: if the Postfix SMTP server runs chrooted, you need to access
+the passwd file via the proxymap(8) service, in order to overcome
+chroot access restrictions. The alternative, maintaining a copy of
+the system password file in the chroot jail is not practical.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+local_recipient_maps =
+</pre>
+
+%PARAM local_transport local:$myhostname
+
+<p> The default mail delivery transport and next-hop destination
+for final delivery to domains listed with mydestination, and for
+[ipaddress] destinations that match $inet_interfaces or $proxy_interfaces.
+This information can be overruled with the transport(5) table. </p>
+
+<p>
+By default, local mail is delivered to the transport called "local",
+which is just the name of a service that is defined the master.cf file.
+</p>
+
+<p>
+Specify a string of the form <i>transport:nexthop</i>, where <i>transport</i>
+is the name of a mail delivery transport defined in master.cf.
+The <i>:nexthop</i> destination is optional; its syntax is documented
+in the manual page of the corresponding delivery agent.
+</p>
+
+<p>
+Beware: if you override the default local delivery agent then you
+need to review the LOCAL_RECIPIENT_README document, otherwise the
+SMTP server may reject mail for local recipients.
+</p>
+
+%PARAM luser_relay
+
+<p>
+Optional catch-all destination for unknown local(8) recipients.
+By default, mail for unknown recipients in domains that match
+$mydestination, $inet_interfaces or $proxy_interfaces is returned
+as undeliverable.
+</p>
+
+<p>
+The luser_relay value is not subject to Postfix configuration
+parameter $name expansion. Instead, the following $name expansions
+are done:
+</p>
+
+<dl>
+
+<dt><b>$domain</b></dt>
+
+<dd>The recipient domain. </dd>
+
+<dt><b>$extension</b></dt>
+
+<dd>The recipient address extension. </dd>
+
+<dt><b>$home</b></dt>
+
+<dd>The recipient's home directory. </dd>
+
+<dt><b>$local</b></dt>
+
+<dd>The entire recipient address localpart. </dd>
+
+<dt><b>$recipient</b></dt>
+
+<dd>The full recipient address. </dd>
+
+<dt><b>$recipient_delimiter</b></dt>
+
+<dd>The address extension delimiter that was found in the recipient
+address (Postfix 2.11 and later), or the system-wide recipient
+address extension delimiter (Postfix 2.10 and earlier). </dd>
+
+<dt><b>$shell</b></dt>
+
+<dd>The recipient's login shell. </dd>
+
+<dt><b>$user</b></dt>
+
+<dd>The recipient username. </dd>
+
+<dt><b>${name?value}</b></dt>
+
+<dt><b>${name?{value}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is non-empty. </dd>
+
+<dt><b>${name:value}</b></dt>
+
+<dt><b>${name:{value}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value</i> when <i>$name</i> is empty. </dd>
+
+<dt><b>${name?{value1}:{value2}}</b> (Postfix &ge; 3.0)</dt>
+
+<dd>Expands to <i>value1</i> when <i>$name</i> is non-empty,
+<i>value2</i> otherwise. </dd>
+
+</dl>
+
+<p>
+Instead of $name you can also specify ${name} or $(name).
+</p>
+
+<p>
+Note: luser_relay works only for the Postfix local(8) delivery agent.
+</p>
+
+<p>
+Note: if you use this feature for accounts not in the UNIX password
+file, then you must specify "local_recipient_maps =" (i.e. empty)
+in the main.cf file, otherwise the Postfix SMTP server will reject mail
+for non-UNIX accounts with "User unknown in local recipient table".
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+luser_relay = $user@other.host
+luser_relay = $local@other.host
+luser_relay = admin+$local
+</pre>
+
+%PARAM mail_name Postfix
+
+<p>
+The mail system name that is displayed in Received: headers, in
+the SMTP greeting banner, and in bounced mail.
+</p>
+
+%PARAM mail_owner postfix
+
+<p>
+The UNIX system account that owns the Postfix queue and most Postfix
+daemon processes. Specify the name of an unprivileged user account
+that does not share a user or group ID with other accounts, and that
+owns no other files
+or processes on the system. In particular, don't specify nobody
+or daemon. PLEASE USE A DEDICATED USER ID AND GROUP ID.
+</p>
+
+<p>
+When this parameter value is changed you need to re-run "<b>postfix
+set-permissions</b>" (with Postfix version 2.0 and earlier:
+"<b>/etc/postfix/post-install set-permissions</b>".
+</p>
+
+%PARAM mail_spool_directory see "postconf -d" output
+
+<p>
+The directory where local(8) UNIX-style mailboxes are kept. The
+default setting depends on the system type. Specify a name ending
+in / for maildir-style delivery.
+</p>
+
+<p>
+Note: maildir delivery is done with the privileges of the recipient.
+If you use the mail_spool_directory setting for maildir style
+delivery, then you must create the top-level maildir directory in
+advance. Postfix will not create it.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+mail_spool_directory = /var/mail
+mail_spool_directory = /var/spool/mail
+</pre>
+
+%PARAM mail_version see "postconf -d" output
+
+<p>
+The version of the mail system. Stable releases are named
+<i>major</i>.<i>minor</i>.<i>patchlevel</i>. Experimental releases
+also include the release date. The version string can be used in,
+for example, the SMTP greeting banner.
+</p>
+
+%PARAM mailbox_command
+
+<p>
+Optional external command that the local(8) delivery agent should
+use for mailbox delivery. The command is run with the user ID and
+the primary group ID privileges of the recipient. Exception:
+command delivery for root executes with $default_privs privileges.
+This is not a problem, because 1) mail for root should always be
+aliased to a real user and 2) don't log in as root, use "su" instead.
+</p>
+
+<p>
+The following environment variables are exported to the command:
+</p>
+
+<dl>
+
+<dt><b>CLIENT_ADDRESS</b></dt>
+
+<dd>Remote client network address. Available in Postfix version 2.2 and
+later. </dd>
+
+<dt><b>CLIENT_HELO</b></dt>
+
+<dd>Remote client EHLO command parameter. Available in Postfix version 2.2
+and later.</dd>
+
+<dt><b>CLIENT_HOSTNAME</b></dt>
+
+<dd>Remote client hostname. Available in Postfix version 2.2 and later.
+</dd>
+
+<dt><b>CLIENT_PROTOCOL</b></dt>
+
+<dd>Remote client protocol. Available in Postfix version 2.2 and later.
+</dd>
+
+<dt><b>DOMAIN</b></dt>
+
+<dd>The domain part of the recipient address. </dd>
+
+<dt><b>EXTENSION</b></dt>
+
+<dd>The optional address extension. </dd>
+
+<dt><b>HOME</b></dt>
+
+<dd>The recipient home directory. </dd>
+
+<dt><b>LOCAL</b></dt>
+
+<dd>The recipient address localpart. </dd>
+
+<dt><b>LOGNAME</b></dt>
+
+<dd>The recipient's username. </dd>
+
+<dt><b>ORIGINAL_RECIPIENT</b></dt>
+
+<dd>The entire recipient address, before any address rewriting or
+aliasing. </dd>
+
+<dt><b>RECIPIENT</b></dt>
+
+<dd>The full recipient address. </dd>
+
+<dt><b>SASL_METHOD</b></dt>
+
+<dd>SASL authentication method specified in the remote client AUTH
+command. Available in Postfix version 2.2 and later. </dd>
+
+<dt><b>SASL_SENDER</b></dt>
+
+<dd>SASL sender address specified in the remote client MAIL FROM
+command. Available in Postfix version 2.2 and later. </dd>
+
+<dt><b>SASL_USER</b></dt>
+
+<dd>SASL username specified in the remote client AUTH command.
+Available in Postfix version 2.2 and later. </dd>
+
+<dt><b>SENDER</b></dt>
+
+<dd>The full sender address. </dd>
+
+<dt><b>SHELL</b></dt>
+
+<dd>The recipient's login shell. </dd>
+
+<dt><b>USER</b></dt>
+
+<dd>The recipient username. </dd>
+
+</dl>
+
+<p>
+Unlike other Postfix configuration parameters, the mailbox_command
+parameter is not subjected to $name substitutions. This is to make
+it easier to specify shell syntax (see example below).
+</p>
+
+<p>
+If you can, avoid shell meta characters because they will force
+Postfix to run an expensive shell process. If you're delivering
+via "procmail" then running a shell won't make a noticeable difference
+in the total cost.
+</p>
+
+<p>
+Note: if you use the mailbox_command feature to deliver mail
+system-wide, you must set up an alias that forwards mail for root
+to a real user.
+</p>
+
+<p> The precedence of local(8) delivery features from high to low
+is: aliases, .forward files, mailbox_transport_maps, mailbox_transport,
+mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory,
+fallback_transport_maps, fallback_transport and luser_relay. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+mailbox_command = /some/where/procmail
+mailbox_command = /some/where/procmail -a "$EXTENSION"
+mailbox_command = /some/where/maildrop -d "$USER"
+ -f "$SENDER" "$EXTENSION"
+</pre>
+
+%PARAM mailbox_size_limit 51200000
+
+<p> The maximal size of any local(8) individual mailbox or maildir
+file, or zero (no limit). In fact, this limits the size of any
+file that is written to upon local delivery, including files written
+by external commands that are executed by the local(8) delivery
+agent. The value cannot exceed LONG_MAX (typically, a 32-bit or
+64-bit signed integer).
+</p>
+
+<p>
+This limit must not be smaller than the message size limit.
+</p>
+
+%PARAM maps_rbl_reject_code 554
+
+<p>
+The numerical Postfix SMTP server response code when a remote SMTP
+client request is blocked by the reject_rbl_client, reject_rhsbl_client,
+reject_rhsbl_reverse_client, reject_rhsbl_sender or
+reject_rhsbl_recipient restriction.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM masquerade_classes envelope_sender, header_sender, header_recipient
+
+<p>
+What addresses are subject to address masquerading.
+</p>
+
+<p>
+By default, address masquerading is limited to envelope sender
+addresses, and to header sender and header recipient addresses.
+This allows you to use address masquerading on a mail gateway while
+still being able to forward mail to users on individual machines.
+</p>
+
+<p>
+Specify zero or more of: envelope_sender, envelope_recipient,
+header_sender, header_recipient
+</p>
+
+%PARAM masquerade_domains
+
+<p>
+Optional list of domains whose subdomain structure will be stripped
+off in email addresses.
+</p>
+
+<p>
+The list is processed left to right, and processing stops at the
+first match. Thus,
+</p>
+
+<blockquote>
+<pre>
+masquerade_domains = foo.example.com example.com
+</pre>
+</blockquote>
+
+<p>
+strips "user@any.thing.foo.example.com" to "user@foo.example.com",
+but strips "user@any.thing.else.example.com" to "user@example.com".
+</p>
+
+<p>
+A domain name prefixed with ! means do not masquerade this domain
+or its subdomains. Thus,
+</p>
+
+<blockquote>
+<pre>
+masquerade_domains = !foo.example.com example.com
+</pre>
+</blockquote>
+
+<p>
+does not change "user@any.thing.foo.example.com" or "user@foo.example.com",
+but strips "user@any.thing.else.example.com" to "user@example.com".
+</p>
+
+<p> Note: with Postfix version 2.2, message header address masquerading
+happens only when message header address rewriting is enabled: </p>
+
+<ul>
+
+<li> The message is received with the Postfix sendmail(1) command,
+
+<li> The message is received from a network client that matches
+$local_header_rewrite_clients,
+
+<li> The message is received from the network, and the
+remote_header_rewrite_domain parameter specifies a non-empty value.
+
+</ul>
+
+<p> To get the behavior before Postfix version 2.2, specify
+"local_header_rewrite_clients = static:all". </p>
+
+
+<p>
+Example:
+</p>
+
+<pre>
+masquerade_domains = $mydomain
+</pre>
+
+%PARAM masquerade_exceptions
+
+<p>
+Optional list of user names that are not subjected to address
+masquerading, even when their addresses match $masquerade_domains.
+</p>
+
+<p>
+By default, address masquerading makes no exceptions.
+</p>
+
+<p>
+Specify a list of user names, "/file/name" or "type:table" patterns,
+separated by commas and/or whitespace. The list is matched left to
+right, and the search stops on the first match. A "/file/name"
+pattern is replaced
+by its contents; a "type:table" lookup table is matched when a name
+matches a lookup key (the lookup result is ignored). Continue long
+lines by starting the next line with whitespace. Specify "!pattern"
+to exclude a name from the list. The form "!/file/name" is supported
+only in Postfix version 2.4 and later. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+masquerade_exceptions = root, mailer-daemon
+masquerade_exceptions = root
+</pre>
+
+%PARAM max_idle 100s
+
+<p>
+The maximum amount of time that an idle Postfix daemon process waits
+for an incoming connection before terminating voluntarily. This
+parameter
+is ignored by the Postfix queue manager and by other long-lived
+Postfix daemon processes.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM max_use 100
+
+<p>
+The maximal number of incoming connections that a Postfix daemon
+process will service before terminating voluntarily. This parameter
+is ignored by the Postfix queue
+manager and by other long-lived Postfix daemon processes.
+</p>
+
+%PARAM maximal_backoff_time 4000s
+
+<p>
+The maximal time between attempts to deliver a deferred message.
+</p>
+
+<p> This parameter should be set to a value greater than or equal
+to $minimal_backoff_time. See also $queue_run_delay. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM maximal_queue_lifetime 5d
+
+<p>
+Consider a message as undeliverable, when delivery fails with a
+temporary error, and the time in the queue has reached the
+maximal_queue_lifetime limit.
+</p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p>
+Specify 0 when mail delivery should be tried only once.
+</p>
+
+%PARAM lmdb_map_size 16777216
+
+<p>
+The initial OpenLDAP LMDB database size limit in bytes. Each time
+a database becomes full, its size limit is doubled.
+</p>
+
+<p>
+This feature is available in Postfix 2.11 and later.
+</p>
+
+%PARAM message_size_limit 10240000
+
+<p>
+The maximal size in bytes of a message, including envelope information.
+The value cannot exceed LONG_MAX (typically, a 32-bit or 64-bit
+signed integer).
+</p>
+
+<p> Note: be careful when making changes. Excessively small values
+will result in the loss of non-delivery notifications, when a bounce
+message size exceeds the local or remote MTA's message size limit.
+</p>
+
+%PARAM minimal_backoff_time 300s
+
+<p>
+The minimal time between attempts to deliver a deferred message;
+prior to Postfix 2.4 the default value was 1000s.
+</p>
+
+<p>
+This parameter also limits the time an unreachable destination is
+kept in the short-term, in-memory, destination status cache.
+</p>
+
+<p> This parameter should be set greater than or equal to
+$queue_run_delay. See also $maximal_backoff_time. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM multi_recipient_bounce_reject_code 550
+
+<p>
+The numerical Postfix SMTP server response code when a remote SMTP
+client request is blocked by the reject_multi_recipient_bounce
+restriction.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM mydestination $myhostname, localhost.$mydomain, localhost
+
+<p> The list of domains that are delivered via the $local_transport
+mail delivery transport. By default this is the Postfix local(8)
+delivery agent which looks up all recipients in /etc/passwd and
+/etc/aliases. The SMTP server validates recipient addresses with
+$local_recipient_maps and rejects non-existent recipients. See also
+the local domain class in the ADDRESS_CLASS_README file.
+</p>
+
+<p>
+The default mydestination value specifies names for the local
+machine only. On a mail domain gateway, you should also include
+$mydomain.
+</p>
+
+<p>
+The $local_transport delivery method is also selected for mail
+addressed to user@[the.net.work.address] of the mail system (the
+IP addresses specified with the inet_interfaces and proxy_interfaces
+parameters).
+</p>
+
+<p>
+Warnings:
+</p>
+
+<ul>
+
+<li><p>Do not specify the names of virtual domains - those domains
+are specified elsewhere. See VIRTUAL_README for more information. </p>
+
+<li><p>Do not specify the names of domains that this machine is
+backup MX host for. See STANDARD_CONFIGURATION_README for how to
+set up backup MX hosts. </p>
+
+<li><p>By default, the Postfix SMTP server rejects mail for recipients
+not listed with the local_recipient_maps parameter. See the
+postconf(5) manual for a description of the local_recipient_maps
+and unknown_local_recipient_reject_code parameters. </p>
+
+</ul>
+
+<p>
+Specify a list of host or domain names, "/file/name" or "type:table"
+patterns, separated by commas and/or whitespace. A "/file/name"
+pattern is replaced by its contents; a "type:table" lookup table
+is matched when a name matches a lookup key (the lookup result is
+ignored). Continue long lines by starting the next line with
+whitespace. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+mydestination = $myhostname, localhost.$mydomain $mydomain
+mydestination = $myhostname, localhost.$mydomain www.$mydomain, ftp.$mydomain
+</pre>
+
+%PARAM mydomain see "postconf -d" output
+
+<p>
+The internet domain name of this mail system. The default is to
+use $myhostname minus the first component, or "localdomain" (Postfix
+2.3 and later). $mydomain is used as
+a default value for many other configuration parameters.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+mydomain = domain.tld
+</pre>
+
+%PARAM myhostname see "postconf -d" output
+
+<p>
+The internet hostname of this mail system. The default is to use
+the fully-qualified domain name (FQDN) from gethostname(), or to
+use the non-FQDN result from gethostname() and append ".$mydomain".
+$myhostname is used as a default value for many other configuration
+parameters. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+myhostname = host.example.com
+</pre>
+
+%PARAM mynetworks see "postconf -d" output
+
+<p>
+The list of "trusted" remote SMTP clients that have more privileges than
+"strangers".
+</p>
+
+<p>
+In particular, "trusted" SMTP clients are allowed to relay mail
+through Postfix. See the smtpd_relay_restrictions parameter
+description in the postconf(5) manual.
+</p>
+
+<p>
+You can specify the list of "trusted" network addresses by hand
+or you can let Postfix do it for you (which is the default).
+See the description of the mynetworks_style parameter for more
+information.
+</p>
+
+<p>
+If you specify the mynetworks list by hand,
+Postfix ignores the mynetworks_style setting.
+</p>
+
+<p> Specify a list of network addresses or network/netmask patterns,
+separated by commas and/or whitespace. Continue long lines by
+starting the next line with whitespace. </p>
+
+<p> The netmask specifies the number of bits in the network part
+of a host address. You can also specify "/file/name" or "type:table"
+patterns. A "/file/name" pattern is replaced by its contents; a
+"type:table" lookup table is matched when a table entry matches a
+lookup string (the lookup result is ignored). </p>
+
+<p> The list is matched left to right, and the search stops on the
+first match. Specify "!pattern" to exclude an address or network
+block from the list. The form "!/file/name" is supported only
+in Postfix version 2.4 and later. </p>
+
+<p> Note 1: Pattern matching of domain names is controlled by the
+presence or absence of "mynetworks" in the parent_domain_matches_subdomains
+parameter value. </p>
+
+<p> Note 2: IP version 6 address information must be specified inside
+<tt>[]</tt> in the mynetworks value, and in files specified with
+"/file/name". IP version 6 addresses contain the ":" character,
+and would otherwise be confused with a "type:table" pattern. </p>
+
+<p> Note 3: CIDR ranges cannot be specified in hash tables. Use cidr
+tables if CIDR ranges are used. </p>
+
+<p> Examples: </p>
+
+<pre>
+mynetworks = 127.0.0.0/8 168.100.189.0/28
+mynetworks = !192.168.0.1, 192.168.0.0/28
+mynetworks = 127.0.0.0/8 168.100.189.0/28 [::1]/128 [2001:240:587::]/64
+mynetworks = $config_directory/mynetworks
+mynetworks = hash:/etc/postfix/network_table
+mynetworks = cidr:/etc/postfix/network_table.cidr
+</pre>
+
+%PARAM myorigin $myhostname
+
+<p>
+The domain name that locally-posted mail appears to come
+from, and that locally posted mail is delivered to. The default,
+$myhostname, is adequate for small sites. If you run a domain with
+multiple machines, you should (1) change this to $mydomain and (2)
+set up a domain-wide alias database that aliases each user to
+user@that.users.mailhost.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+myorigin = $mydomain
+</pre>
+
+%PARAM notify_classes resource, software
+
+<p>
+The list of error classes that are reported to the postmaster. These
+postmaster notifications do not replace user notifications. The
+default is to report only the most serious problems. The paranoid
+may wish to turn on the policy (UCE and mail relaying) and protocol
+error (broken mail software) reports.
+</p>
+
+<p> NOTE: postmaster notifications may contain confidential information
+such as SASL passwords or message content. It is the system
+administrator's responsibility to treat such information with care.
+</p>
+
+<p>
+The error classes are:
+</p>
+
+<dl>
+
+<dt><b>bounce</b> (also implies <b>2bounce</b>)</dt>
+
+<dd>Send the postmaster copies of the headers of bounced mail, and
+send transcripts of SMTP sessions when Postfix rejects mail. The
+notification is sent to the address specified with the
+bounce_notice_recipient configuration parameter (default: postmaster).
+</dd>
+
+<dt><b>2bounce</b></dt>
+
+<dd>Send undeliverable bounced mail to the postmaster. The notification
+is sent to the address specified with the 2bounce_notice_recipient
+configuration parameter (default: postmaster). </dd>
+
+<dt><b>data</b></dt>
+
+<dd>Send the postmaster a transcript of the SMTP session with an
+error because a critical data file was unavailable. The notification
+is sent to the address specified with the error_notice_recipient
+configuration parameter (default: postmaster). <br> This feature
+is available in Postfix 2.9 and later. </dd>
+
+<dt><b>delay</b></dt>
+
+<dd>Send the postmaster copies of the headers of delayed mail (see
+delay_warning_time). The
+notification is sent to the address specified with the
+delay_notice_recipient configuration parameter (default: postmaster).
+</dd>
+
+<dt><b>policy</b></dt>
+
+<dd>Send the postmaster a transcript of the SMTP session when a
+client request was rejected because of (UCE) policy. The notification
+is sent to the address specified with the error_notice_recipient
+configuration parameter (default: postmaster). </dd>
+
+<dt><b>protocol</b></dt>
+
+<dd>Send the postmaster a transcript of the SMTP session in case
+of client or server protocol errors. The notification is sent to
+the address specified with the error_notice_recipient configuration
+parameter (default: postmaster). </dd>
+
+<dt><b>resource</b></dt>
+
+<dd>Inform the postmaster of mail not delivered due to resource
+problems. The notification is sent to the address specified with
+the error_notice_recipient configuration parameter (default:
+postmaster). </dd>
+
+<dt><b>software</b></dt>
+
+<dd>Inform the postmaster of mail not delivered due to software
+problems. The notification is sent to the address specified with
+the error_notice_recipient configuration parameter (default:
+postmaster). </dd>
+
+</dl>
+
+<p>
+Examples:
+</p>
+
+<pre>
+notify_classes = bounce, delay, policy, protocol, resource, software
+notify_classes = 2bounce, resource, software
+</pre>
+
+%PARAM parent_domain_matches_subdomains see "postconf -d" output
+
+<p>
+A list of Postfix features where the pattern "example.com" also
+matches subdomains of example.com,
+instead of requiring an explicit ".example.com" pattern. This is
+planned backwards compatibility: eventually, all Postfix features
+are expected to require explicit ".example.com" style patterns when
+you really want to match subdomains.
+</p>
+
+<p> The following Postfix feature names are supported. </p>
+
+<dl>
+
+<dt> Postfix version 1.0 and later</dt>
+
+<dd>
+debug_peer_list,
+fast_flush_domains,
+mynetworks,
+permit_mx_backup_networks,
+relay_domains,
+transport_maps
+</dd>
+
+<dt> Postfix version 1.1 and later</dt>
+
+<dd>
+qmqpd_authorized_clients,
+<a href="SMTPD_ACCESS_README.html">smtpd_access_maps</a>,
+</dd>
+
+<dt> Postfix version 2.8 and later </dt>
+
+<dd>
+postscreen_access_list
+</dd>
+
+<dt> Postfix version 3.0 and later </dt>
+
+<dd>
+smtpd_client_event_limit_exceptions
+</dd>
+
+</dl>
+
+%PARAM propagate_unmatched_extensions canonical, virtual
+
+<p>
+What address lookup tables copy an address extension from the lookup
+key to the lookup result.
+</p>
+
+<p>
+For example, with a virtual(5) mapping of "<i>joe@example.com =&gt;
+joe.user@example.net</i>", the address "<i>joe+foo@example.com</i>"
+would rewrite to "<i>joe.user+foo@example.net</i>".
+</p>
+
+<p>
+Specify zero or more of <b>canonical</b>, <b>virtual</b>, <b>alias</b>,
+<b>forward</b>, <b>include</b> or <b>generic</b>. These cause
+address extension
+propagation with canonical(5), virtual(5), and aliases(5) maps,
+with local(8) .forward and :include: file lookups, and with smtp(8)
+generic maps, respectively. </p>
+
+<p>
+Note: enabling this feature for types other than <b>canonical</b>
+and <b>virtual</b> is likely to cause problems when mail is forwarded
+to other sites, especially with mail that is sent to a mailing list
+exploder address.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+propagate_unmatched_extensions = canonical, virtual, alias,
+ forward, include
+propagate_unmatched_extensions = canonical, virtual
+</pre>
+
+%PARAM proxy_interfaces
+
+<p>
+The network interface addresses that this mail system receives mail
+on by way of a proxy or network address translation unit.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+<p> You must specify your "outside" proxy/NAT addresses when your
+system is a backup MX host for other domains, otherwise mail delivery
+loops will happen when the primary MX host is down. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+proxy_interfaces = 1.2.3.4
+</pre>
+
+%PARAM qmgr_message_active_limit 20000
+
+<p>
+The maximal number of messages in the active queue.
+</p>
+
+%PARAM qmgr_message_recipient_limit 20000
+
+<p> The maximal number of recipients held in memory by the Postfix
+queue manager, and the maximal size of the short-term,
+in-memory "dead" destination status cache. </p>
+
+%PARAM qmgr_message_recipient_minimum 10
+
+<p>
+The minimal number of in-memory recipients for any message. This
+takes priority over any other in-memory recipient limits (i.e.,
+the global qmgr_message_recipient_limit and the per transport
+_recipient_limit) if necessary. The minimum value allowed for this
+parameter is 1.
+</p>
+
+%PARAM qmqpd_authorized_clients
+
+<p>
+What remote QMQP clients are allowed to connect to the Postfix QMQP
+server port.
+</p>
+
+<p>
+By default, no client is allowed to use the service. This is
+because the QMQP server will relay mail to any destination.
+</p>
+
+<p>
+Specify a list of client patterns. A list pattern specifies a host
+name, a domain name, an internet address, or a network/mask pattern,
+where the mask specifies the number of bits in the network part.
+When a pattern specifies a file name, its contents are substituted
+for the file name; when a pattern is a "type:table" table specification,
+table lookup is used instead. </p>
+
+<p>
+Patterns are separated by whitespace and/or commas. In order to
+reverse the result, precede a pattern with an
+exclamation point (!). The form "!/file/name" is supported only
+in Postfix version 2.4 and later.
+</p>
+
+<p> Pattern matching of domain names is controlled by the presence
+or absence of "qmqpd_authorized_clients" in the
+parent_domain_matches_subdomains parameter value. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+qmqpd_authorized_clients = !192.168.0.1, 192.168.0.0/24
+</pre>
+
+%PARAM qmqpd_error_delay 1s
+
+<p>
+How long the Postfix QMQP server will pause before sending a negative
+reply to the remote QMQP client. The purpose is to slow down confused
+or malicious clients.
+</p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM qmqpd_timeout 300s
+
+<p>
+The time limit for sending or receiving information over the network.
+If a read or write operation blocks for more than $qmqpd_timeout
+seconds the Postfix QMQP server gives up and disconnects.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM queue_minfree 0
+
+<p>
+The minimal amount of free space in bytes in the queue file system
+that is needed to receive mail. This is currently used by the
+Postfix SMTP server to decide if it will accept any mail at all.
+</p>
+
+<p>
+By default, the Postfix SMTP server rejects MAIL FROM commands when
+the amount of free space is less than 1.5*$message_size_limit
+(Postfix version 2.1 and later).
+To specify a higher minimum free space limit, specify a queue_minfree
+value that is at least 1.5*$message_size_limit.
+</p>
+
+<p>
+With Postfix versions 2.0 and earlier, a queue_minfree value of
+zero means there is no minimum required amount of free space.
+</p>
+
+%PARAM queue_run_delay 300s
+
+<p>
+The time between deferred queue scans by the queue manager;
+prior to Postfix 2.4 the default value was 1000s.
+</p>
+
+<p> This parameter should be set less than or equal to
+$minimal_backoff_time. See also $maximal_backoff_time. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM rbl_reply_maps
+
+<p>
+Optional lookup tables with RBL response templates. The tables are
+indexed by the RBL domain name. By default, Postfix uses the default
+template as specified with the default_rbl_reply configuration
+parameter. See there for a discussion of the syntax of RBL reply
+templates.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM receive_override_options
+
+<p> Enable or disable recipient validation, built-in content
+filtering, or address mapping. Typically, these are specified in
+master.cf as command-line arguments for the smtpd(8), qmqpd(8) or
+pickup(8) daemons. </p>
+
+<p> Specify zero or more of the following options. The options
+override main.cf settings and are either implemented by smtpd(8),
+qmqpd(8), or pickup(8) themselves, or they are forwarded to the
+cleanup server. </p>
+
+<dl>
+
+<dt><b><a name="no_unknown_recipient_checks">no_unknown_recipient_checks</a></b></dt>
+
+<dd>Do not try to reject unknown recipients (SMTP server only).
+This is typically specified AFTER an external content filter.
+</dd>
+
+<dt><b><a name="no_address_mappings">no_address_mappings</a></b></dt>
+
+<dd>Disable canonical address mapping, virtual alias map expansion,
+address masquerading, and automatic BCC (blind carbon-copy)
+recipients. This is typically specified BEFORE an external content
+filter. </dd>
+
+<dt><b><a name="no_header_body_checks">no_header_body_checks</a></b></dt>
+
+<dd>Disable header/body_checks. This is typically specified AFTER
+an external content filter. </dd>
+
+<dt><b><a name="no_milters">no_milters</a></b></dt>
+
+<dd>Disable Milter (mail filter) applications. This is typically
+specified AFTER an external content filter. </dd>
+
+</dl>
+
+<p>
+Note: when the "BEFORE content filter" receive_override_options
+setting is specified in the main.cf file, specify the "AFTER content
+filter" receive_override_options setting in master.cf (and vice
+versa).
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+receive_override_options =
+ no_unknown_recipient_checks, no_header_body_checks
+receive_override_options = no_address_mappings
+</pre>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM recipient_bcc_maps
+
+<p>
+Optional BCC (blind carbon-copy) address lookup tables, indexed by
+recipient address. The BCC address (multiple results are not
+supported) is added when mail enters from outside of Postfix.
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p>
+The table search order is as follows:
+</p>
+
+<ul>
+
+<li> Look up the "user+extension@domain.tld" address including the
+optional address extension.
+
+<li> Look up the "user@domain.tld" address without the optional
+address extension.
+
+<li> Look up the "user+extension" address local part when the
+recipient domain equals $myorigin, $mydestination, $inet_interfaces
+or $proxy_interfaces.
+
+<li> Look up the "user" address local part when the recipient domain
+equals $myorigin, $mydestination, $inet_interfaces or $proxy_interfaces.
+
+<li> Look up the "@domain.tld" part.
+
+</ul>
+
+<p>
+Note: with Postfix 2.3 and later the BCC address is added as if it
+was specified with NOTIFY=NONE. The sender will not be notified
+when the BCC address is undeliverable, as long as all down-stream
+software implements RFC 3461.
+</p>
+
+<p>
+Note: with Postfix 2.2 and earlier the sender will unconditionally
+be notified when the BCC address is undeliverable.
+</p>
+
+<p> Note: automatic BCC recipients are produced only for new mail.
+To avoid mailer loops, automatic BCC recipients are not generated
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+recipient_bcc_maps = hash:/etc/postfix/recipient_bcc
+</pre>
+
+<p>
+After a change, run "<b>postmap /etc/postfix/recipient_bcc</b>".
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM recipient_canonical_maps
+
+<p>
+Optional address mapping lookup tables for envelope and header
+recipient addresses.
+The table format and lookups are documented in canonical(5).
+</p>
+
+<p>
+Note: $recipient_canonical_maps is processed before $canonical_maps.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+recipient_canonical_maps = hash:/etc/postfix/recipient_canonical
+</pre>
+
+%PARAM recipient_delimiter
+
+<p> The set of characters that can separate an email address
+localpart, user name, or a .forward file name from its extension.
+For example, with "recipient_delimiter = +", the software tries
+user+foo@example.com before trying user@example.com, user+foo before
+trying user, and .forward+foo before trying .forward. </p>
+
+<p> More formally, an email address localpart or user name is
+separated from its extension by the first character that matches
+the recipient_delimiter set. The delimiter character and extension
+may then be used to generate an extended .forward file name. This
+implementation recognizes one delimiter character and one extension
+per email address localpart or email address. With Postfix 2.10 and
+earlier, the recipient_delimiter specifies a single character. </p>
+
+<p> See canonical(5), local(8), relocated(5) and virtual(5) for the
+effects of recipient_delimiter on lookups in aliases, canonical,
+virtual, and relocated maps, and see the propagate_unmatched_extensions
+parameter for propagating an extension from one email address to
+another. </p>
+
+<p> When used in command_execution_directory, forward_path, or
+luser_relay, ${recipient_delimiter} is replaced with the actual
+recipient delimiter that was found in the recipient email address
+(Postfix 2.11 and later), or it is replaced with the main.cf
+recipient_delimiter parameter value (Postfix 2.10 and earlier).
+</p>
+
+<p> The recipient_delimiter is not applied to the mailer-daemon
+address, the postmaster address, or the double-bounce address. With
+the default "owner_request_special = yes" setting, the recipient_delimiter
+is also not applied to addresses with the special "owner-" prefix
+or the special "-request" suffix. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+# Handle Postfix-style extensions.
+recipient_delimiter = +
+</pre>
+
+<pre>
+# Handle both Postfix and qmail extensions (Postfix 2.11 and later).
+recipient_delimiter = +-
+</pre>
+
+<pre>
+# Use .forward for mail without address extension, and for mail with
+# an unrecognized address extension.
+forward_path = $home/.forward${recipient_delimiter}${extension},
+ $home/.forward
+</pre>
+
+%PARAM reject_code 554
+
+<p>
+The numerical Postfix SMTP server response code when a remote SMTP
+client request is rejected by the "reject" restriction.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM relay_domains Postfix &ge; 3.0: empty, Postfix &lt; 3.0: $mydestination
+
+<p> What destination domains (and subdomains thereof) this system
+will relay mail to. For details about how
+the relay_domains value is used, see the description of the
+permit_auth_destination and reject_unauth_destination SMTP recipient
+restrictions. </p>
+
+<p> Domains that match $relay_domains are delivered with the
+$relay_transport mail delivery transport. The SMTP server validates
+recipient addresses with $relay_recipient_maps and rejects non-existent
+recipients. See also the relay domains address class in the
+ADDRESS_CLASS_README file. </p>
+
+<p> Note: Postfix will not automatically forward mail for domains
+that list this system as their primary or backup MX host. See the
+permit_mx_backup restriction in the postconf(5) manual page. </p>
+
+<p> Specify a list of host or domain names, "/file/name" patterns
+or "type:table" lookup tables, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace. A
+"/file/name" pattern is replaced by its contents; a "type:table"
+lookup table is matched when a (parent) domain appears as lookup
+key. Specify "!pattern" to exclude a domain from the list. The form
+"!/file/name" is supported only in Postfix version 2.4 and later.
+</p>
+
+<p> Pattern matching of domain names is controlled by the presence
+or absence of "relay_domains" in the parent_domain_matches_subdomains
+parameter value. </p>
+
+%PARAM relay_domains_reject_code 554
+
+<p>
+The numerical Postfix SMTP server response code when a client
+request is rejected by the reject_unauth_destination recipient
+restriction.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM relay_recipient_maps
+
+<p> Optional lookup tables with all valid addresses in the domains
+that match $relay_domains. Specify @domain as a wild-card for
+domains that have no valid recipient list, and become a source of
+backscatter mail: Postfix accepts spam for non-existent recipients
+and then floods innocent people with undeliverable mail. Technically,
+tables
+listed with $relay_recipient_maps are used as lists: Postfix needs
+to know only if a lookup string is found or not, but it does not
+use the result from the table lookup. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p>
+If this parameter is non-empty, then the Postfix SMTP server will reject
+mail to unknown relay users. This feature is off by default.
+</p>
+
+<p>
+See also the relay domains address class in the ADDRESS_CLASS_README
+file.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+relay_recipient_maps = hash:/etc/postfix/relay_recipients
+</pre>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM relayhost
+
+<p>
+The next-hop destination(s) for non-local mail; overrides non-local
+domains in recipient addresses. This information is overruled with
+relay_transport, sender_dependent_default_transport_maps,
+default_transport, sender_dependent_relayhost_maps
+and with the transport(5) table.
+</p>
+
+<p>
+On an intranet, specify the organizational domain name. If your
+internal DNS uses no MX records, specify the name of the intranet
+gateway host instead.
+</p>
+
+<p>
+In the case of SMTP or LMTP delivery, specify one or more destinations
+in the form of a domain name, hostname, hostname:port, [hostname]:port,
+[hostaddress] or [hostaddress]:port, separated by comma or whitespace.
+The form [hostname] turns off MX lookups. Multiple destinations are
+supported in Postfix 3.5 and later.
+</p>
+
+<p>
+If you're connected via UUCP, see the UUCP_README file for useful
+information.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+relayhost = $mydomain
+relayhost = [gateway.example.com]
+relayhost = mail1.example:587, mail2.example:587
+relayhost = [an.ip.add.ress]
+</pre>
+
+%PARAM relocated_maps
+
+<p>
+Optional lookup tables with new contact information for users or
+domains that no longer exist. The table format and lookups are
+documented in relocated(5).
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p>
+If you use this feature, run "<b>postmap /etc/postfix/relocated</b>" to
+build the necessary DBM or DB file after change, then "<b>postfix
+reload</b>" to make the changes visible.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+relocated_maps = dbm:/etc/postfix/relocated
+relocated_maps = hash:/etc/postfix/relocated
+</pre>
+
+%PARAM require_home_directory no
+
+<p>
+Require that a local(8) recipient's home directory exists
+before mail delivery is attempted. By default this test is disabled.
+It can be useful for environments that import home directories to
+the mail server (IMPORTING HOME DIRECTORIES IS NOT RECOMMENDED).
+</p>
+
+%PARAM resolve_dequoted_address yes
+
+<p> Resolve a recipient address safely instead of correctly, by
+looking inside quotes. </p>
+
+<p> By default, the Postfix address resolver does not quote the
+address localpart as per RFC 822, so that additional @ or % or !
+operators remain visible. This behavior is safe but it is also
+technically incorrect. </p>
+
+<p> If you specify "resolve_dequoted_address = no", then
+the Postfix
+resolver will not know about additional @ etc. operators in the
+address localpart. This opens opportunities for obscure mail relay
+attacks with user@domain@domain addresses when Postfix provides
+backup MX service for Sendmail systems. </p>
+
+%PARAM resolve_null_domain no
+
+<p> Resolve an address that ends in the "@" null domain as if the
+local hostname were specified, instead of rejecting the address as
+invalid. </p>
+
+<p> This feature is available in Postfix 2.1 and later.
+Earlier versions always resolve the null domain as the local
+hostname. </p>
+
+<p> The Postfix SMTP server uses this feature to reject mail from
+or to addresses that end in the "@" null domain, and from addresses
+that rewrite into a form that ends in the "@" null domain. </p>
+
+%PARAM sender_bcc_maps
+
+<p> Optional BCC (blind carbon-copy) address lookup tables, indexed
+by sender address. The BCC address (multiple results are not
+supported) is added when mail enters from outside of Postfix. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p>
+The table search order is as follows:
+</p>
+
+<ul>
+
+<li> Look up the "user+extension@domain.tld" address including the
+optional address extension.
+
+<li> Look up the "user@domain.tld" address without the optional
+address extension.
+
+<li> Look up the "user+extension" address local part when the
+sender domain equals $myorigin, $mydestination, $inet_interfaces
+or $proxy_interfaces.
+
+<li> Look up the "user" address local part when the sender domain
+equals $myorigin, $mydestination, $inet_interfaces or $proxy_interfaces.
+
+<li> Look up the "@domain.tld" part.
+
+</ul>
+
+<p>
+Note: with Postfix 2.3 and later the BCC address is added as if it
+was specified with NOTIFY=NONE. The sender will not be notified
+when the BCC address is undeliverable, as long as all down-stream
+software implements RFC 3461.
+</p>
+
+<p>
+Note: with Postfix 2.2 and earlier the sender will be notified
+when the BCC address is undeliverable.
+</p>
+
+<p> Note: automatic BCC recipients are produced only for new mail.
+To avoid mailer loops, automatic BCC recipients are not generated
+after Postfix forwards mail internally, or after Postfix generates
+mail itself. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+sender_bcc_maps = hash:/etc/postfix/sender_bcc
+</pre>
+
+<p>
+After a change, run "<b>postmap /etc/postfix/sender_bcc</b>".
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM sender_canonical_maps
+
+<p>
+Optional address mapping lookup tables for envelope and header
+sender addresses.
+The table format and lookups are documented in canonical(5).
+</p>
+
+<p>
+Example: you want to rewrite the SENDER address "user@ugly.domain"
+to "user@pretty.domain", while still being able to send mail to
+the RECIPIENT address "user@ugly.domain".
+</p>
+
+<p>
+Note: $sender_canonical_maps is processed before $canonical_maps.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+sender_canonical_maps = hash:/etc/postfix/sender_canonical
+</pre>
+
+%PARAM smtp_always_send_ehlo yes
+
+<p>
+Always send EHLO at the start of an SMTP session.
+</p>
+
+<p>
+With "smtp_always_send_ehlo = no", the Postfix SMTP client sends
+EHLO only when
+the word "ESMTP" appears in the server greeting banner (example:
+220 spike.porcupine.org ESMTP Postfix).
+</p>
+
+%PARAM smtp_bind_address
+
+<p>
+An optional numerical network address that the Postfix SMTP client
+should bind to when making an IPv4 connection.
+</p>
+
+<p>
+This can be specified in the main.cf file for all SMTP clients, or
+it can be specified in the master.cf file for a specific client,
+for example:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtp ... smtp -o smtp_bind_address=11.22.33.44
+</pre>
+</blockquote>
+
+<p> See smtp_bind_address_enforce for how Postfix should handle
+errors (Postfix 3.7 and later). </p>
+
+<p> Note 1: when inet_interfaces specifies no more than one IPv4
+address, and that address is a non-loopback address, it is
+automatically used as the smtp_bind_address. This supports virtual
+IP hosting, but can be a problem on multi-homed firewalls. See the
+inet_interfaces documentation for more detail. </p>
+
+<p> Note 2: address information may be enclosed inside <tt>[]</tt>,
+but this form is not required here. </p>
+
+%PARAM smtp_bind_address6
+
+<p>
+An optional numerical network address that the Postfix SMTP client
+should bind to when making an IPv6 connection.
+</p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+<p>
+This can be specified in the main.cf file for all SMTP clients, or
+it can be specified in the master.cf file for a specific client,
+for example:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtp ... smtp -o smtp_bind_address6=1:2:3:4:5:6:7:8
+</pre>
+</blockquote>
+
+<p> See smtp_bind_address_enforce for how Postfix should handle
+errors (Postfix 3.7 and later). </p>
+
+<p> Note 1: when inet_interfaces specifies no more than one IPv6
+address, and that address is a non-loopback address, it is
+automatically used as the smtp_bind_address6. This supports virtual
+IP hosting, but can be a problem on multi-homed firewalls. See the
+inet_interfaces documentation for more detail. </p>
+
+<p> Note 2: address information may be enclosed inside <tt>[]</tt>,
+but this form is not recommended here. </p>
+
+%PARAM smtp_connection_cache_time_limit 2s
+
+<p> When SMTP connection caching is enabled, the amount of time that
+an unused SMTP client socket is kept open before it is closed. Do
+not specify larger values without permission from the remote sites.
+</p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_connection_reuse_time_limit 300s
+
+<p> The amount of time during which Postfix will use an SMTP
+connection repeatedly. The timer starts when the connection is
+initiated (i.e. it includes the connect, greeting and helo latency,
+in addition to the latencies of subsequent mail delivery transactions).
+</p>
+
+<p> This feature addresses a performance stability problem with
+remote SMTP servers. This problem is not specific to Postfix: it
+can happen when any MTA sends large amounts of SMTP email to a site
+that has multiple MX hosts. </p>
+
+<p> The problem starts when one of a set of MX hosts becomes slower
+than the rest. Even though SMTP clients connect to fast and slow
+MX hosts with equal probability, the slow MX host ends up with more
+simultaneous inbound connections than the faster MX hosts, because
+the slow MX host needs more time to serve each client request. </p>
+
+<p> The slow MX host becomes a connection attractor. If one MX
+host becomes N times slower than the rest, it dominates mail delivery
+latency unless there are more than N fast MX hosts to counter the
+effect. And if the number of MX hosts is smaller than N, the mail
+delivery latency becomes effectively that of the slowest MX host
+divided by the total number of MX hosts. </p>
+
+<p> The solution uses connection caching in a way that differs from
+Postfix version 2.2. By limiting the amount of time during which a connection
+can be used repeatedly (instead of limiting the number of deliveries
+over that connection), Postfix not only restores fairness in the
+distribution of simultaneous connections across a set of MX hosts,
+it also favors deliveries over connections that perform well, which
+is exactly what we want. </p>
+
+<p> The default reuse time limit, 300s, is comparable to the various
+smtp transaction timeouts which are fair estimates of maximum excess
+latency for a slow delivery. Note that hosts may accept thousands
+of messages over a single connection within the default connection
+reuse time limit. This number is much larger than the default Postfix
+version 2.2 limit of 10 messages per cached connection. It may prove necessary
+to lower the limit to avoid interoperability issues with MTAs that
+exhibit bugs when many messages are delivered via a single connection.
+A lower reuse time limit risks losing the benefit of connection
+reuse when the average connection and mail delivery latency exceeds
+the reuse time limit. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_connection_cache_destinations
+
+<p> Permanently enable SMTP connection caching for the specified
+destinations. With SMTP connection caching, a connection is not
+closed immediately after completion of a mail transaction. Instead,
+the connection is kept open for up to $smtp_connection_cache_time_limit
+seconds. This allows connections to be reused for other deliveries,
+and can improve mail delivery performance. </p>
+
+<p> Specify a comma or white space separated list of destinations
+or pseudo-destinations: </p>
+
+<ul>
+
+<li> if mail is sent without a relay host: a domain name (the
+right-hand side of an email address, without the [] around a numeric
+IP address),
+
+<li> if mail is sent via a relay host: a relay host name (without
+[] or non-default TCP port), as specified in main.cf or in the
+transport map,
+
+<li> if mail is sent via a UNIX-domain socket: a pathname (without
+the unix: prefix),
+
+<li> a /file/name with domain names and/or relay host names as
+defined above,
+
+<li> a "type:table" with domain names and/or relay host names on
+the left-hand side. The right-hand side result from "type:table"
+lookups is ignored.
+
+</ul>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_connection_cache_on_demand yes
+
+<p> Temporarily enable SMTP connection caching while a destination
+has a high volume of mail in the active queue. With SMTP connection
+caching, a connection is not closed immediately after completion
+of a mail transaction. Instead, the connection is kept open for
+up to $smtp_connection_cache_time_limit seconds. This allows
+connections to be reused for other deliveries, and can improve mail
+delivery performance. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_connect_timeout 30s
+
+<p>
+The Postfix SMTP client time limit for completing a TCP connection, or
+zero (use the operating system built-in time limit).
+</p>
+
+<p>
+When no connection can be made within the deadline, the Postfix
+SMTP client
+tries the next address on the mail exchanger list. Specify 0 to
+disable the time limit (i.e. use whatever timeout is implemented by
+the operating system).
+</p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM smtp_data_done_timeout 600s
+
+<p>
+The Postfix SMTP client time limit for sending the SMTP ".", and
+for receiving the remote SMTP server response.
+</p>
+
+<p>
+When no response is received within the deadline, a warning is
+logged that the mail may be delivered multiple times.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM smtp_data_init_timeout 120s
+
+<p>
+The Postfix SMTP client time limit for sending the SMTP DATA command,
+and for receiving the remote SMTP server response.
+</p>
+
+<p>
+Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds).
+</p>
+
+%PARAM smtp_data_xfer_timeout 180s
+
+<p>
+The Postfix SMTP client time limit for sending the SMTP message content.
+When the connection makes no progress for more than $smtp_data_xfer_timeout
+seconds the Postfix SMTP client terminates the transfer.
+</p>
+
+<p>
+Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds).
+</p>
+
+%PARAM smtp_defer_if_no_mx_address_found no
+
+<p>
+Defer mail delivery when no MX record resolves to an IP address.
+</p>
+
+<p>
+The default (no) is to return the mail as undeliverable. With older
+Postfix versions the default was to keep trying to deliver the mail
+until someone fixed the MX record or until the mail was too old.
+</p>
+
+<p>
+Note: the Postfix SMTP client always ignores MX records with equal
+or worse preference
+than the local MTA itself.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM lmtp_destination_concurrency_limit $default_destination_concurrency_limit
+
+<p> The maximal number of parallel deliveries to the same destination
+via the lmtp message delivery transport. This limit is enforced by
+the queue manager. The message delivery transport name is the first
+field in the entry in the master.cf file. </p>
+
+%PARAM lmtp_destination_recipient_limit $default_destination_recipient_limit
+
+<p> The maximal number of recipients per message for the lmtp
+message delivery transport. This limit is enforced by the queue
+manager. The message delivery transport name is the first field in
+the entry in the master.cf file. </p>
+
+<p> Setting this parameter to a value of 1 changes the meaning of
+lmtp_destination_concurrency_limit from concurrency per domain into
+concurrency per recipient. </p>
+
+%PARAM relay_destination_concurrency_limit $default_destination_concurrency_limit
+
+<p> The maximal number of parallel deliveries to the same destination
+via the relay message delivery transport. This limit is enforced
+by the queue manager. The message delivery transport name is the
+first field in the entry in the master.cf file. </p>
+
+<p> This feature is available in Postfix 2.0 and later. </p>
+
+%PARAM relay_destination_recipient_limit $default_destination_recipient_limit
+
+<p> The maximal number of recipients per message for the relay
+message delivery transport. This limit is enforced by the queue
+manager. The message delivery transport name is the first field in
+the entry in the master.cf file. </p>
+
+<p> Setting this parameter to a value of 1 changes the meaning of
+relay_destination_concurrency_limit from concurrency per domain
+into concurrency per recipient. </p>
+
+<p> This feature is available in Postfix 2.0 and later. </p>
+
+%PARAM smtp_destination_concurrency_limit $default_destination_concurrency_limit
+
+<p> The maximal number of parallel deliveries to the same destination
+via the smtp message delivery transport. This limit is enforced by
+the queue manager. The message delivery transport name is the first
+field in the entry in the master.cf file. </p>
+
+%PARAM smtp_destination_recipient_limit $default_destination_recipient_limit
+
+<p> The maximal number of recipients per message for the smtp
+message delivery transport. This limit is enforced by the queue
+manager. The message delivery transport name is the first field in
+the entry in the master.cf file. </p>
+
+<p> Setting this parameter to a value of 1 changes the meaning of
+smtp_destination_concurrency_limit from concurrency per domain
+into concurrency per recipient. </p>
+
+%PARAM virtual_destination_concurrency_limit $default_destination_concurrency_limit
+
+<p> The maximal number of parallel deliveries to the same destination
+via the virtual message delivery transport. This limit is enforced
+by the queue manager. The message delivery transport name is the
+first field in the entry in the master.cf file. </p>
+
+%PARAM virtual_destination_recipient_limit $default_destination_recipient_limit
+
+<p> The maximal number of recipients per message for the virtual
+message delivery transport. This limit is enforced by the queue
+manager. The message delivery transport name is the first field in
+the entry in the master.cf file. </p>
+
+<p> Setting this parameter to a value of 1 changes the meaning of
+virtual_destination_concurrency_limit from concurrency per domain
+into concurrency per recipient. </p>
+
+%PARAM smtp_helo_name $myhostname
+
+<p>
+The hostname to send in the SMTP HELO or EHLO command.
+</p>
+
+<p>
+The default value is the machine hostname. Specify a hostname or
+[ip.add.re.ss].
+</p>
+
+<p>
+This information can be specified in the main.cf file for all SMTP
+clients, or it can be specified in the master.cf file for a specific
+client, for example:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ mysmtp ... smtp -o smtp_helo_name=foo.bar.com
+</pre>
+</blockquote>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM smtp_helo_timeout 300s
+
+<p>
+The Postfix SMTP client time limit for sending the HELO or EHLO command,
+and for receiving the initial remote SMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM smtp_host_lookup dns
+
+<p>
+What mechanisms the Postfix SMTP client uses to look up a host's
+IP address. This parameter is ignored when DNS lookups are disabled
+(see: disable_dns_lookups and smtp_dns_support_level). The "dns"
+mechanism is always tried before "native" if both are listed.
+</p>
+
+<p>
+Specify one of the following:
+</p>
+
+<dl>
+
+<dt><b>dns</b></dt>
+
+<dd>Hosts can be found in the DNS (preferred). </dd>
+
+<dt><b>native</b></dt>
+
+<dd>Use the native naming service only (nsswitch.conf, or equivalent
+mechanism). </dd>
+
+<dt><b>dns, native</b></dt>
+
+<dd>Use the native service for hosts not found in the DNS. </dd>
+
+</dl>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtp_line_length_limit 998
+
+<p>
+The maximal length of message header and body lines that Postfix
+will send via SMTP. This limit does not include the &lt;CR&gt;&lt;LF&gt;
+at the end of each line. Longer lines are broken by inserting
+"&lt;CR&gt;&lt;LF&gt;&lt;SPACE&gt;", to minimize the damage to MIME
+formatted mail. Specify zero to disable this limit.
+</p>
+
+<p>
+The Postfix limit of 998 characters not including &lt;CR&gt;&lt;LF&gt;
+is consistent with the SMTP limit of 1000 characters including
+&lt;CR&gt;&lt;LF&gt;. The Postfix limit was 990 with Postfix 2.8
+and earlier.
+</p>
+
+%PARAM smtp_mail_timeout 300s
+
+<p>
+The Postfix SMTP client time limit for sending the MAIL FROM command,
+and for receiving the remote SMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM smtp_mx_address_limit 5
+
+<p>
+The maximal number of MX (mail exchanger) IP addresses that can
+result from Postfix SMTP client mail exchanger lookups, or zero (no
+limit). Prior to
+Postfix version 2.3, this limit was disabled by default.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtp_mx_session_limit 2
+
+<p> The maximal number of SMTP sessions per delivery request before
+the Postfix SMTP client
+gives up or delivers to a fall-back relay host, or zero (no
+limit). This restriction ignores sessions that fail to complete the
+SMTP initial handshake (Postfix version 2.2 and earlier) or that fail to
+complete the EHLO and TLS handshake (Postfix version 2.3 and later). </p>
+
+<p> This feature is available in Postfix 2.1 and later. </p>
+
+%PARAM smtp_never_send_ehlo no
+
+<p> Never send EHLO at the start of an SMTP session. See also the
+smtp_always_send_ehlo parameter. </p>
+
+%PARAM smtp_pix_workaround_threshold_time 500s
+
+<p> How long a message must be queued before the Postfix SMTP client
+turns on the PIX firewall "&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;"
+bug workaround for delivery through firewalls with "smtp fixup"
+mode turned on. </p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+By default, the workaround is turned off for mail that is queued
+for less than 500 seconds. In other words, the workaround is normally
+turned off for the first delivery attempt.
+</p>
+
+<p>
+Specify 0 to enable the PIX firewall
+"&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;" bug workaround upon the
+first delivery attempt.
+</p>
+
+%PARAM smtp_quit_timeout 300s
+
+<p>
+The Postfix SMTP client time limit for sending the QUIT command,
+and for receiving the remote SMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM smtp_quote_rfc821_envelope yes
+
+<p>
+Quote addresses in Postfix SMTP client MAIL FROM and RCPT TO commands
+as required
+by RFC 5321. This includes putting quotes around an address localpart
+that ends in ".".
+</p>
+
+<p>
+The default is to comply with RFC 5321. If you have to send mail to
+a broken SMTP server, configure a special SMTP client in master.cf:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ broken-smtp . . . smtp -o smtp_quote_rfc821_envelope=no
+</pre>
+</blockquote>
+
+<p>
+and route mail for the destination in question to the "broken-smtp"
+message delivery with a transport(5) table.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtp_rcpt_timeout 300s
+
+<p>
+The Postfix SMTP client time limit for sending the SMTP RCPT TO
+command, and for receiving the remote SMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM smtp_sasl_auth_enable no
+
+<p>
+Enable SASL authentication in the Postfix SMTP client. By default,
+the Postfix SMTP client uses no authentication.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtp_sasl_auth_enable = yes
+</pre>
+
+%PARAM smtp_sasl_password_maps
+
+<p>
+Optional Postfix SMTP client lookup tables with one username:password
+entry per sender, remote hostname or next-hop domain. Per-sender
+lookup is done only when sender-dependent authentication is enabled.
+If no username:password entry is found, then the Postfix SMTP client
+will not attempt to authenticate to the remote host.
+</p>
+
+<p>
+The Postfix SMTP client opens the lookup table before going to
+chroot jail, so you can leave the password file in /etc/postfix.
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+%PARAM smtp_sasl_security_options noplaintext, noanonymous
+
+<p> Postfix SMTP client SASL security options; as of Postfix 2.3
+the list of available
+features depends on the SASL client implementation that is selected
+with <b>smtp_sasl_type</b>. </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+client SASL implementation: </p>
+
+<p>
+Specify zero or more of the following:
+</p>
+
+<dl>
+
+<dt><b>noplaintext</b></dt>
+
+<dd>Disallow methods that use plaintext passwords. </dd>
+
+<dt><b>noactive</b></dt>
+
+<dd>Disallow methods subject to active (non-dictionary) attack.
+</dd>
+
+<dt><b>nodictionary</b></dt>
+
+<dd>Disallow methods subject to passive (dictionary) attack. </dd>
+
+<dt><b>noanonymous</b></dt>
+
+<dd>Disallow methods that allow anonymous authentication. </dd>
+
+<dt><b>mutual_auth</b></dt>
+
+<dd>Only allow methods that provide mutual authentication (not
+available with SASL version 1). </dd>
+
+</dl>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtp_sasl_security_options = noplaintext
+</pre>
+
+%PARAM smtp_sasl_mechanism_filter
+
+<p>
+If non-empty, a Postfix SMTP client filter for the remote SMTP
+server's list of offered SASL mechanisms. Different client and
+server implementations may support different mechanism lists; by
+default, the Postfix SMTP client will use the intersection of the
+two. smtp_sasl_mechanism_filter specifies an optional third mechanism
+list to intersect with. </p>
+
+<p> Specify mechanism names, "/file/name" patterns or "type:table"
+lookup tables. The right-hand side result from "type:table" lookups
+is ignored. Specify "!pattern" to exclude a mechanism name from the
+list. The form "!/file/name" is supported only in Postfix version
+2.4 and later. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+smtp_sasl_mechanism_filter = plain, login
+smtp_sasl_mechanism_filter = /etc/postfix/smtp_mechs
+smtp_sasl_mechanism_filter = !gssapi, !login, static:rest
+</pre>
+
+%PARAM smtp_send_xforward_command no
+
+<p>
+Send the non-standard XFORWARD command when the Postfix SMTP server
+EHLO response announces XFORWARD support.
+</p>
+
+<p>
+This allows a Postfix SMTP delivery agent, used for injecting mail
+into
+a content filter, to forward the name, address, protocol and HELO
+name of the original client to the content filter and downstream
+queuing SMTP server. This can produce more useful logging than
+localhost[127.0.0.1] etc.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtp_skip_4xx_greeting yes
+
+<p>
+Skip SMTP servers that greet with a 4XX status code (go away, try
+again later).
+</p>
+
+<p>
+By default, the Postfix SMTP client moves on the next mail exchanger.
+Specify
+"smtp_skip_4xx_greeting = no" if Postfix should defer delivery
+immediately.
+</p>
+
+<p> This feature is available in Postfix 2.0 and earlier.
+Later Postfix versions always skip remote SMTP servers that greet
+with a
+4XX status code. </p>
+
+%PARAM smtp_skip_5xx_greeting yes
+
+<p>
+Skip remote SMTP servers that greet with a 5XX status code.
+</p>
+
+<p> By default, the Postfix SMTP client moves on the next mail
+exchanger. Specify "smtp_skip_5xx_greeting = no" if Postfix should
+bounce the mail immediately. Caution: the latter behavior appears
+to contradict RFC 2821. </p>
+
+%PARAM smtp_skip_quit_response yes
+
+<p>
+Do not wait for the response to the SMTP QUIT command.
+</p>
+
+%PARAM smtp_xforward_timeout 300s
+
+<p>
+The Postfix SMTP client time limit for sending the XFORWARD command,
+and for receiving the remote SMTP server response.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM authorized_verp_clients $mynetworks
+
+<p> What remote SMTP clients are allowed to specify the XVERP command.
+This command requests that mail be delivered one recipient at a
+time with a per recipient return address. </p>
+
+<p> By default, only trusted clients are allowed to specify XVERP.
+</p>
+
+<p> This parameter was introduced with Postfix version 1.1. Postfix
+version 2.1 renamed this parameter to smtpd_authorized_verp_clients
+and changed the default to none. </p>
+
+<p> Specify a list of network/netmask patterns, separated by commas
+and/or whitespace. The mask specifies the number of bits in the
+network part of a host address. You can also specify hostnames or
+.domain names (the initial dot causes the domain to match any name
+below it), "/file/name" or "type:table" patterns. A "/file/name"
+pattern is replaced by its contents; a "type:table" lookup table
+is matched when a table entry matches a lookup string (the lookup
+result is ignored). Continue long lines by starting the next line
+with whitespace. Specify "!pattern" to exclude an address or network
+block from the list. The form "!/file/name" is supported only in
+Postfix version 2.4 and later. </p>
+
+<p> Note: IP version 6 address information must be specified inside
+<tt>[]</tt> in the authorized_verp_clients value, and in files
+specified with "/file/name". IP version 6 addresses contain the
+":" character, and would otherwise be confused with a "type:table"
+pattern. </p>
+
+%PARAM smtpd_authorized_verp_clients $authorized_verp_clients
+
+<p> What remote SMTP clients are allowed to specify the XVERP command.
+This command requests that mail be delivered one recipient at a
+time with a per recipient return address. </p>
+
+<p> By default, no clients are allowed to specify XVERP. </p>
+
+<p> This parameter was renamed with Postfix version 2.1. The default value
+is backwards compatible with Postfix version 2.0. </p>
+
+<p> Specify a list of network/netmask patterns, separated by commas
+and/or whitespace. The mask specifies the number of bits in the
+network part of a host address. You can also specify hostnames or
+.domain names (the initial dot causes the domain to match any name
+below it), "/file/name" or "type:table" patterns. A "/file/name"
+pattern is replaced by its contents; a "type:table" lookup table
+is matched when a table entry matches a lookup string (the lookup
+result is ignored). Continue long lines by starting the next line
+with whitespace. Specify "!pattern" to exclude an address or network
+block from the list. The form "!/file/name" is supported only in
+Postfix version 2.4 and later. </p>
+
+<p> Note: IP version 6 address information must be specified inside
+<tt>[]</tt> in the smtpd_authorized_verp_clients value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern. </p>
+
+%PARAM smtpd_authorized_xclient_hosts
+
+<p>
+What remote SMTP clients are allowed to use the XCLIENT feature. This
+command overrides remote SMTP client information that is used for access
+control. Typical use is for SMTP-based content filters, fetchmail-like
+programs, or SMTP server access rule testing. See the XCLIENT_README
+document for details.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+<p>
+By default, no clients are allowed to specify XCLIENT.
+</p>
+
+<p>
+Specify a list of network/netmask patterns, separated by commas
+and/or whitespace. The mask specifies the number of bits in the
+network part of a host address. You can also specify hostnames or
+.domain names (the initial dot causes the domain to match any name
+below it), "/file/name" or "type:table" patterns. A "/file/name"
+pattern is replaced by its contents; a "type:table" lookup table
+is matched when a table entry matches a lookup string (the lookup
+result is ignored). Continue long lines by starting the next line
+with whitespace. Specify "!pattern" to exclude an address or network
+block from the list. The form "!/file/name" is supported only in
+Postfix version 2.4 and later. </p>
+
+<p> Note: IP version 6 address information must be specified inside
+<tt>[]</tt> in the smtpd_authorized_xclient_hosts value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern. </p>
+
+%PARAM smtpd_authorized_xforward_hosts
+
+<p>
+What remote SMTP clients are allowed to use the XFORWARD feature. This
+command forwards information that is used to improve logging after
+SMTP-based content filters. See the XFORWARD_README document for
+details.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+<p>
+By default, no clients are allowed to specify XFORWARD.
+</p>
+
+<p>
+Specify a list of network/netmask patterns, separated by commas
+and/or whitespace. The mask specifies the number of bits in the
+network part of a host address. You can also specify hostnames or
+.domain names (the initial dot causes the domain to match any name
+below it), "/file/name" or "type:table" patterns. A "/file/name"
+pattern is replaced by its contents; a "type:table" lookup table
+is matched when a table entry matches a lookup string (the lookup
+result is ignored). Continue long lines by starting the next line
+with whitespace. Specify "!pattern" to exclude an address or network
+block from the list. The form "!/file/name" is supported only in
+Postfix version 2.4 and later. </p>
+
+<p> Note: IP version 6 address information must be specified inside
+<tt>[]</tt> in the smtpd_authorized_xforward_hosts value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern. </p>
+
+%PARAM smtpd_banner $myhostname ESMTP $mail_name
+
+<p>
+The text that follows the 220 status code in the SMTP greeting
+banner. Some people like to see the mail version advertised. By
+default, Postfix shows no version.
+</p>
+
+<p>
+You MUST specify $myhostname at the start of the text. This is
+required by the SMTP protocol.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_banner = $myhostname ESMTP $mail_name ($mail_version)
+</pre>
+
+%PARAM smtpd_client_connection_count_limit 50
+
+<p>
+How many simultaneous connections any client is allowed to
+make to this service. By default, the limit is set to half
+the default process limit value.
+</p>
+
+<p>
+To disable this feature, specify a limit of 0.
+</p>
+
+<p>
+WARNING: The purpose of this feature is to limit abuse. It must
+not be used to regulate legitimate mail traffic.
+</p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+%PARAM smtpd_client_event_limit_exceptions $mynetworks
+
+<p>
+Clients that are excluded from smtpd_client_*_count/rate_limit
+restrictions. See the mynetworks parameter
+description for the parameter value syntax.
+</p>
+
+<p>
+By default, clients in trusted networks are excluded. Specify a
+list of network blocks, hostnames or .domain names (the initial
+dot causes the domain to match any name below it).
+</p>
+
+<p> Note: IP version 6 address information must be specified inside
+<tt>[]</tt> in the smtpd_client_event_limit_exceptions value, and
+in files specified with "/file/name". IP version 6 addresses
+contain the ":" character, and would otherwise be confused with a
+"type:table" pattern. </p>
+
+<p> Pattern matching of domain names is controlled by the presence
+or absence of "smtpd_client_event_limit_exceptions" in the
+parent_domain_matches_subdomains parameter value (Postfix 3.0 and
+later). </p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+%PARAM smtpd_client_connection_rate_limit 0
+
+<p>
+The maximal number of connection attempts any client is allowed to
+make to this service per time unit. The time unit is specified
+with the anvil_rate_time_unit configuration parameter.
+</p>
+
+<p>
+By default, a client can make as many connections per time unit as
+Postfix can accept.
+</p>
+
+<p>
+To disable this feature, specify a limit of 0.
+</p>
+
+<p>
+WARNING: The purpose of this feature is to limit abuse. It must
+not be used to regulate legitimate mail traffic.
+</p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_client_connection_rate_limit = 1000
+</pre>
+
+%PARAM smtpd_client_message_rate_limit 0
+
+<p>
+The maximal number of message delivery requests that any client is
+allowed to make to this service per time unit, regardless of whether
+or not Postfix actually accepts those messages. The time unit is
+specified with the anvil_rate_time_unit configuration parameter.
+</p>
+
+<p>
+By default, a client can send as many message delivery requests
+per time unit as Postfix can accept.
+</p>
+
+<p>
+To disable this feature, specify a limit of 0.
+</p>
+
+<p>
+WARNING: The purpose of this feature is to limit abuse. It must
+not be used to regulate legitimate mail traffic.
+</p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_client_message_rate_limit = 1000
+</pre>
+
+%PARAM smtpd_client_recipient_rate_limit 0
+
+<p>
+The maximal number of recipient addresses that any client is allowed
+to send to this service per time unit, regardless of whether or not
+Postfix actually accepts those recipients. The time unit is specified
+with the anvil_rate_time_unit configuration parameter.
+</p>
+
+<p>
+By default, a client can send as many recipient addresses per time
+unit as Postfix can accept.
+</p>
+
+<p>
+To disable this feature, specify a limit of 0.
+</p>
+
+<p>
+WARNING: The purpose of this feature is to limit abuse. It must
+not be used to regulate legitimate mail traffic.
+</p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_client_recipient_rate_limit = 1000
+</pre>
+
+%PARAM smtpd_client_new_tls_session_rate_limit 0
+
+<p>
+The maximal number of new (i.e., uncached) TLS sessions that a
+remote SMTP client is allowed to negotiate with this service per
+time unit. The time unit is specified with the anvil_rate_time_unit
+configuration parameter.
+</p>
+
+<p>
+By default, a remote SMTP client can negotiate as many new TLS
+sessions per time unit as Postfix can accept.
+</p>
+
+<p>
+To disable this feature, specify a limit of 0. Otherwise, specify
+a limit that is at least the per-client concurrent session limit,
+or else legitimate client sessions may be rejected.
+</p>
+
+<p>
+WARNING: The purpose of this feature is to limit abuse. It must
+not be used to regulate legitimate mail traffic.
+</p>
+
+<p>
+This feature is available in Postfix 2.3 and later.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_client_new_tls_session_rate_limit = 100
+</pre>
+
+%PARAM smtpd_client_auth_rate_limit 0
+
+<p>
+The maximal number of AUTH commands that any client is allowed to
+send to this service per time unit, regardless of whether or not
+Postfix actually accepts those commands. The time unit is specified
+with the anvil_rate_time_unit configuration parameter.
+</p>
+
+<p>
+By default, there is no limit on the number of AUTH commands that a
+client may send.
+</p>
+
+<p>
+To disable this feature, specify a limit of 0.
+</p>
+
+<p>
+WARNING: The purpose of this feature is to limit abuse. It must
+not be used to regulate legitimate mail traffic.
+</p>
+
+<p>
+This feature is available in Postfix 3.1 and later.
+</p>
+
+%PARAM smtpd_client_restrictions
+
+<p>
+Optional restrictions that the Postfix SMTP server applies in the
+context of a client connection request.
+See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access
+restriction lists" for a discussion of evaluation context and time.
+</p>
+
+<p>
+The default is to allow all connection requests.
+</p>
+
+<p>
+Specify a list of restrictions, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace.
+Restrictions are applied in the order as specified; the first
+restriction that matches wins.
+</p>
+
+<p>
+The following restrictions are specific to client hostname or
+client network address information.
+</p>
+
+<dl>
+
+<dt><b><a name="check_ccert_access">check_ccert_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd> By default use the remote SMTP client certificate fingerprint
+or the public key
+fingerprint (Postfix 2.9 and later) as the lookup key for the specified
+access(5) database; with Postfix version 2.2, also require that the
+remote SMTP client certificate is verified successfully.
+The fingerprint digest algorithm is configurable via the
+smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to
+Postfix version 2.5). This feature requires "smtpd_tls_ask_ccert
+= yes" and is available with Postfix version
+2.2 and later. </dd>
+
+<dd> The default algorithm is <b>sha256</b> with Postfix &ge; 3.6
+and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix
+&le; 3.5, the default algorithm is <b>md5</b>. The best-practice
+algorithm is now <b>sha256</b>. Recent advances in hash function
+cryptanalysis have led to md5 and sha1 being deprecated in favor of
+sha256. However, as long as there are no known "second pre-image"
+attacks against the older algorithms, their use in this context, though
+not recommended, is still likely safe. </dd>
+
+<dd> Alternatively, check_ccert_access accepts an explicit search
+order (Postfix 3.5 and later). The default search order as described
+above corresponds with: </dd>
+
+<dd> check_ccert_access { type:table, { search_order = cert_fingerprint,
+pubkey_fingerprint } } </dd>
+
+<dd> The commas are optional. </dd>
+
+<dt><b><a name="check_client_access">check_client_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access database for the client hostname,
+parent domains, client IP address, or networks obtained by stripping
+least significant octets. See the access(5) manual page for details. </dd>
+
+<dt><b><a name="check_client_a_access">check_client_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the IP addresses for the
+client hostname, and execute the corresponding action. Note: a result
+of "OK" is not allowed for safety reasons. Instead, use DUNNO in order
+to exclude specific hosts from denylists. This feature is available
+in Postfix 3.0 and later. </dd>
+
+<dt><b><a name="check_client_mx_access">check_client_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the MX hosts for the
+client hostname, and execute the corresponding action. If no MX
+record is found, look up A or AAAA records, just like the Postfix
+SMTP client would. Note: a result
+of "OK" is not allowed for safety reasons. Instead, use DUNNO in order
+to exclude specific hosts from denylists. This feature is available
+in Postfix 2.7 and later. </dd>
+
+<dt><b><a name="check_client_ns_access">check_client_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the DNS servers for
+the client hostname, and execute the corresponding action. Note: a
+result of "OK" is not allowed for safety reasons. Instead, use DUNNO
+in order to exclude specific hosts from denylists. This feature is
+available in Postfix 2.7 and later. </dd>
+
+<dt><b><a name="check_reverse_client_hostname_access">check_reverse_client_hostname_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access database for the unverified reverse
+client hostname, parent domains, client IP address, or networks
+obtained by stripping least significant octets. See the access(5)
+manual page for details. Note: a result of "OK" is not allowed for
+safety reasons. Instead, use DUNNO in order to exclude specific
+hosts from denylists. This feature is available in Postfix 2.6
+and later.</dd>
+
+<dt><b><a name="check_reverse_client_hostname_a_access">check_reverse_client_hostname_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the IP addresses for the
+unverified reverse client hostname, and execute the corresponding
+action. Note: a result of "OK" is not allowed for safety reasons.
+Instead, use DUNNO in order to exclude specific hosts from denylists.
+This feature is available in Postfix 3.0 and later. </dd>
+
+<dt><b><a name="check_reverse_client_hostname_mx_access">check_reverse_client_hostname_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the MX hosts for the
+unverified reverse client hostname, and execute the corresponding
+action. If no MX record is found, look up A or AAAA records, just
+like the Postfix SMTP client would.
+Note: a result of "OK" is not allowed for safety reasons.
+Instead, use DUNNO in order to exclude specific hosts from denylists.
+This feature is available in Postfix 2.7 and later. </dd>
+
+<dt><b><a name="check_reverse_client_hostname_ns_access">check_reverse_client_hostname_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the DNS servers for
+the unverified reverse client hostname, and execute the corresponding
+action. Note: a result of "OK" is not allowed for safety reasons.
+Instead, use DUNNO in order to exclude specific hosts from denylists.
+This feature is available in Postfix 2.7 and later. </dd>
+
+<dt><b><a name="check_sasl_access">check_sasl_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd> Use the remote SMTP client SASL user name as the lookup key for
+the specified access(5) database. The lookup key has the form
+"username@domainname" when the smtpd_sasl_local_domain parameter
+value is non-empty. Unlike the check_client_access feature,
+check_sasl_access does not perform matches of parent domains or IP
+subnet ranges. This feature is available with Postfix version 2.11
+and later. </dd>
+
+<dt><b><a name="permit_inet_interfaces">permit_inet_interfaces</a></b></dt>
+
+<dd>Permit the request when the client IP address matches
+$inet_interfaces. </dd>
+
+<dt><b><a name="permit_mynetworks">permit_mynetworks</a></b></dt>
+
+<dd>Permit the request when the client IP address matches any
+network or network address listed in $mynetworks. </dd>
+
+<dt><b><a name="permit_sasl_authenticated">permit_sasl_authenticated</a></b></dt>
+
+<dd> Permit the request when the client is successfully
+authenticated via the RFC 4954 (AUTH) protocol. </dd>
+
+
+<dt><b><a name="permit_tls_all_clientcerts">permit_tls_all_clientcerts</a></b></dt>
+
+<dd> Permit the request when the remote SMTP client certificate is
+verified successfully. This option must be used only if a special
+CA issues the certificates and only this CA is listed as a trusted
+CA. Otherwise, clients with a third-party certificate would also
+be allowed to relay. Specify "tls_append_default_CA = no" when the
+trusted CA is specified with smtpd_tls_CAfile or smtpd_tls_CApath,
+to prevent Postfix from appending the system-supplied default CAs.
+This feature requires "smtpd_tls_ask_ccert = yes" and is available
+with Postfix version 2.2 and later.</dd>
+
+<dt><b><a name="permit_tls_clientcerts">permit_tls_clientcerts</a></b></dt>
+
+<dd>Permit the request when the remote SMTP client certificate
+fingerprint or public key fingerprint (Postfix 2.9 and later) is
+listed in $relay_clientcerts.
+The fingerprint digest algorithm is configurable via the
+smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to
+Postfix version 2.5). This feature requires "smtpd_tls_ask_ccert
+= yes" and is available with Postfix version 2.2 and later.</dd>
+
+<dd> The default algorithm is <b>sha256</b> with Postfix &ge; 3.6
+and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix
+&le; 3.5, the default algorithm is <b>md5</b>. The best-practice
+algorithm is now <b>sha256</b>. Recent advances in hash function
+cryptanalysis have led to md5 and sha1 being deprecated in favor of
+sha256. However, as long as there are no known "second pre-image"
+attacks against the older algorithms, their use in this context, though
+not recommended, is still likely safe. </dd>
+
+<dt><b><a name="reject_rbl_client">reject_rbl_client <i>rbl_domain=d.d.d.d</i></a></b></dt>
+
+<dd>Reject the request when the reversed client network address is
+listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
+(Postfix version 2.1 and later only). Each "<i>d</i>" is a number,
+or a pattern inside "[]" that contains one or more ";"-separated
+numbers or number..number ranges (Postfix version 2.8 and later).
+If no "<i>=d.d.d.d</i>" is specified, reject the request when the
+reversed client network address is listed with any A record under
+<i>rbl_domain</i>. <br>
+The maps_rbl_reject_code parameter specifies the response code for
+rejected requests (default: 554), the default_rbl_reply parameter
+specifies the default server reply, and the rbl_reply_maps parameter
+specifies tables with server replies indexed by <i>rbl_domain</i>.
+This feature is available in Postfix 2.0 and later. </dd>
+
+<dt><b><a name="permit_dnswl_client">permit_dnswl_client <i>dnswl_domain=d.d.d.d</i></a></b></dt>
+
+<dd>Accept the request when the reversed client network address is
+listed with the A record "<i>d.d.d.d</i>" under <i>dnswl_domain</i>.
+Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
+one or more ";"-separated numbers or number..number ranges.
+If no "<i>=d.d.d.d</i>" is specified, accept the request when the
+reversed client network address is listed with any A record under
+<i>dnswl_domain</i>. <br> For safety, permit_dnswl_client is silently
+ignored when it would override reject_unauth_destination. The
+result is DEFER_IF_REJECT when allowlist lookup fails. This feature
+is available in Postfix 2.8 and later. </dd>
+
+<dt><b><a name="reject_rhsbl_client">reject_rhsbl_client <i>rbl_domain=d.d.d.d</i></a></b></dt>
+
+<dd>Reject the request when the client hostname is listed with the
+A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
+2.1 and later only). Each "<i>d</i>" is a number, or a pattern
+inside "[]" that contains one or more ";"-separated numbers or
+number..number ranges (Postfix version 2.8 and later). If no
+"<i>=d.d.d.d</i>" is specified, reject the request when the client
+hostname is listed with
+any A record under <i>rbl_domain</i>. See the reject_rbl_client
+description above for additional RBL related configuration parameters.
+This feature is available in Postfix 2.0 and later; with Postfix
+version 2.8 and later, reject_rhsbl_reverse_client will usually
+produce better results. </dd>
+
+<dt><b><a name="permit_rhswl_client">permit_rhswl_client <i>rhswl_domain=d.d.d.d</i></a></b></dt>
+
+<dd>Accept the request when the client hostname is listed with the
+A record "<i>d.d.d.d</i>" under <i>rhswl_domain</i>. Each "<i>d</i>"
+is a number, or a pattern inside "[]" that contains one or more
+";"-separated numbers or number..number ranges. If no
+"<i>=d.d.d.d</i>" is specified, accept the request when the client
+hostname is listed with any A record under <i>rhswl_domain</i>.
+<br> Caution: client name allowlisting is fragile, since the client
+name lookup can fail due to temporary outages. Client name
+allowlisting should be used only to reduce false positives in e.g.
+DNS-based blocklists, and not for making access rule exceptions.
+<br> For safety, permit_rhswl_client is silently ignored when it
+would override reject_unauth_destination. The result is DEFER_IF_REJECT
+when allowlist lookup fails. This feature is available in Postfix
+2.8 and later. </dd>
+
+<dt><b><a name="reject_rhsbl_reverse_client">reject_rhsbl_reverse_client <i>rbl_domain=d.d.d.d</i></a></b></dt>
+
+<dd>Reject the request when the unverified reverse client hostname
+is listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>.
+Each "<i>d</i>" is a number, or a pattern inside "[]" that contains
+one or more ";"-separated numbers or number..number ranges.
+If no "<i>=d.d.d.d</i>" is specified, reject the request when the
+unverified reverse client hostname is listed with any A record under
+<i>rbl_domain</i>. See the reject_rbl_client description above for
+additional RBL related configuration parameters. This feature is
+available in Postfix 2.8 and later. </dd>
+
+<dt><b><a name="reject_unknown_client_hostname">reject_unknown_client_hostname</a></b> (with Postfix &lt; 2.3: reject_unknown_client)</dt>
+
+<dd>Reject the request when 1) the client IP address-&gt;name mapping
+fails, or 2) the name-&gt;address mapping fails, or 3) the name-&gt;address
+mapping does not match the client IP address. <br> This is a
+stronger restriction than the reject_unknown_reverse_client_hostname
+feature, which triggers only under condition 1) above. <br> The
+unknown_client_reject_code parameter specifies the response code
+for rejected requests (default: 450). The reply is always 450 in
+case the address-&gt;name or name-&gt;address lookup failed due to
+a temporary problem. </dd>
+
+<dt><b><a name="reject_unknown_reverse_client_hostname">reject_unknown_reverse_client_hostname</a></b></dt>
+
+<dd>Reject the request when the client IP address has no address-&gt;name
+mapping. <br> This is a weaker restriction than the
+reject_unknown_client_hostname feature, which requires not only
+that the address-&gt;name and name-&gt;address mappings exist, but
+also that the two mappings reproduce the client IP address. <br>
+The unknown_client_reject_code parameter specifies the response
+code for rejected requests (default: 450). The reply is always 450
+in case the address-&gt;name lookup failed due to a temporary
+problem. <br> This feature is available in Postfix 2.3 and
+later. </dd>
+
+#<dt><b><a name="reject_unknown_forward_client_hostname">reject_unknown_forward_client_hostname</a></b></dt>
+#
+#<dd>Reject the request when the client IP address has no address-&gt;name
+#or name -&gt;address mapping. <br> This is a weaker restriction
+#than the reject_unknown_client_hostname feature, which requires not
+#only that the address-&gt;name and name-&gt;address mappings exist,
+#but also that the two mappings reproduce the client IP address.
+#<br> The unknown_client_reject_code parameter specifies the response
+#code for rejected requests (default: 450). The reply is always 450
+#in case the address-&gt;name or name -&gt;address lookup failed due
+#to a temporary problem. <br> This feature is available in Postfix
+#version 2.3 and later. </dd>
+
+</dl>
+
+<p>
+In addition, you can use any of the following <a name="generic">
+generic</a> restrictions. These restrictions are applicable in
+any SMTP command context.
+</p>
+
+<dl>
+
+<dt><b><a name="check_policy_service">check_policy_service <i>servername</i></a></b></dt>
+
+<dd>Query the specified policy server. See the SMTPD_POLICY_README
+document for details. This feature is available in Postfix 2.1
+and later. </dd>
+
+<dt><b><a name="defer">defer</a></b></dt>
+
+<dd>Defer the request. The client is told to try again later. This
+restriction is useful at the end of a restriction list, to make
+the default policy explicit. <br> The defer_code parameter specifies
+the SMTP server reply code (default: 450).</dd>
+
+<dt><b><a name="defer_if_permit">defer_if_permit</a></b></dt>
+
+<dd>Defer the request if some later restriction would result in an
+explicit or implicit PERMIT action. This is useful when a denylisting
+feature fails due to a temporary problem. This feature is available
+in Postfix version 2.1 and later. </dd>
+
+<dt><b><a name="defer_if_reject">defer_if_reject</a></b></dt>
+
+<dd>Defer the request if some later restriction would result in a
+REJECT action. This is useful when an allowlisting feature fails
+due to a temporary problem. This feature is available in Postfix
+version 2.1 and later. </dd>
+
+<dt><b><a name="permit">permit</a></b></dt>
+
+<dd>Permit the request. This restriction is useful at the end of
+a restriction list, to make the default policy explicit.</dd>
+
+<dt><b><a name="reject_multi_recipient_bounce">reject_multi_recipient_bounce</a></b></dt>
+
+<dd>Reject the request when the envelope sender is the null address,
+and the message has multiple envelope recipients. This usage has
+rare but legitimate applications: under certain conditions,
+multi-recipient mail that was posted with the DSN option NOTIFY=NEVER
+may be forwarded with the null sender address.
+<br> Note: this restriction can only work reliably
+when used in smtpd_data_restrictions or
+smtpd_end_of_data_restrictions, because the total number of
+recipients is not known at an earlier stage of the SMTP conversation.
+Use at the RCPT stage will only reject the second etc. recipient.
+<br>
+The multi_recipient_bounce_reject_code parameter specifies the
+response code for rejected requests (default: 550). This feature
+is available in Postfix 2.1 and later. </dd>
+
+<dt><b><a name="reject_plaintext_session">reject_plaintext_session</a></b></dt>
+
+<dd>Reject the request when the connection is not encrypted. This
+restriction should not be used before the client has had a chance
+to negotiate encryption with the AUTH or STARTTLS commands.
+<br>
+The plaintext_reject_code parameter specifies the response
+code for rejected requests (default: 450). This feature is available
+in Postfix 2.3 and later. </dd>
+
+<dt><b><a name="reject_unauth_pipelining">reject_unauth_pipelining</a></b></dt>
+
+<dd>Reject the request when the client sends SMTP commands ahead
+of time where it is not allowed, or when the client sends SMTP
+commands ahead of time without knowing that Postfix actually supports
+ESMTP command pipelining. This stops mail from bulk mail software
+that improperly uses ESMTP command pipelining in order to speed up
+deliveries.
+<br> With Postfix 2.6 and later, the SMTP server sets a per-session
+flag whenever it detects illegal pipelining, including pipelined
+HELO or EHLO commands. The reject_unauth_pipelining feature simply
+tests whether the flag was set at any point in time during the
+session.
+<br> With older Postfix versions, reject_unauth_pipelining checks
+the current status of the input read queue, and its usage is not
+recommended in contexts other than smtpd_data_restrictions. </dd>
+
+<dt><b><a name="reject">reject</a></b></dt>
+
+<dd>Reject the request. This restriction is useful at the end of
+a restriction list, to make the default policy explicit. The
+reject_code configuration parameter specifies the response code for
+rejected requests (default: 554).</dd>
+
+<dt><b><a name="sleep">sleep <i>seconds</i></a></b></dt>
+
+<dd>Pause for the specified number of seconds and proceed with
+the next restriction in the list, if any. This may stop zombie
+mail when used as:
+<pre>
+/etc/postfix/main.cf:
+ smtpd_client_restrictions =
+ sleep 1, reject_unauth_pipelining
+ smtpd_delay_reject = no
+</pre>
+This feature is available in Postfix 2.3. </dd>
+
+<dt><b><a name="warn_if_reject">warn_if_reject</a></b></dt>
+
+<dd> A safety net for testing. When "warn_if_reject" is placed
+before a reject-type restriction, access table query, or
+check_policy_service query, this logs a "reject_warning" message
+instead of rejecting a request (when a reject-type restriction fails
+due to a temporary error, this logs a "reject_warning" message for
+any implicit "defer_if_permit" actions that would normally prevent
+mail from being accepted by some later access restriction). This
+feature has no effect on defer_if_reject restrictions. </dd>
+
+</dl>
+
+<p>
+Other restrictions that are valid in this context:
+</p>
+
+<ul>
+
+<li> SMTP command specific restrictions that are described under
+the smtpd_helo_restrictions, smtpd_sender_restrictions or
+smtpd_recipient_restrictions parameters. When helo, sender or
+recipient restrictions are listed under smtpd_client_restrictions,
+they have effect only with "smtpd_delay_reject = yes", so that
+$smtpd_client_restrictions is evaluated at the time of the RCPT TO
+command.
+
+</ul>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_client_restrictions = permit_mynetworks, reject_unknown_client_hostname
+</pre>
+
+%CLASS smtpd-tarpit Tarpit features
+
+<p>
+When a remote SMTP client makes errors, the Postfix SMTP server
+can insert delays before responding. This can help to slow down
+run-away software. The behavior is controlled by an error counter
+that counts the number of errors within an SMTP session that a
+client makes without delivering mail.
+</p>
+
+<ul>
+
+<li><p>When the error counter is less than $smtpd_soft_error_limit the
+Postfix SMTP server replies immediately (Postfix version 2.0 and earlier
+delay their 4xx or 5xx error response). </p>
+
+<li><p>When the error counter reaches $smtpd_soft_error_limit, the Postfix
+SMTP server delays all its responses. </p>
+
+<li><p>When the error counter reaches $smtpd_hard_error_limit the Postfix
+SMTP server breaks the connection. </p>
+
+</ul>
+
+%PARAM smtpd_error_sleep_time 1s
+
+<p>With Postfix version 2.1 and later: the SMTP server response delay after
+a client has made more than $smtpd_soft_error_limit errors, and
+fewer than $smtpd_hard_error_limit errors, without delivering mail.
+</p>
+
+<p>With Postfix version 2.0 and earlier: the SMTP server delay
+before sending a reject (4xx or 5xx) response, when the client has
+made fewer than $smtpd_soft_error_limit errors without delivering
+mail. When the client has made $smtpd_soft_error_limit or more errors,
+delay all responses with the larger of (number of errors) seconds
+or $smtpd_error_sleep_time. </p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM smtpd_soft_error_limit 10
+
+<p>
+The number of errors a remote SMTP client is allowed to make without
+delivering mail before the Postfix SMTP server slows down all its
+responses.
+</p>
+
+<ul>
+
+<li><p>With Postfix version 2.1 and later, when the error count
+is &gt; $smtpd_soft_error_limit, the Postfix SMTP server
+delays all responses by $smtpd_error_sleep_time. </p>
+
+<li><p>With Postfix versions 2.0 and earlier, when the error count
+is &gt; $smtpd_soft_error_limit, the Postfix SMTP server delays all
+responses by the larger of (number of errors) seconds or
+$smtpd_error_sleep_time. </p>
+
+<li><p>With Postfix versions 2.0 and earlier, when the error count
+is &le; $smtpd_soft_error_limit, the Postfix SMTP server delays 4XX
+and 5XX responses by $smtpd_error_sleep_time. </p>
+
+</ul>
+
+%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 reached. Normally the default limit is 20, but
+it changes under overload to just 1. With Postfix 2.5 and earlier,
+the SMTP server always allows up to 20 errors by default.
+Valid values are greater than zero.
+
+</p>
+
+%PARAM smtpd_junk_command_limit normal: 100, overload: 1
+
+<p>
+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.5 and earlier, the SMTP server
+always allows up to 100 junk commands by default. </p>
+
+%PARAM smtpd_recipient_overshoot_limit 1000
+
+<p> The number of recipients that a remote SMTP client can send in
+excess of the limit specified with $smtpd_recipient_limit, before
+the Postfix SMTP server increments the per-session error count
+for each excess recipient. </p>
+
+%PARAM smtpd_etrn_restrictions
+
+<p>
+Optional restrictions that the Postfix SMTP server applies in the
+context of a client ETRN command.
+See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access
+restriction lists" for a discussion of evaluation context and time.
+</p>
+
+<p>
+The Postfix ETRN implementation accepts only destinations that are
+eligible for the Postfix "fast flush" service. See the ETRN_README
+file for details.
+</p>
+
+<p>
+Specify a list of restrictions, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace.
+Restrictions are applied in the order as specified; the first
+restriction that matches wins.
+</p>
+
+<p>
+The following restrictions are specific to the domain name information
+received with the ETRN command.
+</p>
+
+<dl>
+
+<dt><b><a name="check_etrn_access">check_etrn_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access database for the ETRN domain name
+or its parent domains. See the access(5) manual page for details.
+</dd>
+
+</dl>
+
+<p>
+Other restrictions that are valid in this context:
+</p>
+
+<ul>
+
+<li><a href="#generic">Generic</a> restrictions that can be used
+in any SMTP command context, described under smtpd_client_restrictions.
+
+<li>SMTP command specific restrictions described under
+smtpd_client_restrictions and smtpd_helo_restrictions.
+
+</ul>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_etrn_restrictions = permit_mynetworks, reject
+</pre>
+
+%PARAM smtpd_expansion_filter see "postconf -d" output
+
+<p>
+What characters are allowed in $name expansions of RBL reply
+templates. Characters not in the allowed set are replaced by "_".
+Use C like escapes to specify special characters such as whitespace.
+</p>
+
+<p>
+The smtpd_expansion_filter value is not subject to Postfix configuration
+parameter $name expansion.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM smtpd_forbidden_commands CONNECT GET POST regexp:{{/^[^A-Z]/ Bogus}}
+
+<p>
+List of commands that cause the Postfix SMTP server to immediately
+terminate the session with a 221 code. This can be used to disconnect
+clients that obviously attempt to abuse the system. In addition to the
+commands listed in this parameter, commands that follow the "Label:"
+format of message headers will also cause a disconnect. With Postfix
+versions 3.6 and earlier, the default value is "CONNECT GET POST".
+</p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+<p>
+Support for inline regular expressions was added in Postfix version
+3.7. See regexp_table(5) for a description of the syntax and features.
+</p>
+
+%PARAM smtpd_helo_required no
+
+<p>
+Require that a remote SMTP client introduces itself with the HELO
+or EHLO command before sending the MAIL command or other commands
+that require EHLO negotiation.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_helo_required = yes
+</pre>
+
+%PARAM smtpd_helo_restrictions
+
+<p>
+Optional restrictions that the Postfix SMTP server applies in the
+context of a client HELO command.
+See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access
+restriction lists" for a discussion of evaluation context and time.
+</p>
+
+<p>
+The default is to permit everything.
+</p>
+
+<p> Note: specify "smtpd_helo_required = yes" to fully enforce this
+restriction (without "smtpd_helo_required = yes", a client can
+simply skip smtpd_helo_restrictions by not sending HELO or EHLO).
+</p>
+
+<p>
+Specify a list of restrictions, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace.
+Restrictions are applied in the order as specified; the first
+restriction that matches wins.
+</p>
+
+<p>
+The following restrictions are specific to the hostname information
+received with the HELO or EHLO command.
+</p>
+
+<dl>
+
+<dt><b><a name="check_helo_access">check_helo_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the HELO or EHLO
+hostname or parent domains, and execute the corresponding action.
+Note: specify "smtpd_helo_required = yes" to fully enforce this
+restriction (without "smtpd_helo_required = yes", a client can
+simply skip check_helo_access by not sending HELO or EHLO). </dd>
+
+<dt><b><a name="check_helo_a_access">check_helo_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the IP addresses for
+the HELO or EHLO hostname, and execute the corresponding action.
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from denylists. Note
+2: specify "smtpd_helo_required = yes" to fully enforce this
+restriction (without "smtpd_helo_required = yes", a client can
+simply skip check_helo_a_access by not sending HELO or EHLO). This
+feature is available in Postfix 3.0 and later.
+</dd>
+
+<dt><b><a name="check_helo_mx_access">check_helo_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the MX hosts for
+the HELO or EHLO hostname, and execute the corresponding action.
+If no MX record is found, look up A or AAAA records, just like the
+Postfix SMTP client would.
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from denylists. Note
+2: specify "smtpd_helo_required = yes" to fully enforce this
+restriction (without "smtpd_helo_required = yes", a client can
+simply skip check_helo_mx_access by not sending HELO or EHLO). This
+feature is available in Postfix 2.1 and later.
+</dd>
+
+<dt><b><a name="check_helo_ns_access">check_helo_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the DNS servers
+for the HELO or EHLO hostname, and execute the corresponding action.
+Note 1: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from denylists. Note
+2: specify "smtpd_helo_required = yes" to fully enforce this
+restriction (without "smtpd_helo_required = yes", a client can
+simply skip check_helo_ns_access by not sending HELO or EHLO). This
+feature is available in Postfix 2.1 and later.
+</dd>
+
+<dt><b><a name="reject_invalid_helo_hostname">reject_invalid_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_invalid_hostname)</dt>
+
+<dd>Reject the request when the HELO or EHLO hostname is malformed.
+Note: specify "smtpd_helo_required = yes" to fully enforce
+this restriction (without "smtpd_helo_required = yes", a client can simply
+skip reject_invalid_helo_hostname by not sending HELO or EHLO).
+<br> The invalid_hostname_reject_code specifies the response code
+for rejected requests (default: 501).</dd>
+
+<dt><b><a name="reject_non_fqdn_helo_hostname">reject_non_fqdn_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_non_fqdn_hostname)</dt>
+
+<dd>Reject the request when the HELO or EHLO hostname is not in
+fully-qualified domain or address literal form, as required by the
+RFC. Note: specify
+"smtpd_helo_required = yes" to fully enforce this restriction
+(without "smtpd_helo_required = yes", a client can simply skip
+reject_non_fqdn_helo_hostname by not sending HELO or EHLO). <br>
+The non_fqdn_reject_code parameter specifies the response code for
+rejected requests (default: 504).</dd>
+
+<dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
+
+<dd>Reject the request when the HELO or EHLO hostname is
+listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
+(Postfix version 2.1 and later only). Each "<i>d</i>" is a number,
+or a pattern inside "[]" that contains one or more ";"-separated
+numbers or number..number ranges (Postfix version 2.8 and later).
+If no "<i>=d.d.d.d</i>" is
+specified, reject the request when the HELO or EHLO hostname is
+listed with any A record under <i>rbl_domain</i>. See the
+reject_rbl_client description for additional RBL related configuration
+parameters. Note: specify "smtpd_helo_required = yes" to fully
+enforce this restriction (without "smtpd_helo_required = yes", a
+client can simply skip reject_rhsbl_helo by not sending HELO or
+EHLO). This feature is available in Postfix 2.0
+and later. </dd>
+
+<dt><b><a name="reject_unknown_helo_hostname">reject_unknown_helo_hostname</a></b> (with Postfix &lt; 2.3: reject_unknown_hostname)</dt>
+
+<dd>Reject the request when the HELO or EHLO hostname has no DNS A
+or MX record. <br> The reply is specified with the
+unknown_hostname_reject_code parameter (default: 450) or
+unknown_helo_hostname_tempfail_action (default: defer_if_permit).
+See the respective parameter descriptions for details. <br>
+Note: specify "smtpd_helo_required = yes" to fully
+enforce this restriction (without "smtpd_helo_required = yes", a
+client can simply skip reject_unknown_helo_hostname by not sending
+HELO or EHLO). </dd>
+
+</dl>
+
+<p>
+Other restrictions that are valid in this context:
+</p>
+
+<ul>
+
+<li> <a href="#generic">Generic</a> restrictions that can be used
+in any SMTP command context, described under smtpd_client_restrictions.
+
+<li> Client hostname or network address specific restrictions
+described under smtpd_client_restrictions.
+
+<li> SMTP command specific restrictions described under
+smtpd_sender_restrictions or smtpd_recipient_restrictions. When
+sender or recipient restrictions are listed under smtpd_helo_restrictions,
+they have effect only with "smtpd_delay_reject = yes", so that
+$smtpd_helo_restrictions is evaluated at the time of the RCPT TO
+command.
+
+</ul>
+
+<p>
+Examples:
+</p>
+
+<pre>
+smtpd_helo_restrictions = permit_mynetworks, reject_invalid_helo_hostname
+smtpd_helo_restrictions = permit_mynetworks, reject_unknown_helo_hostname
+</pre>
+
+%PARAM smtpd_history_flush_threshold 100
+
+<p>
+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.
+</p>
+
+%PARAM smtpd_noop_commands
+
+<p>
+List of commands that the Postfix SMTP server replies to with "250
+Ok", without doing any syntax checks and without changing state.
+This list overrides any commands built into the Postfix SMTP server.
+</p>
+
+%PARAM smtpd_proxy_ehlo $myhostname
+
+<p>
+How the Postfix SMTP server announces itself to the proxy filter.
+By default, the Postfix hostname is used.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtpd_proxy_options
+
+<p>
+List of options that control how the Postfix SMTP server
+communicates with a before-queue content filter. Specify zero or
+more of the following, separated by comma or whitespace. </p>
+
+<dl>
+
+<dt><b>speed_adjust</b></dt>
+
+<dd> <p> Do not connect to a before-queue content filter until an entire
+message has been received. This reduces the number of simultaneous
+before-queue content filter processes. </p>
+
+<p> NOTE 1: A filter must not <i>selectively</i> reject recipients
+of a multi-recipient message. Rejecting all recipients is OK, as
+is accepting all recipients. </p>
+
+<p> NOTE 2: This feature increases the minimum amount of free queue
+space by $message_size_limit. The extra space is needed to save the
+message to a temporary file. </p> </dd>
+
+</dl>
+
+<p>
+This feature is available in Postfix 2.7 and later.
+</p>
+
+%CLASS smtpd-proxy SMTP Proxy filter
+
+<p>
+As of Postfix version 2.1, the SMTP server can forward all incoming
+mail to a content filtering proxy server that inspects all mail
+BEFORE it is stored in the Postfix mail queue.
+</p>
+
+<p>
+WARNING: the proxy filter must reply within a fixed deadline or
+else the remote SMTP client times out and mail duplication happens.
+This becomes a problem as mail load increases so that fewer and
+fewer CPU cycles remain available to mead the fixed deadline.
+</p>
+
+%PARAM smtpd_proxy_filter
+
+<p> The hostname and TCP port of the mail filtering proxy server.
+The proxy receives all mail from the Postfix SMTP server, and is
+supposed to give the result to another Postfix SMTP server process.
+</p>
+
+<p> Specify "host:port" or "inet:host:port" for a TCP endpoint, or
+"unix:pathname" for a UNIX-domain endpoint. The host can be specified
+as an IP address or as a symbolic name; no MX lookups are done.
+When no "host" or "host:" is specified, the local machine is
+assumed. Pathname interpretation is relative to the Postfix queue
+directory. </p>
+
+<p> This feature is available in Postfix 2.1 and later. </p>
+
+<p> The "inet:" and "unix:" prefixes are available in Postfix 2.3
+and later. </p>
+
+%PARAM smtpd_proxy_timeout 100s
+
+<p>
+The time limit for connecting to a proxy filter and for sending or
+receiving information. When a connection fails the client gets a
+generic error message while more detailed information is logged to
+the maillog file.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtpd_recipient_limit 1000
+
+<p>
+The maximal number of recipients that the Postfix SMTP server
+accepts per message delivery request.
+</p>
+
+%PARAM smtpd_recipient_restrictions see "postconf -d" output
+
+<p>
+Optional restrictions that the Postfix SMTP server applies in the
+context of a client RCPT TO command, after smtpd_relay_restrictions.
+See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access
+restriction lists" for a discussion of evaluation context and time.
+</p>
+
+<p> With Postfix versions before 2.10, the rules for relay permission
+and spam blocking were combined under smtpd_recipient_restrictions,
+resulting in error-prone configuration. As of Postfix 2.10, relay
+permission rules are preferably implemented with smtpd_relay_restrictions,
+so that a permissive spam blocking policy under
+smtpd_recipient_restrictions will no longer result in a permissive
+mail relay policy. </p>
+
+<p> For backwards compatibility, sites that migrate from Postfix
+versions before 2.10 can set smtpd_relay_restrictions to the empty
+value, and use smtpd_recipient_restrictions exactly as before. </p>
+
+<p>
+IMPORTANT: Either the smtpd_relay_restrictions or the
+smtpd_recipient_restrictions parameter must specify
+at least one of the following restrictions. Otherwise Postfix will
+refuse to receive mail:
+</p>
+
+<blockquote>
+<pre>
+reject, reject_unauth_destination
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+defer, defer_if_permit, defer_unauth_destination
+</pre>
+</blockquote>
+
+<p>
+Specify a list of restrictions, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace.
+Restrictions are applied in the order as specified; the first
+restriction that matches wins.
+</p>
+
+<p>
+The following restrictions are specific to the recipient address
+that is received with the RCPT TO command.
+</p>
+
+<dl>
+
+<dt><b><a name="check_recipient_access">check_recipient_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the resolved RCPT
+TO address, domain, parent domains, or localpart@, and execute the
+corresponding action. </dd>
+
+<dt><b><a name="check_recipient_a_access">check_recipient_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the IP addresses for
+the RCPT TO domain, and execute the corresponding action. Note:
+a result of "OK" is not allowed for safety reasons. Instead, use
+DUNNO in order to exclude specific hosts from denylists. This
+feature is available in Postfix 3.0 and later. </dd>
+
+<dt><b><a name="check_recipient_mx_access">check_recipient_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the MX hosts for
+the RCPT TO domain, and execute the corresponding action. If no
+MX record is found, look up A or AAAA records, just like the Postfix
+SMTP client would. Note:
+a result of "OK" is not allowed for safety reasons. Instead, use
+DUNNO in order to exclude specific hosts from denylists. This
+feature is available in Postfix 2.1 and later. </dd>
+
+<dt><b><a name="check_recipient_ns_access">check_recipient_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the DNS servers
+for the RCPT TO domain, and execute the corresponding action.
+Note: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from denylists. This
+feature is available in Postfix 2.1 and later. </dd>
+
+<dt><b><a name="permit_auth_destination">permit_auth_destination</a></b></dt>
+
+<dd>Permit the request when one of the following is true:
+
+<ul>
+
+<li> Postfix is a mail forwarder: the resolved RCPT TO domain matches
+$relay_domains or a subdomain thereof, and the address contains no
+sender-specified routing (user@elsewhere@domain),
+
+<li> Postfix is the final destination: the resolved RCPT TO domain
+matches $mydestination, $inet_interfaces, $proxy_interfaces,
+$virtual_alias_domains, or $virtual_mailbox_domains, and the address
+contains no sender-specified routing (user@elsewhere@domain).
+
+</ul></dd>
+
+<dt><b><a name="permit_mx_backup">permit_mx_backup</a></b></dt>
+
+<dd>Permit the request when the local mail system is a backup MX for
+the RCPT TO domain, or when the domain is an authorized destination
+(see permit_auth_destination for definition).
+
+<ul>
+
+<li> Safety: permit_mx_backup does not accept addresses that have
+sender-specified routing information (example: user@elsewhere@domain).
+
+<li> Safety: permit_mx_backup can be vulnerable to mis-use when
+access is not restricted with permit_mx_backup_networks.
+
+<li> Safety: as of Postfix version 2.3, permit_mx_backup no longer
+accepts the address when the local mail system is a primary MX for
+the recipient domain. Exception: permit_mx_backup accepts the address
+when it specifies an authorized destination (see permit_auth_destination
+for definition).
+
+<li> Limitation: mail may be rejected in case of a temporary DNS
+lookup problem with Postfix prior to version 2.0.
+
+</ul></dd>
+
+<dt><b><a name="reject_non_fqdn_recipient">reject_non_fqdn_recipient</a></b></dt>
+
+<dd>Reject the request when the RCPT TO address specifies a
+domain that is not in
+fully-qualified domain form, as required by the RFC. <br> The
+non_fqdn_reject_code parameter specifies the response code for
+rejected requests (default: 504). </dd>
+
+<dt><b><a name="reject_rhsbl_recipient">reject_rhsbl_recipient <i>rbl_domain=d.d.d.d</i></a></b></dt>
+
+<dd>Reject the request when the RCPT TO domain is listed with the
+A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix version
+2.1 and later only). Each "<i>d</i>" is a number, or a pattern
+inside "[]" that contains one or more ";"-separated numbers or
+number..number ranges (Postfix version 2.8 and later). If no
+"<i>=d.d.d.d</i>" is specified, reject
+the request when the RCPT TO domain is listed with
+any A record under <i>rbl_domain</i>. <br> The maps_rbl_reject_code
+parameter specifies the response code for rejected requests (default:
+554); the default_rbl_reply parameter specifies the default server
+reply; and the rbl_reply_maps parameter specifies tables with server
+replies indexed by <i>rbl_domain</i>. This feature is available
+in Postfix version 2.0 and later.</dd>
+
+<dt><b><a name="reject_unauth_destination">reject_unauth_destination</a></b></dt>
+
+<dd>Reject the request unless one of the following is true:
+
+<ul>
+
+<li> Postfix is a mail forwarder: the resolved RCPT TO domain matches
+$relay_domains or a subdomain thereof, and contains no sender-specified
+routing (user@elsewhere@domain),
+
+<li> Postfix is the final destination: the resolved RCPT TO domain
+matches $mydestination, $inet_interfaces, $proxy_interfaces,
+$virtual_alias_domains, or $virtual_mailbox_domains, and contains
+no sender-specified routing (user@elsewhere@domain).
+
+</ul>The relay_domains_reject_code parameter specifies the response
+code for rejected requests (default: 554). </dd>
+
+<dt><b><a name="defer_unauth_destination">defer_unauth_destination</a></b></dt>
+
+<dd> Reject the same requests as reject_unauth_destination, with a
+non-permanent error code. This feature is available in Postfix
+2.10 and later.</dd>
+
+<dt><b><a name="reject_unknown_recipient_domain">reject_unknown_recipient_domain</a></b></dt>
+
+<dd>Reject the request when Postfix is not final destination for
+the recipient domain, and the RCPT TO domain has 1) no DNS MX and
+no DNS A
+record or 2) a malformed MX record such as a record with
+a zero-length MX hostname (Postfix version 2.3 and later). <br> The
+reply is specified with the unknown_address_reject_code parameter
+(default: 450), unknown_address_tempfail_action (default:
+defer_if_permit), or 556 (nullmx, Postfix 3.0 and
+later). See the respective parameter descriptions for details.
+</dd>
+
+<dt><b><a name="reject_unlisted_recipient">reject_unlisted_recipient</a></b> (with Postfix version 2.0: check_recipient_maps)</dt>
+
+<dd> Reject the request when the RCPT TO address is not listed in
+the list of valid recipients for its domain class. See the
+smtpd_reject_unlisted_recipient parameter description for details.
+This feature is available in Postfix 2.1 and later.</dd>
+
+<dt><b><a name="reject_unverified_recipient">reject_unverified_recipient</a></b></dt>
+
+<dd>Reject the request when mail to the RCPT TO address is known
+to bounce, or when the recipient address destination is not reachable.
+Address verification information is managed by the verify(8) server;
+see the ADDRESS_VERIFICATION_README file for details. <br> The
+unverified_recipient_reject_code parameter specifies the numerical
+response code when an address is known to bounce (default: 450,
+change it to 550 when you are confident that it is safe to do so).
+<br>The unverified_recipient_defer_code parameter specifies the
+numerical response code when an address probe failed due to a
+temporary problem (default: 450). <br> The
+unverified_recipient_tempfail_action parameter specifies the action
+after address probe failure due to a temporary problem (default:
+defer_if_permit). <br> This feature breaks for aliased addresses
+with "enable_original_recipient = no" (Postfix &le; 3.2). <br>
+This feature is available in Postfix 2.1 and later. </dd>
+
+</dl>
+
+<p>
+Other restrictions that are valid in this context:
+</p>
+
+<ul>
+
+<li><a href="#generic">Generic</a> restrictions that can be used
+in any SMTP command context, described under smtpd_client_restrictions.
+
+<li>SMTP command specific restrictions described under
+smtpd_client_restrictions, smtpd_helo_restrictions and
+smtpd_sender_restrictions.
+
+</ul>
+
+<p>
+Example:
+</p>
+
+<pre>
+# The Postfix before 2.10 default mail relay policy. Later Postfix
+# versions implement this preferably with smtpd_relay_restrictions.
+smtpd_recipient_restrictions = permit_mynetworks, reject_unauth_destination
+</pre>
+
+%PARAM smtpd_relay_restrictions permit_mynetworks, permit_sasl_authenticated, defer_unauth_destination
+
+<p> Access restrictions for mail relay control that the Postfix
+SMTP server applies in the context of the RCPT TO command, before
+smtpd_recipient_restrictions.
+See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access
+restriction lists" for a discussion of evaluation context and time.
+</p>
+
+<p> With Postfix versions before 2.10, the rules for relay permission
+and spam blocking were combined under smtpd_recipient_restrictions,
+resulting in error-prone configuration. As of Postfix 2.10, relay
+permission rules are preferably implemented with smtpd_relay_restrictions,
+so that a permissive spam blocking policy under
+smtpd_recipient_restrictions will no longer result in a permissive
+mail relay policy. </p>
+
+<p> For backwards compatibility, sites that migrate from Postfix
+versions before 2.10 can set smtpd_relay_restrictions to the empty
+value, and use smtpd_recipient_restrictions exactly as before. </p>
+
+<p>
+By default, the Postfix SMTP server accepts:
+</p>
+
+<ul>
+
+<li> Mail from clients whose IP address matches $mynetworks, or:
+
+<li> Mail from clients who are SASL authenticated, or:
+
+<li> Mail to remote destinations that match $relay_domains, except
+for addresses that contain sender-specified routing
+(user@elsewhere@domain), or:
+
+<li> Mail to local destinations that match $inet_interfaces
+or $proxy_interfaces, $mydestination, $virtual_alias_domains, or
+$virtual_mailbox_domains.
+
+</ul>
+
+<p>
+IMPORTANT: Either the smtpd_relay_restrictions or the
+smtpd_recipient_restrictions parameter must specify
+at least one of the following restrictions. Otherwise Postfix will
+refuse to receive mail:
+</p>
+
+<blockquote>
+<pre>
+reject, reject_unauth_destination
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+defer, defer_if_permit, defer_unauth_destination
+</pre>
+</blockquote>
+
+<p>
+Specify a list of restrictions, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace.
+The same restrictions are available as documented under
+smtpd_recipient_restrictions.
+</p>
+
+<p> This feature is available in Postix 2.10 and later. </p>
+
+%CLASS sasl-auth SASL Authentication
+
+<p>
+Postfix SASL support (RFC 4954) can be used to authenticate remote
+SMTP clients to the Postfix SMTP server, and to authenticate the
+Postfix SMTP client to a remote SMTP server.
+See the SASL_README document for details.
+</p>
+
+%PARAM smtpd_sasl_auth_enable no
+
+<p>
+Enable SASL authentication in the Postfix SMTP server. By default,
+the Postfix SMTP server does not use authentication.
+</p>
+
+<p>
+If a remote SMTP client is authenticated, the permit_sasl_authenticated
+access restriction can be used to permit relay access, like this:
+</p>
+
+<blockquote>
+<pre>
+# With Postfix 2.10 and later, the mail relay policy is
+# preferably specified under smtpd_relay_restrictions.
+smtpd_relay_restrictions =
+ permit_mynetworks, permit_sasl_authenticated, ...
+</pre>
+
+<pre>
+# With Postfix before 2.10, the relay policy can be
+# specified only under smtpd_recipient_restrictions.
+smtpd_recipient_restrictions =
+ permit_mynetworks, permit_sasl_authenticated, ...
+</pre>
+</blockquote>
+
+<p> To reject all SMTP connections from unauthenticated clients,
+specify "smtpd_delay_reject = yes" (which is the default) and use:
+</p>
+
+<blockquote>
+<pre>
+smtpd_client_restrictions = permit_sasl_authenticated, reject
+</pre>
+</blockquote>
+
+<p>
+See the SASL_README file for SASL configuration and operation details.
+</p>
+
+%PARAM smtpd_sasl_authenticated_header no
+
+<p> Report the SASL authenticated user name in the smtpd(8) Received
+message header. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_sasl_exceptions_networks
+
+<p>
+What remote SMTP clients the Postfix SMTP server will not offer
+AUTH support to.
+</p>
+
+<p>
+Some clients (Netscape 4 at least) have a bug that causes them to
+require a login and password whenever AUTH is offered, whether it's
+necessary or not. To work around this, specify, for example,
+$mynetworks to prevent Postfix from offering AUTH to local clients.
+</p>
+
+<p>
+Specify a list of network/netmask patterns, separated by commas
+and/or whitespace. The mask specifies the number of bits in the
+network part of a host address. You can also specify "/file/name" or
+"type:table" patterns. A "/file/name" pattern is replaced by its
+contents; a "type:table" lookup table is matched when a table entry
+matches a lookup string (the lookup result is ignored). Continue
+long lines by starting the next line with whitespace. Specify
+"!pattern" to exclude an address or network block from the list.
+The form "!/file/name" is supported only in Postfix version 2.4 and
+later. </p>
+
+<p> Note: IP version 6 address information must be specified inside
+<tt>[]</tt> in the smtpd_sasl_exceptions_networks value, and in
+files specified with "/file/name". IP version 6 addresses contain
+the ":" character, and would otherwise be confused with a "type:table"
+pattern. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_sasl_exceptions_networks = $mynetworks
+</pre>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtpd_sasl_local_domain
+
+<p>
+The name of the Postfix SMTP server's local SASL authentication
+realm.
+</p>
+
+<p>
+By default, the local authentication realm name is the null string.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+smtpd_sasl_local_domain = $mydomain
+smtpd_sasl_local_domain = $myhostname
+</pre>
+
+%PARAM smtpd_sasl_security_options noanonymous
+
+<p> Postfix SMTP server SASL security options; as of Postfix 2.3
+the list of available
+features depends on the SASL server implementation that is selected
+with <b>smtpd_sasl_type</b>. </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+server SASL implementation: </p>
+
+<p>
+Restrict what authentication mechanisms the Postfix SMTP server
+will offer to the client. The list of available authentication
+mechanisms is system dependent.
+</p>
+
+<p>
+Specify zero or more of the following:
+</p>
+
+<dl>
+
+<dt><b>noplaintext</b></dt>
+
+<dd>Disallow methods that use plaintext passwords. </dd>
+
+<dt><b>noactive</b></dt>
+
+<dd>Disallow methods subject to active (non-dictionary) attack. </dd>
+
+<dt><b>nodictionary</b></dt>
+
+<dd>Disallow methods subject to passive (dictionary) attack. </dd>
+
+<dt><b>noanonymous</b></dt>
+
+<dd>Disallow methods that allow anonymous authentication. </dd>
+
+<dt><b>forward_secrecy</b></dt>
+
+<dd>Only allow methods that support forward secrecy (Dovecot only).
+</dd>
+
+<dt><b>mutual_auth</b></dt>
+
+<dd>Only allow methods that provide mutual authentication (not available
+with Cyrus SASL version 1). </dd>
+
+</dl>
+
+<p>
+By default, the Postfix SMTP server accepts plaintext passwords but
+not anonymous logins.
+</p>
+
+<p>
+Warning: it appears that clients try authentication methods in the
+order as advertised by the server (e.g., PLAIN ANONYMOUS CRAM-MD5)
+which means that if you disable plaintext passwords, clients will
+log in anonymously, even when they should be able to use CRAM-MD5.
+So, if you disable plaintext logins, disable anonymous logins too.
+Postfix treats anonymous login as no authentication.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+smtpd_sasl_security_options = noanonymous, noplaintext
+</pre>
+
+%PARAM smtpd_sender_login_maps
+
+<p>
+Optional lookup table with the SASL login names that own the sender
+(MAIL FROM) addresses.
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found. With lookups from
+indexed files such as DB or DBM, or from networked tables such as
+NIS, LDAP or SQL, the following search operations are done with a
+sender address of <i>user@domain</i>: </p>
+
+<dl>
+
+<dt> 1) <i>user@domain</i> </dt>
+
+<dd>This table lookup is always done and has the highest precedence. </dd>
+
+<dt> 2) <i>user</i> </dt>
+
+<dd>This table lookup is done only when the <i>domain</i> part of the
+sender address matches $myorigin, $mydestination, $inet_interfaces
+or $proxy_interfaces. </dd>
+
+<dt> 3) <i>@domain</i> </dt>
+
+<dd>This table lookup is done last and has the lowest precedence. </dd>
+
+</dl>
+
+<p>
+In all cases the result of table lookup must be either "not found"
+or a list of SASL login names separated by comma and/or whitespace.
+</p>
+
+%PARAM smtpd_sender_restrictions
+
+<p>
+Optional restrictions that the Postfix SMTP server applies in the
+context of a client MAIL FROM command.
+See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access
+restriction lists" for a discussion of evaluation context and time.
+</p>
+
+<p>
+The default is to permit everything.
+</p>
+
+<p>
+Specify a list of restrictions, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace.
+Restrictions are applied in the order as specified; the first
+restriction that matches wins.
+</p>
+
+<p>
+The following restrictions are specific to the sender address
+received with the MAIL FROM command.
+</p>
+
+<dl>
+
+<dt><b><a name="check_sender_access">check_sender_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the MAIL FROM
+address, domain, parent domains, or localpart@, and execute the
+corresponding action. </dd>
+
+<dt><b><a name="check_sender_a_access">check_sender_a_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the IP addresses for
+the MAIL FROM domain, and execute the corresponding action. Note:
+a result of "OK" is not allowed for safety reasons. Instead, use
+DUNNO in order to exclude specific hosts from denylists. This
+feature is available in Postfix 3.0 and later. </dd>
+
+<dt><b><a name="check_sender_mx_access">check_sender_mx_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the MX hosts for
+the MAIL FROM domain, and execute the corresponding action. If no
+MX record is found, look up A or AAAA records, just like the Postfix
+SMTP client would. Note:
+a result of "OK" is not allowed for safety reasons. Instead, use
+DUNNO in order to exclude specific hosts from denylists. This
+feature is available in Postfix 2.1 and later. </dd>
+
+<dt><b><a name="check_sender_ns_access">check_sender_ns_access</a> <i><a href="DATABASE_README.html">type:table</a></i></b></dt>
+
+<dd>Search the specified access(5) database for the DNS servers
+for the MAIL FROM domain, and execute the corresponding action.
+Note: a result of "OK" is not allowed for safety reasons. Instead,
+use DUNNO in order to exclude specific hosts from denylists. This
+feature is available in Postfix 2.1 and later. </dd>
+
+<dt><b><a name="reject_authenticated_sender_login_mismatch">reject_authenticated_sender_login_mismatch</a></b></dt>
+
+<dd>Enforces the reject_sender_login_mismatch restriction for
+authenticated clients only. This feature is available in
+Postfix version 2.1 and later. </dd>
+
+<dt><b><a name="reject_known_sender_login_mismatch">reject_known_sender_login_mismatch</a></b></dt>
+
+<dd>Apply the reject_sender_login_mismatch restriction only to MAIL
+FROM addresses that are known in $smtpd_sender_login_maps. This
+feature is available in Postfix version 2.11 and later. </dd>
+
+<dt><b><a name="reject_non_fqdn_sender">reject_non_fqdn_sender</a></b></dt>
+
+<dd>Reject the request when the MAIL FROM address specifies a
+domain that is not in
+fully-qualified domain form as required by the RFC. <br> The
+non_fqdn_reject_code parameter specifies the response code for
+rejected requests (default: 504). </dd>
+
+<dt><b><a name="reject_rhsbl_sender">reject_rhsbl_sender <i>rbl_domain=d.d.d.d</i></a></b></dt>
+
+<dd>Reject the request when the MAIL FROM domain is listed with
+the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i> (Postfix
+version 2.1 and later only). Each "<i>d</i>" is a number, or a
+pattern inside "[]" that contains one or more ";"-separated numbers
+or number..number ranges (Postfix version 2.8 and later). If no
+"<i>=d.d.d.d</i>" is specified,
+reject the request when the MAIL FROM domain is
+listed with any A record under <i>rbl_domain</i>. <br> The
+maps_rbl_reject_code parameter specifies the response code for
+rejected requests (default: 554); the default_rbl_reply parameter
+specifies the default server reply; and the rbl_reply_maps parameter
+specifies tables with server replies indexed by <i>rbl_domain</i>.
+This feature is available in Postfix 2.0 and later.</dd>
+
+<dt><b><a name="reject_sender_login_mismatch">reject_sender_login_mismatch</a></b></dt>
+
+<dd>Reject the request when $smtpd_sender_login_maps specifies an
+owner for the MAIL FROM address, but the client is not (SASL) logged
+in as that MAIL FROM address owner; or when the client is (SASL)
+logged in, but the client login name doesn't own the MAIL FROM
+address according to $smtpd_sender_login_maps.</dd>
+
+<dt><b><a name="reject_unauthenticated_sender_login_mismatch">reject_unauthenticated_sender_login_mismatch</a></b></dt>
+
+<dd>Enforces the reject_sender_login_mismatch restriction for
+unauthenticated clients only. This feature is available in
+Postfix version 2.1 and later. </dd>
+
+<dt><b><a name="reject_unknown_sender_domain">reject_unknown_sender_domain</a></b></dt>
+
+<dd>Reject the request when Postfix is not the final destination for
+the sender address, and the MAIL FROM domain has 1) no DNS MX and
+no DNS A
+record, or 2) a malformed MX record such as a record with
+a zero-length MX hostname (Postfix version 2.3 and later). <br> The
+reply is specified with the unknown_address_reject_code parameter
+(default: 450), unknown_address_tempfail_action (default:
+defer_if_permit), or 550 (nullmx, Postfix 3.0 and
+later). See the respective parameter descriptions for details.
+</dd>
+
+<dt><b><a name="reject_unlisted_sender">reject_unlisted_sender</a></b></dt>
+
+<dd>Reject the request when the MAIL FROM address is not listed in
+the list of valid recipients for its domain class. See the
+smtpd_reject_unlisted_sender parameter description for details.
+This feature is available in Postfix 2.1 and later.</dd>
+
+<dt><b><a name="reject_unverified_sender">reject_unverified_sender</a></b></dt>
+
+<dd>Reject the request when mail to the MAIL FROM address is known to
+bounce, or when the sender address destination is not reachable.
+Address verification information is managed by the verify(8) server;
+see the ADDRESS_VERIFICATION_README file for details. <br> The
+unverified_sender_reject_code parameter specifies the numerical
+response code when an address is known to bounce (default: 450,
+change into 550 when you are confident that it is safe to do so).
+<br>The unverified_sender_defer_code specifies the numerical response
+code when an address probe failed due to a temporary problem
+(default: 450). <br> The unverified_sender_tempfail_action parameter
+specifies the action after address probe failure due to a temporary
+problem (default: defer_if_permit). <br> This feature breaks for
+aliased addresses with "enable_original_recipient = no" (Postfix
+&le; 3.2). <br> This feature is available in Postfix 2.1 and later.
+</dd>
+
+</dl>
+
+<p>
+Other restrictions that are valid in this context:
+</p>
+
+<ul>
+
+<li> <a href="#generic">Generic</a> restrictions that can be used
+in any SMTP command context, described under smtpd_client_restrictions.
+
+<li> SMTP command specific restrictions described under
+smtpd_client_restrictions and smtpd_helo_restrictions.
+
+<li> SMTP command specific restrictions described under
+smtpd_recipient_restrictions. When recipient restrictions are listed
+under smtpd_sender_restrictions, they have effect only with
+"smtpd_delay_reject = yes", so that $smtpd_sender_restrictions is
+evaluated at the time of the RCPT TO command.
+
+</ul>
+
+<p>
+Examples:
+</p>
+
+<pre>
+smtpd_sender_restrictions = reject_unknown_sender_domain
+smtpd_sender_restrictions = reject_unknown_sender_domain,
+ check_sender_access hash:/etc/postfix/access
+</pre>
+
+%PARAM smtpd_timeout normal: 300s, overload: 10s
+
+<p> When the Postfix SMTP server wants to send an SMTP server
+response, how long the Postfix SMTP server will wait for an underlying
+network write operation to complete; and when the Postfix SMTP
+server Postfix wants to receive an SMTP client request, how long
+the Postfix SMTP server will wait for an underlying network read
+operation to complete. See the smtpd_per_request_deadline for how
+this time limit may be enforced (with Postfix 2.9-3.6 see
+smtpd_per_record_deadline). </p>
+
+<p> Normally the default limit
+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>
+Note: if you set SMTP time limits to very large values you may have
+to update the global ipc_timeout parameter.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM soft_bounce no
+
+<p>
+Safety net to keep mail queued that would otherwise be returned to
+the sender. This parameter disables locally-generated bounces,
+changes the handling of negative responses from remote servers,
+content filters or plugins,
+and prevents the Postfix SMTP server from rejecting mail permanently
+by changing 5xx reply codes into 4xx. However, soft_bounce is no
+cure for address rewriting mistakes or mail routing mistakes.
+</p>
+
+<p>
+Note: "soft_bounce = yes" is in some cases implemented by modifying
+server responses. Therefore, the response that Postfix logs may
+differ from the response that Postfix actually sends or receives.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+soft_bounce = yes
+</pre>
+
+%PARAM stale_lock_time 500s
+
+<p>
+The time after which a stale exclusive mailbox lockfile is removed.
+This is used for delivery to file or mailbox.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM strict_rfc821_envelopes no
+
+<p>
+Require that addresses received in SMTP MAIL FROM and RCPT TO
+commands are enclosed with &lt;&gt;, and that those addresses do
+not contain RFC 822 style comments or phrases. This stops mail
+from poorly written software.
+</p>
+
+<p>
+By default, the Postfix SMTP server accepts RFC 822 syntax in MAIL
+FROM and RCPT TO addresses.
+</p>
+
+%PARAM swap_bangpath yes
+
+<p>
+Enable the rewriting of "site!user" into "user@site". This is
+necessary if your machine is connected to UUCP networks. It is
+enabled by default.
+</p>
+
+<p> Note: with Postfix version 2.2, message header address rewriting
+happens only when one of the following conditions is true: </p>
+
+<ul>
+
+<li> The message is received with the Postfix sendmail(1) command,
+
+<li> The message is received from a network client that matches
+$local_header_rewrite_clients,
+
+<li> The message is received from the network, and the
+remote_header_rewrite_domain parameter specifies a non-empty value.
+
+</ul>
+
+<p> To get the behavior before Postfix version 2.2, specify
+"local_header_rewrite_clients = static:all". </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+swap_bangpath = no
+</pre>
+
+%PARAM syslog_facility mail
+
+<p>
+The syslog facility of Postfix logging. Specify a facility as
+defined in syslog.conf(5). The default facility is "mail".
+</p>
+
+<p>
+Warning: a non-default syslog_facility setting takes effect only
+after a Postfix process has completed initialization. Errors during
+process initialization will be logged with the default facility.
+Examples are errors while parsing the command line arguments, and
+errors while accessing the Postfix main.cf configuration file.
+</p>
+
+%PARAM syslog_name see "postconf -d" output
+
+<p>
+A prefix that is prepended to the process name in syslog
+records, so that, for example, "smtpd" becomes "prefix/smtpd".
+</p>
+
+<p>
+Warning: a non-default syslog_name setting takes effect only after
+a Postfix process has completed initialization. Errors during
+process initialization will be logged with the default name. Examples
+are errors while parsing the command line arguments, and errors
+while accessing the Postfix main.cf configuration file.
+</p>
+
+%PARAM transport_maps
+
+<p>
+Optional lookup tables with mappings from recipient address to
+(message delivery transport, next-hop destination). See transport(5)
+for details.
+</p>
+
+<p>
+Specify zero or more "type:table" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found. If you use this
+feature with local files, run "<b>postmap /etc/postfix/transport</b>"
+after making a change. </p>
+
+<p> Pattern matching of domain names is controlled by the presence
+or absence of "transport_maps" in the parent_domain_matches_subdomains
+parameter value. </p>
+
+<p> For safety reasons, as of Postfix 2.3 this feature does not
+allow $number substitutions in regular expression maps. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+transport_maps = dbm:/etc/postfix/transport
+transport_maps = hash:/etc/postfix/transport
+</pre>
+
+%PARAM transport_retry_time 60s
+
+<p>
+The time between attempts by the Postfix queue manager to contact
+a malfunctioning message delivery transport.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM trigger_timeout 10s
+
+<p>
+The time limit for sending a trigger to a Postfix daemon (for
+example, the pickup(8) or qmgr(8) daemon). This time limit prevents
+programs from getting stuck when the mail system is under heavy
+load.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM unknown_address_reject_code 450
+
+<p>
+The numerical response code when the Postfix SMTP server rejects a
+sender or recipient address because its domain is unknown. This
+is one of the possible replies from the restrictions
+reject_unknown_sender_domain and reject_unknown_recipient_domain.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM unknown_client_reject_code 450
+
+<p>
+The numerical Postfix SMTP server response code when a client
+without valid address &lt;=&gt; name mapping is rejected by the
+reject_unknown_client_hostname restriction. The SMTP server always replies
+with 450 when the mapping failed due to a temporary error condition.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM unknown_hostname_reject_code 450
+
+<p>
+The numerical Postfix SMTP server response code when the hostname
+specified with the HELO or EHLO command is rejected by the
+reject_unknown_helo_hostname restriction.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+%PARAM unknown_local_recipient_reject_code 550
+
+<p>
+The numerical Postfix SMTP server response code when a recipient
+address is local, and $local_recipient_maps specifies a list of
+lookup tables that does not match the recipient. A recipient
+address is local when its domain matches $mydestination,
+$proxy_interfaces or $inet_interfaces.
+</p>
+
+<p>
+The default setting is 550 (reject mail) but it is safer to initially
+use 450 (try again later) so you have time to find out if your
+local_recipient_maps settings are OK.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+unknown_local_recipient_reject_code = 450
+</pre>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM unverified_recipient_reject_code 450
+
+<p>
+The numerical Postfix SMTP server response when a recipient address
+is rejected by the reject_unverified_recipient restriction.
+</p>
+
+<p>
+Unlike elsewhere in Postfix, you can specify 250 in order to
+accept the address anyway.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM unverified_recipient_defer_code 450
+
+<p>
+The numerical Postfix SMTP server response when a recipient address
+probe fails due to a temporary error condition.
+</p>
+
+<p>
+Unlike elsewhere in Postfix, you can specify 250 in order to
+accept the address anyway.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+<p>
+This feature is available in Postfix 2.6 and later.
+</p>
+
+%PARAM unverified_sender_reject_code 450
+
+<p>
+The numerical Postfix SMTP server response code when a recipient
+address is rejected by the reject_unverified_sender restriction.
+</p>
+
+<p>
+Unlike elsewhere in Postfix, you can specify 250 in order to
+accept the address anyway.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM unverified_sender_defer_code 450
+
+<p>
+The numerical Postfix SMTP server response code when a sender address
+probe fails due to a temporary error condition.
+</p>
+
+<p>
+Unlike elsewhere in Postfix, you can specify 250 in order to
+accept the address anyway.
+</p>
+
+<p>
+Do not change this unless you have a complete understanding of RFC 5321.
+</p>
+
+<p>
+This feature is available in Postfix 2.6 and later.
+</p>
+
+%PARAM virtual_alias_domains $virtual_alias_maps
+
+<p> Postfix is the final destination for the specified list of virtual
+alias domains, that is, domains for which all addresses are aliased
+to addresses in other local or remote domains. The SMTP server
+validates recipient addresses with $virtual_alias_maps and rejects
+non-existent recipients. See also the virtual alias domain class
+in the ADDRESS_CLASS_README file </p>
+
+<p>
+This feature is available in Postfix 2.0 and later. The default
+value is backwards compatible with Postfix version 1.1.
+</p>
+
+<p>
+The default value is $virtual_alias_maps so that you can keep all
+information about virtual alias domains in one place. If you have
+many users, it is better to separate information that changes more
+frequently (virtual address -&gt; local or remote address mapping)
+from information that changes less frequently (the list of virtual
+domain names).
+</p>
+
+<p> Specify a list of host or domain names, "/file/name" or
+"type:table" patterns, separated by commas and/or whitespace. A
+"/file/name" pattern is replaced by its contents; a "type:table"
+lookup table is matched when a table entry matches a host or domain name
+(the lookup result is ignored). Continue long lines by starting
+the next line with whitespace. Specify "!pattern" to exclude a host
+or domain name from the list. The form "!/file/name" is supported
+only in Postfix version 2.4 and later. </p>
+
+<p>
+See also the VIRTUAL_README and ADDRESS_CLASS_README documents
+for further information.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+virtual_alias_domains = virtual1.tld virtual2.tld
+</pre>
+
+%PARAM virtual_alias_expansion_limit 1000
+
+<p>
+The maximal number of addresses that virtual alias expansion produces
+from each original recipient.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM virtual_alias_maps $virtual_maps
+
+<p>
+Optional lookup tables that alias specific mail addresses or domains
+to other local or remote addresses. The table format and lookups
+are documented in virtual(5). For an overview of Postfix address
+manipulations see the ADDRESS_REWRITING_README document.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later. The default
+value is backwards compatible with Postfix version 1.1.
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+Note: these lookups are recursive.
+</p>
+
+<p>
+If you use this feature with indexed files, run "<b>postmap
+/etc/postfix/virtual</b>" after changing the file.
+</p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+virtual_alias_maps = dbm:/etc/postfix/virtual
+virtual_alias_maps = hash:/etc/postfix/virtual
+</pre>
+
+%PARAM virtual_alias_recursion_limit 1000
+
+<p>
+The maximal nesting depth of virtual alias expansion. Currently
+the recursion limit is applied only to the left branch of the
+expansion graph, so the depth of the tree can in the worst case
+reach the sum of the expansion and recursion limits. This may
+change in the future.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%CLASS trouble-shooting Trouble shooting
+
+<p>
+The DEBUG_README document describes how to debug parts of the
+Postfix mail system. The methods vary from making the software log
+a lot of detail, to running some daemon processes under control of
+a call tracer or debugger.
+</p>
+
+%PARAM debugger_command
+
+<p>
+The external command to execute when a Postfix daemon program is
+invoked with the -D option.
+</p>
+
+<p>
+Use "command .. &amp; sleep 5" so that the debugger can attach before
+the process marches on. If you use an X-based debugger, be sure to
+set up your XAUTHORITY environment variable before starting Postfix.
+</p>
+
+<p>
+Note: the command is subject to $name expansion, before it is
+passed to the default command interpreter. Specify "$$" to
+produce a single "$" character.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+debugger_command =
+ PATH=/usr/bin:/usr/X11R6/bin
+ ddd $daemon_directory/$process_name $process_id &amp; sleep 5
+</pre>
+
+%PARAM 2bounce_notice_recipient postmaster
+
+<p> The recipient of undeliverable mail that cannot be returned to
+the sender. This feature is enabled with the notify_classes
+parameter. </p>
+
+%PARAM address_verify_service_name verify
+
+<p>
+The name of the verify(8) address verification service. This service
+maintains the status of sender and/or recipient address verification
+probes, and generates probes on request by other Postfix processes.
+</p>
+
+%PARAM alternate_config_directories
+
+<p>
+A list of non-default Postfix configuration directories that may
+be specified with "-c config_directory" on the command line (in the
+case of sendmail(1), with the "-C" option), or via the MAIL_CONFIG
+environment parameter.
+</p>
+
+<p>
+This list must be specified in the default Postfix main.cf file,
+and will be used by set-gid Postfix commands such as postqueue(1)
+and postdrop(1).
+</p>
+
+<p>
+Specify absolute pathnames, separated by comma or space. Note: $name
+expansion is not supported.
+</p>
+
+%PARAM append_at_myorigin yes
+
+<p>
+With locally submitted mail, append the string "@$myorigin" to mail
+addresses without domain information. With remotely submitted mail,
+append the string "@$remote_header_rewrite_domain" instead.
+</p>
+
+<p>
+Note 1: this feature is enabled by default and must not be turned off.
+Postfix does not support domain-less addresses.
+</p>
+
+<p> Note 2: with Postfix version 2.2, message header address rewriting
+happens only when one of the following conditions is true: </p>
+
+<ul>
+
+<li> The message is received with the Postfix sendmail(1) command,
+
+<li> The message is received from a network client that matches
+$local_header_rewrite_clients,
+
+<li> The message is received from the network, and the
+remote_header_rewrite_domain parameter specifies a non-empty value.
+
+</ul>
+
+<p> To get the behavior before Postfix version 2.2, specify
+"local_header_rewrite_clients = static:all". </p>
+
+%PARAM append_dot_mydomain Postfix &ge; 3.0: no, Postfix &lt; 3.0: yes
+
+<p>
+With locally submitted mail, append the string ".$mydomain" to
+addresses that have no ".domain" information. With remotely submitted
+mail, append the string ".$remote_header_rewrite_domain"
+instead.
+</p>
+
+<p>
+Note 1: this feature is enabled by default. If disabled, users will not be
+able to send mail to "user@partialdomainname" but will have to
+specify full domain names instead.
+</p>
+
+<p> Note 2: with Postfix version 2.2, message header address rewriting
+happens only when one of the following conditions is true: </p>
+
+<ul>
+
+<li> The message is received with the Postfix sendmail(1) command,
+
+<li> The message is received from a network client that matches
+$local_header_rewrite_clients,
+
+<li> The message is received from the network, and the
+remote_header_rewrite_domain parameter specifies a non-empty value.
+
+</ul>
+
+<p> To get the behavior before Postfix version 2.2, specify
+"local_header_rewrite_clients = static:all". </p>
+
+%PARAM application_event_drain_time 100s
+
+<p>
+How long the postkick(1) command waits for a request to enter the
+Postfix daemon process input buffer before giving up.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM authorized_flush_users static:anyone
+
+<p>
+List of users who are authorized to flush the queue.
+</p>
+
+<p>
+By default, all users are allowed to flush the queue. Access is
+always granted if the invoking user is the super-user or the
+$mail_owner user. Otherwise, the real UID of the process is looked
+up in the system password file, and access is granted only if the
+corresponding login name is on the access list. The username
+"unknown" is used for processes whose real UID is not found in the
+password file. </p>
+
+<p>
+Specify a list of user names, "/file/name" or "type:table" patterns,
+separated by commas and/or whitespace. The list is matched left to
+right, and the search stops on the first match. A "/file/name"
+pattern is replaced
+by its contents; a "type:table" lookup table is matched when a name
+matches a lookup key (the lookup result is ignored). Continue long
+lines by starting the next line with whitespace. Specify "!pattern"
+to exclude a name from the list. The form "!/file/name" is supported
+only in Postfix version 2.4 and later. </p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+%PARAM authorized_mailq_users static:anyone
+
+<p>
+List of users who are authorized to view the queue.
+</p>
+
+<p>
+By default, all users are allowed to view the queue. Access is
+always granted if the invoking user is the super-user or the
+$mail_owner user. Otherwise, the real UID of the process is looked
+up in the system password file, and access is granted only if the
+corresponding login name is on the access list. The username
+"unknown" is used for processes whose real UID is not found in the
+password file. </p>
+
+<p>
+Specify a list of user names, "/file/name" or "type:table" patterns,
+separated by commas and/or whitespace. The list is matched left to
+right, and the search stops on the first match. A "/file/name"
+pattern is replaced
+by its contents; a "type:table" lookup table is matched when a name
+matches a lookup key (the lookup result is ignored). Continue long
+lines by starting the next line with whitespace. Specify "!pattern"
+to exclude a user name from the list. The form "!/file/name" is
+supported only in Postfix version 2.4 and later. </p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+%PARAM authorized_submit_users static:anyone
+
+<p>
+List of users who are authorized to submit mail with the sendmail(1)
+command (and with the privileged postdrop(1) helper command).
+</p>
+
+<p>
+By default, all users are allowed to submit mail. Otherwise, the
+real UID of the process is looked up in the system password file,
+and access is granted only if the corresponding login name is on
+the access list. The username "unknown" is used for processes
+whose real UID is not found in the password file. To deny mail
+submission access to all users specify an empty list. </p>
+
+<p>
+Specify a list of user names, "/file/name" or "type:table" patterns,
+separated by commas and/or whitespace. The list is matched left to right,
+and the search stops on the first match. A "/file/name" pattern is
+replaced by its contents;
+a "type:table" lookup table is matched when a name matches a lookup key
+(the lookup result is ignored). Continue long lines by starting the
+next line with whitespace. Specify "!pattern" to exclude a user
+name from the list. The form "!/file/name" is supported only in
+Postfix version 2.4 and later. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+authorized_submit_users = !www, static:all
+</pre>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+%PARAM backwards_bounce_logfile_compatibility yes
+
+<p>
+Produce additional bounce(8) logfile records that can be read by
+Postfix versions before 2.0. The current and more extensible "name =
+value" format is needed in order to implement more sophisticated
+functionality.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM bounce_notice_recipient postmaster
+
+<p>
+The recipient of postmaster notifications with the message headers
+of mail that Postfix did not deliver and of SMTP conversation
+transcripts of mail that Postfix did not receive. This feature is
+enabled with the notify_classes parameter. </p>
+
+%PARAM bounce_service_name bounce
+
+<p>
+The name of the bounce(8) service. This service maintains a record
+of failed delivery attempts and generates non-delivery notifications.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM broken_sasl_auth_clients no
+
+<p>
+Enable interoperability with remote SMTP clients that implement an obsolete
+version of the AUTH command (RFC 4954). Examples of such clients
+are MicroSoft Outlook Express version 4 and MicroSoft Exchange
+version 5.0.
+</p>
+
+<p>
+Specify "broken_sasl_auth_clients = yes" to have Postfix advertise
+AUTH support in a non-standard way.
+</p>
+
+%PARAM cleanup_service_name cleanup
+
+<p>
+The name of the cleanup(8) service. This service rewrites addresses
+into the standard form, and performs canonical(5) address mapping
+and virtual(5) aliasing.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM anvil_status_update_time 600s
+
+<p>
+How frequently the anvil(8) connection and rate limiting server
+logs peak usage information.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.2 and later.
+</p>
+
+%PARAM enable_errors_to no
+
+<p> Report mail delivery errors to the address specified with the
+non-standard Errors-To: message header, instead of the envelope
+sender address (this feature is removed with Postfix version 2.2, is
+turned off by default with Postfix version 2.1, and is always turned on
+with older Postfix versions). </p>
+
+%PARAM extract_recipient_limit 10240
+
+<p>
+The maximal number of recipient addresses that Postfix will extract
+from message headers when mail is submitted with "<b>sendmail -t</b>".
+</p>
+
+<p>
+This feature was removed in Postfix version 2.1.
+</p>
+
+%PARAM anvil_rate_time_unit 60s
+
+<p>
+The time unit over which client connection rates and other rates
+are calculated.
+</p>
+
+<p>
+This feature is implemented by the anvil(8) service which is available
+in Postfix version 2.2 and later.
+</p>
+
+<p>
+The default interval is relatively short. Because of the high
+frequency of updates, the anvil(8) server uses volatile memory
+only. Thus, information is lost whenever the process terminates.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM command_expansion_filter see "postconf -d" output
+
+<p>
+Restrict the characters that the local(8) delivery agent allows in
+$name expansions of $mailbox_command and $command_execution_directory.
+Characters outside the
+allowed set are replaced by underscores.
+</p>
+
+%PARAM content_filter
+
+<p> After the message is queued, send the entire message to the
+specified <i>transport:destination</i>. The <i>transport</i> name
+specifies the first field of a mail delivery agent definition in
+master.cf; the syntax of the next-hop <i>destination</i> is described
+in the manual page of the corresponding delivery agent. More
+information about external content filters is in the Postfix
+FILTER_README file. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> This setting has lower precedence than a FILTER action
+that is specified in an access(5), header_checks(5) or body_checks(5)
+table. </p>
+
+<li> <p> The meaning of an empty next-hop filter <i>destination</i>
+is version dependent. Postfix 2.7 and later will use the recipient
+domain; earlier versions will use $myhostname. Specify
+"default_filter_nexthop = $myhostname" for compatibility with Postfix
+2.6 or earlier, or specify a content_filter value with an explicit
+next-hop <i>destination</i>. </p>
+
+</ul>
+
+%PARAM default_delivery_slot_discount 50
+
+<p>
+The default value for transport-specific _delivery_slot_discount
+settings.
+</p>
+
+<p>
+This parameter speeds up the moment when a message preemption can
+happen. Instead of waiting until the full amount of delivery slots
+required is available, the preemption can happen when
+<i>transport</i>_delivery_slot_discount percent of the required amount
+plus <i>transport</i>_delivery_slot_loan still remains to be accumulated.
+Note that the full amount will still have to be accumulated before
+another preemption can take place later.
+</p>
+
+<p> Use <i>transport</i>_delivery_slot_discount to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+%PARAM default_delivery_slot_loan 3
+
+<p>
+The default value for transport-specific _delivery_slot_loan
+settings.
+</p>
+
+<p>
+This parameter speeds up the moment when a message preemption can
+happen. Instead of waiting until the full amount of delivery slots
+required is available, the preemption can happen when
+transport_delivery_slot_discount percent of the required amount
+plus transport_delivery_slot_loan still remains to be accumulated.
+Note that the full amount will still have to be accumulated before
+another preemption can take place later.
+</p>
+
+<p> Use <i>transport</i>_delivery_slot_loan to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+%CLASS verp VERP Support
+
+<p>
+With VERP style delivery, each recipient of a message receives a
+customized copy of the message with his/her own recipient address
+encoded in the envelope sender address. The VERP_README file
+describes configuration and operation details of Postfix support
+for variable envelope return path addresses. VERP style delivery
+is requested with the SMTP XVERP command or with the "<b>sendmail
+-V</b>" command-line option and is available in Postfix
+1.1 and later.
+</p>
+
+%PARAM default_verp_delimiters +=
+
+<p> The two default VERP delimiter characters. These are used when
+no explicit delimiters are specified with the SMTP XVERP command
+or with the "<b>sendmail -XV</b>" command-line option (Postfix 2.2
+and earlier: <b>-V</b>). Specify characters that are allowed by the
+verp_delimiter_filter setting.
+</p>
+
+<p>
+This feature is available in Postfix 1.1 and later.
+</p>
+
+%PARAM defer_service_name defer
+
+<p>
+The name of the defer service. This service is implemented by the
+bounce(8) daemon and maintains a record
+of failed delivery attempts and generates non-delivery notifications.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM delay_notice_recipient postmaster
+
+<p>
+The recipient of postmaster notifications with the message headers
+of mail that cannot be delivered within $delay_warning_time time
+units. </p>
+
+<p>
+See also: delay_warning_time, notify_classes.
+</p>
+
+%PARAM delay_warning_time 0h
+
+<p>
+The time after which the sender receives a copy of the message
+headers of mail that is still queued. The confirm_delay_cleared
+parameter controls sender notification when the delay clears up.
+</p>
+
+<p>
+To enable this feature, specify a non-zero time value (an integral
+value plus an optional one-letter suffix that specifies the time
+unit).
+</p>
+
+<p>
+Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is h (hours).
+</p>
+
+<p>
+See also: delay_notice_recipient, notify_classes, confirm_delay_cleared.
+</p>
+
+%PARAM confirm_delay_cleared no
+
+<p> After sending a "your message is delayed" notification, inform
+the sender when the delay clears up. This can result in a sudden
+burst of notifications at the end of a prolonged network outage,
+and is therefore disabled by default. </p>
+
+<p> See also: delay_warning_time. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM disable_dns_lookups no
+
+<p>
+Disable DNS lookups in the Postfix SMTP and LMTP clients. When
+disabled, hosts are looked up with the getaddrinfo() system
+library routine which normally also looks in /etc/hosts. As of
+Postfix 2.11, this parameter is deprecated; use smtp_dns_support_level
+instead.
+</p>
+
+<p>
+DNS lookups are enabled by default.
+</p>
+
+%CLASS mime MIME Processing
+
+<p>
+MIME processing is available in Postfix as of version 2.0. Older
+Postfix versions do not recognize MIME headers inside the message
+body.
+</p>
+
+%PARAM disable_mime_input_processing no
+
+<p>
+Turn off MIME processing while receiving mail. This means that no
+special treatment is given to Content-Type: message headers, and
+that all text after the initial message headers is considered to
+be part of the message body.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+<p>
+Mime input processing is enabled by default, and is needed in order
+to recognize MIME headers in message content.
+</p>
+
+%PARAM disable_mime_output_conversion no
+
+<p>
+Disable the conversion of 8BITMIME format to 7BIT format. Mime
+output conversion is needed when the destination does not advertise
+8BITMIME support.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM disable_verp_bounces no
+
+<p>
+Disable sending one bounce report per recipient.
+</p>
+
+<p>
+The default, one per recipient, is what ezmlm needs.
+</p>
+
+<p>
+This feature is available in Postfix 1.1 and later.
+</p>
+
+%PARAM dont_remove 0
+
+<p>
+Don't remove queue files and save them to the "saved" mail queue.
+This is a debugging aid. To inspect the envelope information and
+content of a Postfix queue file, use the postcat(1) command.
+</p>
+
+%PARAM empty_address_recipient MAILER-DAEMON
+
+<p>
+The recipient of mail addressed to the null address. Postfix does
+not accept such addresses in SMTP commands, but they may still be
+created locally as the result of configuration or software error.
+</p>
+
+%PARAM error_notice_recipient postmaster
+
+<p> The recipient of postmaster notifications about mail delivery
+problems that are caused by policy, resource, software or protocol
+errors. These notifications are enabled with the notify_classes
+parameter. </p>
+
+%PARAM error_service_name error
+
+<p>
+The name of the error(8) pseudo delivery agent. This service always
+returns mail as undeliverable.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM expand_owner_alias no
+
+<p>
+When delivering to an alias "<i>aliasname</i>" that has an
+"owner-<i>aliasname</i>" companion alias, set the envelope sender
+address to the expansion of the "owner-<i>aliasname</i>" alias.
+Normally, Postfix sets the envelope sender address to the name of
+the "owner-<i>aliasname</i>" alias.
+</p>
+
+%PARAM fallback_transport
+
+<p>
+Optional message delivery transport that the local(8) delivery
+agent should use for names that are not found in the aliases(5)
+or UNIX password database.
+</p>
+
+<p> The precedence of local(8) delivery features from high to low
+is: aliases, .forward files, mailbox_transport_maps, mailbox_transport,
+mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory,
+fallback_transport_maps, fallback_transport and luser_relay. </p>
+
+%PARAM fault_injection_code 0
+
+<p>
+Force specific internal tests to fail, to test the handling of
+errors that are difficult to reproduce otherwise.
+</p>
+
+%PARAM flush_service_name flush
+
+<p>
+The name of the flush(8) service. This service maintains per-destination
+logfiles with the queue file names of mail that is queued for those
+destinations.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM forward_expansion_filter see "postconf -d" output
+
+<p>
+Restrict the characters that the local(8) delivery agent allows in
+$name expansions of $forward_path. Characters outside the
+allowed set are replaced by underscores.
+</p>
+
+%PARAM header_address_token_limit 10240
+
+<p>
+The maximal number of address tokens are allowed in an address
+message header. Information that exceeds the limit is discarded.
+The limit is enforced by the cleanup(8) server.
+</p>
+
+%PARAM helpful_warnings yes
+
+<p>
+Log warnings about problematic configuration settings, and provide
+helpful suggestions.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM lmtp_cache_connection yes
+
+<p>
+Keep Postfix LMTP client connections open for up to $max_idle
+seconds. When the LMTP client receives a request for the same
+connection the connection is reused.
+</p>
+
+<p> This parameter is available in Postfix version 2.2 and earlier.
+With Postfix version 2.3 and later, see lmtp_connection_cache_on_demand,
+lmtp_connection_cache_destinations, or lmtp_connection_reuse_time_limit.
+</p>
+
+<p>
+The effectiveness of cached connections will be determined by the
+number of remote LMTP servers in use, and the concurrency limit specified
+for the Postfix LMTP client. Cached connections are closed under any of
+the following conditions:
+</p>
+
+<ul>
+
+<li> The Postfix LMTP client idle time limit is reached. This limit is
+specified with the Postfix max_idle configuration parameter.
+
+<li> A delivery request specifies a different destination than the
+one currently cached.
+
+<li> The per-process limit on the number of delivery requests is
+reached. This limit is specified with the Postfix max_use
+configuration parameter.
+
+<li> Upon the onset of another delivery request, the remote LMTP server
+associated with the current session does not respond to the RSET
+command.
+
+</ul>
+
+<p>
+Most of these limitations have been with the Postfix
+connection cache that is shared among multiple LMTP client
+programs.
+</p>
+
+%PARAM lmtp_sasl_auth_enable no
+
+<p>
+Enable SASL authentication in the Postfix LMTP client.
+</p>
+
+%PARAM lmtp_sasl_password_maps
+
+<p>
+Optional Postfix LMTP client lookup tables with one username:password entry
+per host or domain. If a remote host or domain has no username:password
+entry, then the Postfix LMTP client will not attempt to authenticate
+to the remote host.
+</p>
+
+%PARAM lmtp_sasl_security_options noplaintext, noanonymous
+
+<p> SASL security options; as of Postfix 2.3 the list of available
+features depends on the SASL client implementation that is selected
+with <b>lmtp_sasl_type</b>. </p>
+
+<p> The following security features are defined for the <b>cyrus</b>
+client SASL implementation: </p>
+
+<dl>
+
+<dt><b>noplaintext</b></dt>
+
+<dd>Disallow authentication methods that use plaintext passwords. </dd>
+
+<dt><b>noactive</b></dt>
+
+<dd>Disallow authentication methods that are vulnerable to non-dictionary
+active attacks. </dd>
+
+<dt><b>nodictionary</b></dt>
+
+<dd>Disallow authentication methods that are vulnerable to passive
+dictionary attacks. </dd>
+
+<dt><b>noanonymous</b></dt>
+
+<dd>Disallow anonymous logins. </dd>
+
+</dl>
+
+<p>
+Example:
+</p>
+
+<pre>
+lmtp_sasl_security_options = noplaintext
+</pre>
+
+%PARAM lmtp_tcp_port 24
+
+<p>
+The default TCP port that the Postfix LMTP client connects to.
+Specify a symbolic name (see services(5)) or a numeric port.
+</p>
+
+%PARAM smtp_tcp_port smtp
+
+<p>
+The default TCP port that the Postfix SMTP client connects to.
+Specify a symbolic name (see services(5)) or a numeric port.
+</p>
+
+%PARAM mail_release_date see "postconf -d" output
+
+<p>
+The Postfix release date, in "YYYYMMDD" format.
+</p>
+
+%PARAM mailbox_command_maps
+
+<p>
+Optional lookup tables with per-recipient external commands to use
+for local(8) mailbox delivery. Behavior is as with mailbox_command.
+</p>
+
+<p> The precedence of local(8) delivery features from high to low
+is: aliases, .forward files, mailbox_transport_maps, mailbox_transport,
+mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory,
+fallback_transport_maps, fallback_transport and luser_relay. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+%PARAM mailbox_delivery_lock see "postconf -d" output
+
+<p>
+How to lock a UNIX-style local(8) mailbox before attempting delivery.
+For a list of available file locking methods, use the "<b>postconf
+-l</b>" command.
+</p>
+
+<p>
+This setting is ignored with <b>maildir</b> style delivery,
+because such deliveries are safe without explicit locks.
+</p>
+
+<p>
+Note: The <b>dotlock</b> method requires that the recipient UID or
+GID has write access to the parent directory of the mailbox file.
+</p>
+
+<p>
+Note: the default setting of this parameter is system dependent.
+</p>
+
+%PARAM mailbox_transport
+
+<p>
+Optional message delivery transport that the local(8) delivery
+agent should use for mailbox delivery to all local recipients,
+whether or not they are found in the UNIX passwd database.
+</p>
+
+<p> The precedence of local(8) delivery features from high to low
+is: aliases, .forward files, mailbox_transport_maps, mailbox_transport,
+mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory,
+fallback_transport_maps, fallback_transport and luser_relay. </p>
+
+%PARAM mailq_path see "postconf -d" output
+
+<p>
+Sendmail compatibility feature that specifies where the Postfix
+mailq(1) command is installed. This command can be used to
+list the Postfix mail queue.
+</p>
+
+%PARAM manpage_directory see "postconf -d" output
+
+<p>
+Where the Postfix manual pages are installed.
+</p>
+
+%PARAM maps_rbl_domains
+
+<p>
+Obsolete feature: use the reject_rbl_client feature instead.
+</p>
+
+%PARAM mime_boundary_length_limit 2048
+
+<p>
+The maximal length of MIME multipart boundary strings. The MIME
+processor is unable to distinguish between boundary strings that
+do not differ in the first $mime_boundary_length_limit characters.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM mime_header_checks $header_checks
+
+<p>
+Optional lookup tables for content inspection of MIME related
+message headers, as described in the header_checks(5) manual page.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM mime_nesting_limit 100
+
+<p>
+The maximal recursion level that the MIME processor will handle.
+Postfix refuses mail that is nested deeper than the specified limit.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM mynetworks_style Postfix &ge; 3.0: host, Postfix &lt; 3.0: subnet
+
+<p>
+The method to generate the default value for the mynetworks parameter.
+This is the list of trusted networks for relay access control etc.
+</p>
+
+<ul>
+
+<li><p>Specify "mynetworks_style = host" when Postfix should
+"trust" only the local machine. </p>
+
+<li><p>Specify "mynetworks_style = subnet" when Postfix
+should "trust" remote SMTP clients in the same IP subnetworks as the local
+machine. On Linux, this works correctly only with interfaces
+specified with the "ifconfig" or "ip" command. </p>
+
+<li><p>Specify "mynetworks_style = class" when Postfix should
+"trust" remote SMTP clients in the same IP class A/B/C networks as the
+local machine. Caution: this may cause
+Postfix to "trust" your entire provider's network. Instead, specify
+an explicit mynetworks list by hand, as described with the mynetworks
+configuration parameter. </p>
+
+</ul>
+
+%PARAM nested_header_checks $header_checks
+
+<p>
+Optional lookup tables for content inspection of non-MIME message
+headers in attached messages, as described in the header_checks(5)
+manual page.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM newaliases_path see "postconf -d" output
+
+<p>
+Sendmail compatibility feature that specifies the location of the
+newaliases(1) command. This command can be used to rebuild the
+local(8) aliases(5) database.
+</p>
+
+%PARAM non_fqdn_reject_code 504
+
+<p>
+The numerical Postfix SMTP server reply code when a client request
+is rejected by the reject_non_fqdn_helo_hostname, reject_non_fqdn_sender
+or reject_non_fqdn_recipient restriction.
+</p>
+
+%PARAM owner_request_special yes
+
+<p>
+Enable special treatment for owner-<i>listname</i> entries in the
+aliases(5) file, and don't split owner-<i>listname</i> and
+<i>listname</i>-request address localparts when the recipient_delimiter
+is set to "-". This feature is useful for mailing lists.
+</p>
+
+%PARAM permit_mx_backup_networks
+
+<p>
+Restrict the use of the permit_mx_backup SMTP access feature to
+only domains whose primary MX hosts match the listed networks.
+The parameter value syntax is the same as with the mynetworks
+parameter; note, however, that the default value is empty. </p>
+
+<p> Pattern matching of domain names is controlled by the presence
+or absence of "permit_mx_backup_networks" in the
+parent_domain_matches_subdomains parameter value. </p>
+
+%PARAM pickup_service_name pickup
+
+<p>
+The name of the pickup(8) service. This service picks up local mail
+submissions from the Postfix maildrop queue.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM prepend_delivered_header command, file, forward
+
+<p> The message delivery contexts where the Postfix local(8) delivery
+agent prepends a Delivered-To: message header with the address
+that the mail was delivered to. This information is used for mail
+delivery loop detection. </p>
+
+<p>
+By default, the Postfix local delivery agent prepends a Delivered-To:
+header when forwarding mail and when delivering to file (mailbox)
+and command. Turning off the Delivered-To: header when forwarding
+mail is not recommended.
+</p>
+
+<p>
+Specify zero or more of <b>forward</b>, <b>file</b>, or <b>command</b>.
+</p>
+
+<p>
+Example:
+</p>
+
+<pre>
+prepend_delivered_header = forward
+</pre>
+
+%PARAM process_name read-only
+
+<p>
+The process name of a Postfix command or daemon process.
+</p>
+
+%PARAM service_name read-only
+
+<p> The master.cf service name of a Postfix daemon process. This
+can be used to distinguish the logging from different services that
+use the same program name. </p>
+
+<p> Example master.cf entries: </p>
+
+<pre>
+# Distinguish inbound MTA logging from submission and smtps logging.
+smtp inet n - n - - smtpd
+submission inet n - n - - smtpd
+ -o syslog_name=postfix/$service_name
+smtps inet n - n - - smtpd
+ -o syslog_name=postfix/$service_name
+</pre>
+
+<pre>
+# Distinguish outbound MTA logging from inbound relay logging.
+smtp unix - - n - - smtp
+relay unix - - n - - smtp
+ -o syslog_name=postfix/$service_name
+</pre>
+
+%PARAM process_id read-only
+
+<p>
+The process ID of a Postfix command or daemon process.
+</p>
+
+%PARAM process_id_directory pid
+
+<p>
+The location of Postfix PID files relative to $queue_directory.
+This is a read-only parameter.
+</p>
+
+%PARAM proxy_read_maps see "postconf -d" output
+
+<p>
+The lookup tables that the proxymap(8) server is allowed to
+access for the read-only service.
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma.
+Table references that don't begin with proxy: are ignored.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM proxy_write_maps see "postconf -d" output
+
+<p> The lookup tables that the proxymap(8) server is allowed to
+access for the read-write service. Postfix-owned local database
+files should be stored under the Postfix-owned data_directory.
+Table references that don't begin with proxy: are ignored. </p>
+
+<p>
+This feature is available in Postfix 2.5 and later.
+</p>
+
+%PARAM qmgr_clog_warn_time 300s
+
+<p>
+The minimal delay between warnings that a specific destination is
+clogging up the Postfix active queue. Specify 0 to disable.
+</p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is enabled with the helpful_warnings parameter.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM qmgr_fudge_factor 100
+
+<p>
+Obsolete feature: the percentage of delivery resources that a busy
+mail system will use up for delivery of a large mailing list
+message.
+</p>
+
+<p>
+This feature exists only in the oqmgr(8) old queue manager. The
+current queue manager solves the problem in a better way.
+</p>
+
+%PARAM queue_directory see "postconf -d" output
+
+<p>
+The location of the Postfix top-level queue directory. This is the
+root directory of Postfix daemon processes that run chrooted.
+</p>
+
+%PARAM queue_file_attribute_count_limit 100
+
+<p>
+The maximal number of (name=value) attributes that may be stored
+in a Postfix queue file. The limit is enforced by the cleanup(8)
+server.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM queue_service_name qmgr
+
+<p>
+The name of the qmgr(8) service. This service manages the Postfix
+queue and schedules delivery requests.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM html_directory see "postconf -d" output
+
+<p>
+The location of Postfix HTML files that describe how to build,
+configure or operate a specific Postfix subsystem or feature.
+</p>
+
+%PARAM readme_directory see "postconf -d" output
+
+<p>
+The location of Postfix README files that describe how to build,
+configure or operate a specific Postfix subsystem or feature.
+</p>
+
+%PARAM relay_transport relay
+
+<p>
+The default mail delivery transport and next-hop destination for
+remote delivery to domains listed with $relay_domains. In order of
+decreasing precedence, the nexthop destination is taken from
+$relay_transport, $sender_dependent_relayhost_maps, $relayhost, or
+from the recipient domain. This information can be overruled with
+the transport(5) table.
+</p>
+
+<p>
+Specify a string of the form <i>transport:nexthop</i>, where <i>transport</i>
+is the name of a mail delivery transport defined in master.cf.
+The <i>:nexthop</i> destination is optional; its syntax is documented
+in the manual page of the corresponding delivery agent.
+</p>
+
+<p>
+See also the relay domains address class in the ADDRESS_CLASS_README
+file.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM rewrite_service_name rewrite
+
+<p>
+The name of the address rewriting service. This service rewrites
+addresses to standard form and resolves them to a (delivery method,
+next-hop host, recipient) triple.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM sample_directory /etc/postfix
+
+<p>
+The name of the directory with example Postfix configuration files.
+Starting with Postfix 2.1, these files have been replaced with the
+postconf(5) manual page.
+</p>
+
+%PARAM sender_based_routing no
+
+<p>
+This parameter should not be used. It was replaced by sender_dependent_relayhost_maps
+in Postfix version 2.3.
+</p>
+
+%PARAM sendmail_path see "postconf -d" output
+
+<p>
+A Sendmail compatibility feature that specifies the location of
+the Postfix sendmail(1) command. This command can be used to
+submit mail into the Postfix queue.
+</p>
+
+%PARAM service_throttle_time 60s
+
+<p>
+How long the Postfix master(8) waits before forking a server that
+appears to be malfunctioning.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM setgid_group postdrop
+
+<p>
+The group ownership of set-gid Postfix commands and of group-writable
+Postfix directories. When this parameter value is changed you need
+to re-run "<b>postfix set-permissions</b>" (with Postfix version 2.0 and
+earlier: "<b>/etc/postfix/post-install set-permissions</b>".
+</p>
+
+%PARAM show_user_unknown_table_name yes
+
+<p>
+Display the name of the recipient table in the "User unknown"
+responses. The extra detail makes troubleshooting easier but also
+reveals information that is nobody else's business.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM showq_service_name showq
+
+<p>
+The name of the showq(8) service. This service produces mail queue
+status reports.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM smtp_pix_workaround_delay_time 10s
+
+<p>
+How long the Postfix SMTP client pauses before sending
+".&lt;CR&gt;&lt;LF&gt;" in order to work around the PIX firewall
+"&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;" bug.
+</p>
+
+<p>
+Choosing too short a time makes this workaround ineffective when
+sending large messages over slow network connections.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+%PARAM smtp_randomize_addresses yes
+
+<p>
+Randomize the order of equal-preference MX host addresses. This
+is a performance feature of the Postfix SMTP client.
+</p>
+
+%PARAM smtp_rset_timeout 20s
+
+<p> The Postfix SMTP client time limit for sending the RSET command,
+and for receiving the remote SMTP server response. The SMTP client
+sends RSET in
+order to finish a recipient address probe, or to verify that a
+cached session is still usable. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.1 and later. </p>
+
+%PARAM smtpd_data_restrictions
+
+<p>
+Optional access restrictions that the Postfix SMTP server applies
+in the context of the SMTP DATA command.
+See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access
+restriction lists" for a discussion of evaluation context and time.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+<p>
+Specify a list of restrictions, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace.
+Restrictions are applied in the order as specified; the first
+restriction that matches wins.
+</p>
+
+<p>
+The following restrictions are valid in this context:
+</p>
+
+<ul>
+
+<li><a href="#generic">Generic</a> restrictions that can be used
+in any SMTP command context, described under smtpd_client_restrictions.
+
+<li>SMTP command specific restrictions described under
+smtpd_client_restrictions, smtpd_helo_restrictions,
+smtpd_sender_restrictions or smtpd_recipient_restrictions.
+
+<li>However, no recipient information is available in the case of
+multi-recipient mail. Acting on only one recipient would be misleading,
+because any decision will affect all recipients equally. Acting on
+all recipients would require a possibly very large amount of memory,
+and would also be misleading for the reasons mentioned before.
+
+</ul>
+
+<p>
+Examples:
+</p>
+
+<pre>
+smtpd_data_restrictions = reject_unauth_pipelining
+smtpd_data_restrictions = reject_multi_recipient_bounce
+</pre>
+
+%PARAM smtpd_end_of_data_restrictions
+
+<p> Optional access restrictions that the Postfix SMTP server
+applies in the context of the SMTP END-OF-DATA command.
+See SMTPD_ACCESS_README, section "Delayed evaluation of SMTP access
+restriction lists" for a discussion of evaluation context and time.
+</p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+<p> See smtpd_data_restrictions for details and limitations. </p>
+
+%PARAM smtpd_delay_reject yes
+
+<p>
+Wait until the RCPT TO command before evaluating
+$smtpd_client_restrictions, $smtpd_helo_restrictions and
+$smtpd_sender_restrictions, or wait until the ETRN command before
+evaluating $smtpd_client_restrictions and $smtpd_helo_restrictions.
+</p>
+
+<p>
+This feature is turned on by default because some clients apparently
+mis-behave when the Postfix SMTP server rejects commands before
+RCPT TO.
+</p>
+
+<p>
+The default setting has one major benefit: it allows Postfix to log
+recipient address information when rejecting a client name/address
+or sender address, so that it is possible to find out whose mail
+is being rejected.
+</p>
+
+%PARAM smtpd_null_access_lookup_key &lt;&gt;
+
+<p>
+The lookup key to be used in SMTP access(5) tables instead of the
+null sender address.
+</p>
+
+%CLASS smtpd-policy SMTP server policy delegation
+
+<p>
+The Postfix SMTP server has a number of built-in mechanisms to
+block or accept mail at specific SMTP protocol stages. As of version
+2.1 Postfix can be configured to delegate policy decisions to an
+external server that runs outside Postfix. See the file
+SMTPD_POLICY_README for more information.
+</p>
+
+%PARAM smtpd_policy_service_max_idle 300s
+
+<p>
+The time after which an idle SMTPD policy service connection is
+closed.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtpd_policy_service_max_ttl 1000s
+
+<p>
+The time after which an active SMTPD policy service connection is
+closed.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtpd_policy_service_timeout 100s
+
+<p>
+The time limit for connecting to, writing to, or receiving from a
+delegated SMTPD policy server.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtpd_policy_service_request_limit 0
+
+<p>
+The maximal number of requests per SMTPD policy service connection,
+or zero (no limit). Once a connection reaches this limit, the
+connection is closed and the next request will be sent over a new
+connection. This is a workaround to avoid error-recovery delays
+with policy servers that cannot maintain a persistent connection.
+</p>
+
+<p>
+This feature is available in Postfix 3.0 and later.
+</p>
+
+%PARAM smtpd_reject_unlisted_recipient yes
+
+<p>
+Request that the Postfix SMTP server rejects mail for unknown
+recipient addresses, even when no explicit reject_unlisted_recipient
+access restriction is specified. This prevents the Postfix queue
+from filling up with undeliverable MAILER-DAEMON messages.
+</p>
+
+<p> An address is always considered "known" when it matches a
+virtual(5) alias or a canonical(5) mapping.
+
+<ul>
+
+<li> The recipient domain matches $mydestination, $inet_interfaces
+or $proxy_interfaces, but the recipient is not listed in
+$local_recipient_maps, and $local_recipient_maps is not null.
+
+<li> The recipient domain matches $virtual_alias_domains but the
+recipient is not listed in $virtual_alias_maps.
+
+<li> The recipient domain matches $virtual_mailbox_domains but the
+recipient is not listed in $virtual_mailbox_maps, and $virtual_mailbox_maps
+is not null.
+
+<li> The recipient domain matches $relay_domains but the recipient
+is not listed in $relay_recipient_maps, and $relay_recipient_maps
+is not null.
+
+</ul>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtpd_reject_unlisted_sender no
+
+<p> Request that the Postfix SMTP server rejects mail from unknown
+sender addresses, even when no explicit reject_unlisted_sender
+access restriction is specified. This can slow down an explosion
+of forged mail from worms or viruses. </p>
+
+<p> An address is always considered "known" when it matches a
+virtual(5) alias or a canonical(5) mapping.
+
+<ul>
+
+<li> The sender domain matches $mydestination, $inet_interfaces or
+$proxy_interfaces, but the sender is not listed in
+$local_recipient_maps, and $local_recipient_maps is not null.
+
+<li> The sender domain matches $virtual_alias_domains but the sender
+is not listed in $virtual_alias_maps.
+
+<li> The sender domain matches $virtual_mailbox_domains but the
+sender is not listed in $virtual_mailbox_maps, and $virtual_mailbox_maps
+is not null.
+
+<li> The sender domain matches $relay_domains but the sender is
+not listed in $relay_recipient_maps, and $relay_recipient_maps is
+not null.
+
+</ul>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM smtpd_restriction_classes
+
+<p>
+User-defined aliases for groups of access restrictions. The aliases
+can be specified in smtpd_recipient_restrictions etc., and on the
+right-hand side of a Postfix access(5) table.
+</p>
+
+<p>
+One major application is for implementing per-recipient UCE control.
+See the RESTRICTION_CLASS_README document for other examples.
+</p>
+
+%PARAM smtpd_sasl_application_name smtpd
+
+<p>
+The application name that the Postfix SMTP server uses for SASL
+server initialization. This
+controls the name of the SASL configuration file. The default value
+is <b>smtpd</b>, corresponding to a SASL configuration file named
+<b>smtpd.conf</b>.
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and 2.2. With Postfix 2.3
+it was renamed to smtpd_sasl_path.
+</p>
+
+%PARAM strict_7bit_headers no
+
+<p>
+Reject mail with 8-bit text in message headers. This blocks mail
+from poorly written applications.
+</p>
+
+<p>
+This feature should not be enabled on a general purpose mail server,
+because it is likely to reject legitimate email.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM strict_8bitmime no
+
+<p>
+Enable both strict_7bit_headers and strict_8bitmime_body.
+</p>
+
+<p>
+This feature should not be enabled on a general purpose mail server,
+because it is likely to reject legitimate email.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM strict_8bitmime_body no
+
+<p>
+Reject 8-bit message body text without 8-bit MIME content encoding
+information. This blocks mail from poorly written applications.
+</p>
+
+<p>
+Unfortunately, this also rejects majordomo approval requests when
+the included request contains valid 8-bit MIME mail, and it rejects
+bounces from mailers that do not MIME encapsulate 8-bit content
+(for example, bounces from qmail or from old versions of Postfix).
+</p>
+
+<p>
+This feature should not be enabled on a general purpose mail server,
+because it is likely to reject legitimate email.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM strict_mime_encoding_domain no
+
+<p>
+Reject mail with invalid Content-Transfer-Encoding: information
+for the message/* or multipart/* MIME content types. This blocks
+mail from poorly written software.
+</p>
+
+<p>
+This feature should not be enabled on a general purpose mail server,
+because it will reject mail after a single violation.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM sun_mailtool_compatibility no
+
+<p>
+Obsolete SUN mailtool compatibility feature. Instead, use
+"mailbox_delivery_lock = dotlock".
+</p>
+
+%PARAM trace_service_name trace
+
+<p>
+The name of the trace service. This service is implemented by the
+bounce(8) daemon and maintains a record
+of mail deliveries and produces a mail delivery report when verbose
+delivery is requested with "<b>sendmail -v</b>".
+</p>
+
+<p>
+This feature is available in Postfix 2.1 and later.
+</p>
+
+%PARAM undisclosed_recipients_header see "postconf -d" output
+
+<p>
+Message header that the Postfix cleanup(8) server inserts when a
+message contains no To: or Cc: message header. With Postfix 2.8
+and later, the default value is empty. With Postfix 2.4-2.7,
+specify an empty value to disable this feature. </p>
+
+<p> Example: </p>
+
+<pre>
+# Default value before Postfix 2.8.
+# Note: the ":" and ";" are both required.
+undisclosed_recipients_header = To: undisclosed-recipients:;
+</pre>
+
+%PARAM unknown_relay_recipient_reject_code 550
+
+<p>
+The numerical Postfix SMTP server reply code when a recipient
+address matches $relay_domains, and relay_recipient_maps specifies
+a list of lookup tables that does not match the recipient address.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM unknown_virtual_alias_reject_code 550
+
+<p>
+The Postfix SMTP server reply code when a recipient address matches
+$virtual_alias_domains, and $virtual_alias_maps specifies a list
+of lookup tables that does not match the recipient address.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM unknown_virtual_mailbox_reject_code 550
+
+<p>
+The Postfix SMTP server reply code when a recipient address matches
+$virtual_mailbox_domains, and $virtual_mailbox_maps specifies a list
+of lookup tables that does not match the recipient address.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM verp_delimiter_filter -=+
+
+<p>
+The characters Postfix accepts as VERP delimiter characters on the
+Postfix sendmail(1) command line and in SMTP commands.
+</p>
+
+<p>
+This feature is available in Postfix 1.1 and later.
+</p>
+
+%PARAM virtual_gid_maps
+
+<p>
+Lookup tables with the per-recipient group ID for virtual(8) mailbox
+delivery.
+</p>
+
+<p> This parameter is specific to the virtual(8) delivery agent.
+It does not apply when mail is delivered with a different mail
+delivery program. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p>
+In a lookup table, specify a left-hand side of "@domain.tld" to
+match any user in the specified domain that does not have a specific
+"user@domain.tld" entry.
+</p>
+
+<p>
+When a recipient address has an optional address extension
+(user+foo@domain.tld), the virtual(8) delivery agent looks up
+the full address first, and when the lookup fails, it looks up the
+unextended address (user@domain.tld).
+</p>
+
+<p>
+Note 1: for security reasons, the virtual(8) delivery agent disallows
+regular expression substitution of $1 etc. in regular expression
+lookup tables, because that would open a security hole.
+</p>
+
+<p>
+Note 2: for security reasons, the virtual(8) delivery agent will
+silently ignore requests to use the proxymap(8) server. Instead
+it will open the table directly. Before Postfix version 2.2, the
+virtual(8) delivery agent will terminate with a fatal error.
+</p>
+
+%PARAM virtual_mailbox_base
+
+<p>
+A prefix that the virtual(8) delivery agent prepends to all pathname
+results from $virtual_mailbox_maps table lookups. This is a safety
+measure to ensure that an out of control map doesn't litter the
+file system with mailboxes. While virtual_mailbox_base could be
+set to "/", this setting isn't recommended.
+</p>
+
+<p> This parameter is specific to the virtual(8) delivery agent.
+It does not apply when mail is delivered with a different mail
+delivery program. </p>
+
+<p>
+Example:
+</p>
+
+<pre>
+virtual_mailbox_base = /var/mail
+</pre>
+
+%PARAM virtual_mailbox_domains $virtual_mailbox_maps
+
+<p> Postfix is the final destination for the specified list of domains;
+mail is delivered via the $virtual_transport mail delivery transport.
+By default this is the Postfix virtual(8) delivery agent. The SMTP
+server validates recipient addresses with $virtual_mailbox_maps
+and rejects mail for non-existent recipients. See also the virtual
+mailbox domain class in the ADDRESS_CLASS_README file. </p>
+
+<p> This parameter expects the same syntax as the mydestination
+configuration parameter. </p>
+
+<p>
+This feature is available in Postfix 2.0 and later. The default
+value is backwards compatible with Postfix version 1.1.
+</p>
+
+%PARAM virtual_mailbox_limit 51200000
+
+<p>
+The maximal size in bytes of an individual virtual(8) mailbox or
+maildir file, or zero (no limit). </p>
+
+<p> This parameter is specific to the virtual(8) delivery agent.
+It does not apply when mail is delivered with a different mail
+delivery program. </p>
+
+%PARAM virtual_mailbox_lock see "postconf -d" output
+
+<p>
+How to lock a UNIX-style virtual(8) mailbox before attempting
+delivery. For a list of available file locking methods, use the
+"<b>postconf -l</b>" command.
+</p>
+
+<p> This parameter is specific to the virtual(8) delivery agent.
+It does not apply when mail is delivered with a different mail
+delivery program. </p>
+
+<p>
+This setting is ignored with <b>maildir</b> style delivery, because
+such deliveries are safe without application-level locks.
+</p>
+
+<p>
+Note 1: the <b>dotlock</b> method requires that the recipient UID
+or GID has write access to the parent directory of the recipient's
+mailbox file.
+</p>
+
+<p>
+Note 2: the default setting of this parameter is system dependent.
+</p>
+
+%PARAM virtual_mailbox_maps
+
+<p>
+Optional lookup tables with all valid addresses in the domains that
+match $virtual_mailbox_domains.
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p>
+In a lookup table, specify a left-hand side of "@domain.tld" to
+match any user in the specified domain that does not have a specific
+"user@domain.tld" entry.
+</p>
+
+<p>
+With the default "virtual_mailbox_domains = $virtual_mailbox_maps",
+lookup tables also need entries with a left-hand side of "domain.tld"
+to satisfy virtual_mailbox_domain lookups (the right-hand side is
+required but will not be used).
+</p>
+
+<p> The remainder of this text is specific to the virtual(8) delivery
+agent. It does not apply when mail is delivered with a different
+mail delivery program. </p>
+
+<p>
+The virtual(8) delivery agent uses this table to look up the
+per-recipient mailbox or maildir pathname. If the lookup result
+ends in a slash ("/"), maildir-style delivery is carried out,
+otherwise the path is assumed to specify a UNIX-style mailbox file.
+Note that $virtual_mailbox_base is unconditionally prepended to
+this path.
+</p>
+
+<p>
+When a recipient address has an optional address extension
+(user+foo@domain.tld), the virtual(8) delivery agent looks up
+the full address first, and when the lookup fails, it looks up the
+unextended address (user@domain.tld).
+</p>
+
+<p>
+Note 1: for security reasons, the virtual(8) delivery agent disallows
+regular expression substitution of $1 etc. in regular expression
+lookup tables, because that would open a security hole.
+</p>
+
+<p>
+Note 2: for security reasons, the virtual(8) delivery agent will
+silently ignore requests to use the proxymap(8) server. Instead
+it will open the table directly. Before Postfix version 2.2, the
+virtual(8) delivery agent will terminate with a fatal error.
+</p>
+
+%PARAM virtual_minimum_uid 100
+
+<p>
+The minimum user ID value that the virtual(8) delivery agent accepts
+as a result from $virtual_uid_maps table lookup. Returned
+values less than this will be rejected, and the message will be
+deferred.
+</p>
+
+<p> This parameter is specific to the virtual(8) delivery agent.
+It does not apply when mail is delivered with a different mail
+delivery program. </p>
+
+%PARAM virtual_transport virtual
+
+<p>
+The default mail delivery transport and next-hop destination for
+final delivery to domains listed with $virtual_mailbox_domains.
+This information can be overruled with the transport(5) table.
+</p>
+
+<p>
+Specify a string of the form <i>transport:nexthop</i>, where <i>transport</i>
+is the name of a mail delivery transport defined in master.cf.
+The <i>:nexthop</i> destination is optional; its syntax is documented
+in the manual page of the corresponding delivery agent.
+</p>
+
+<p>
+This feature is available in Postfix 2.0 and later.
+</p>
+
+%PARAM virtual_uid_maps
+
+<p>
+Lookup tables with the per-recipient user ID that the virtual(8)
+delivery agent uses while writing to the recipient's mailbox.
+</p>
+
+<p> This parameter is specific to the virtual(8) delivery agent.
+It does not apply when mail is delivered with a different mail
+delivery program. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p>
+In a lookup table, specify a left-hand side of "@domain.tld"
+to match any user in the specified domain that does not have a
+specific "user@domain.tld" entry.
+</p>
+
+<p>
+When a recipient address has an optional address extension
+(user+foo@domain.tld), the virtual(8) delivery agent looks up
+the full address first, and when the lookup fails, it looks up the
+unextended address (user@domain.tld).
+</p>
+
+<p>
+Note 1: for security reasons, the virtual(8) delivery agent disallows
+regular expression substitution of $1 etc. in regular expression
+lookup tables, because that would open a security hole.
+</p>
+
+<p>
+Note 2: for security reasons, the virtual(8) delivery agent will
+silently ignore requests to use the proxymap(8) server. Instead
+it will open the table directly. Before Postfix version 2.2, the
+virtual(8) delivery agent will terminate with a fatal error.
+</p>
+
+%PARAM config_directory see "postconf -d" output
+
+<p> The default location of the Postfix main.cf and master.cf
+configuration files. This can be overruled via the following
+mechanisms: </p>
+
+<ul>
+
+<li> <p> The MAIL_CONFIG environment variable (daemon processes
+and commands). </p>
+
+<li> <p> The "-c" command-line option (commands only). </p>
+
+</ul>
+
+<p> With Postfix commands that run with set-gid privileges, a
+config_directory override either requires root privileges, or it
+requires that the directory is listed with the alternate_config_directories
+parameter in the default main.cf file. </p>
+
+%PARAM virtual_maps
+
+<p> Optional lookup tables with a) names of domains for which all
+addresses are aliased to addresses in other local or remote domains,
+and b) addresses that are aliased to addresses in other local or
+remote domains. Available before Postfix version 2.0. With Postfix
+version 2.0 and later, this is replaced by separate controls: virtual_alias_domains
+and virtual_alias_maps. </p>
+
+%PARAM smtp_discard_ehlo_keywords
+
+<p> A case insensitive list of EHLO keywords (pipelining, starttls,
+auth, etc.) that the Postfix SMTP client will ignore in the EHLO
+response from a remote SMTP server. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent
+this action from being logged. </p>
+
+<li> <p> Use the smtp_discard_ehlo_keyword_address_maps feature to
+discard EHLO keywords selectively. </p>
+
+</ul>
+
+%PARAM smtpd_discard_ehlo_keywords
+
+<p> A case insensitive list of EHLO keywords (pipelining, starttls,
+auth, etc.) that the Postfix SMTP server will not send in the EHLO
+response
+to a remote SMTP client. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent
+this action from being logged. </p>
+
+<li> <p> Use the smtpd_discard_ehlo_keyword_address_maps feature
+to discard EHLO keywords selectively. </p>
+
+</ul>
+
+%PARAM smtp_discard_ehlo_keyword_address_maps
+
+<p> Lookup tables, indexed by the remote SMTP server address, with
+case insensitive lists of EHLO keywords (pipelining, starttls, auth,
+etc.) that the Postfix SMTP client will ignore in the EHLO response from a
+remote SMTP server. See smtp_discard_ehlo_keywords for details. The
+table is not indexed by hostname for consistency with
+smtpd_discard_ehlo_keyword_address_maps. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_discard_ehlo_keyword_address_maps
+
+<p> Lookup tables, indexed by the remote SMTP client address, with
+case insensitive lists of EHLO keywords (pipelining, starttls, auth,
+etc.) that the Postfix SMTP server will not send in the EHLO response
+to a
+remote SMTP client. See smtpd_discard_ehlo_keywords for details.
+The tables are not searched by hostname for robustness reasons. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM connection_cache_service_name scache
+
+<p> The name of the scache(8) connection cache service. This service
+maintains a limited pool of cached sessions. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM connection_cache_ttl_limit 2s
+
+<p> The maximal time-to-live value that the scache(8) connection
+cache server
+allows. Requests that specify a larger TTL will be stored with the
+maximum allowed TTL. The purpose of this additional control is to
+protect the infrastructure against careless people. The cache TTL
+is already bounded by $max_idle. </p>
+
+%PARAM connection_cache_status_update_time 600s
+
+<p> How frequently the scache(8) server logs usage statistics with
+connection cache hit and miss rates for logical destinations and for
+physical endpoints. </p>
+
+%PARAM remote_header_rewrite_domain
+
+<p> Don't rewrite message headers from remote clients at all when
+this parameter is empty; otherwise, rewrite message headers and
+append the specified domain name to incomplete addresses. The
+local_header_rewrite_clients parameter controls what clients Postfix
+considers local. </p>
+
+<p> Examples: </p>
+
+<p> The safe setting: append "domain.invalid" to incomplete header
+addresses from remote SMTP clients, so that those addresses cannot
+be confused with local addresses. </p>
+
+<blockquote>
+<pre>
+remote_header_rewrite_domain = domain.invalid
+</pre>
+</blockquote>
+
+<p> The default, purist, setting: don't rewrite headers from remote
+clients at all. </p>
+
+<blockquote>
+<pre>
+remote_header_rewrite_domain =
+</pre>
+</blockquote>
+
+%PARAM local_header_rewrite_clients permit_inet_interfaces
+
+<p> Rewrite message header addresses in mail from these clients and
+update incomplete addresses with the domain name in $myorigin or
+$mydomain; either don't rewrite message headers from other clients
+at all, or rewrite message headers and update incomplete addresses
+with the domain specified in the remote_header_rewrite_domain
+parameter. </p>
+
+<p> See the append_at_myorigin and append_dot_mydomain parameters
+for details of how domain names are appended to incomplete addresses.
+</p>
+
+<p> Specify a list of zero or more of the following: </p>
+
+<dl>
+
+<dt><b>permit_inet_interfaces</b></dt>
+
+<dd> Append the domain name in $myorigin or $mydomain when the
+client IP address matches $inet_interfaces. This is enabled by
+default. </dd>
+
+<dt><b>permit_mynetworks</b></dt>
+
+<dd> Append the domain name in $myorigin or $mydomain when the
+client IP address matches any network or network address listed in
+$mynetworks. This setting will not prevent remote mail header
+address rewriting when mail from a remote client is forwarded by
+a neighboring system. </dd>
+
+<dt><b>permit_sasl_authenticated </b></dt>
+
+<dd> Append the domain name in $myorigin or $mydomain when the
+client is successfully authenticated via the RFC 4954 (AUTH)
+protocol. </dd>
+
+<dt><b>permit_tls_clientcerts </b></dt>
+
+<dd> Append the domain name in $myorigin or $mydomain when the
+remote SMTP client TLS certificate fingerprint or public key fingerprint
+(Postfix 2.9 and later) is listed in $relay_clientcerts.
+The fingerprint digest algorithm is configurable via the
+smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to
+Postfix version 2.5). </dd>
+
+<dd> The default algorithm is <b>sha256</b> with Postfix &ge; 3.6
+and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix
+&le; 3.5, the default algorithm is <b>md5</b>. The best-practice
+algorithm is now <b>sha256</b>. Recent advances in hash function
+cryptanalysis have led to md5 and sha1 being deprecated in favor of
+sha256. However, as long as there are no known "second pre-image"
+attacks against the older algorithms, their use in this context, though
+not recommended, is still likely safe. </dd>
+
+<dt><b>permit_tls_all_clientcerts </b></dt>
+
+<dd> Append the domain name in $myorigin or $mydomain when the
+remote SMTP client TLS certificate is successfully verified, regardless of
+whether it is listed on the server, and regardless of the certifying
+authority. </dd>
+
+<dt><b><a name="check_address_map">check_address_map</a> <i><a href="DATABASE_README.html">type:table</a></i> </b></dt>
+
+<dt><b><i><a href="DATABASE_README.html">type:table</a></i> </b></dt>
+
+<dd> Append the domain name in $myorigin or $mydomain when the
+client IP address matches the specified lookup table.
+The lookup result is ignored, and no subnet lookup is done. This
+is suitable for, e.g., pop-before-smtp lookup tables. </dd>
+
+</dl>
+
+<p> Examples: </p>
+
+<p> The Postfix &lt; 2.2 backwards compatible setting: always rewrite
+message headers, and always append my own domain to incomplete
+header addresses. </p>
+
+<blockquote>
+<pre>
+local_header_rewrite_clients = static:all
+</pre>
+</blockquote>
+
+<p> The purist (and default) setting: rewrite headers only in mail
+from Postfix sendmail and in SMTP mail from this machine. </p>
+
+<blockquote>
+<pre>
+local_header_rewrite_clients = permit_inet_interfaces
+</pre>
+</blockquote>
+
+<p> The intermediate setting: rewrite header addresses and append
+$myorigin or $mydomain information only with mail from Postfix
+sendmail, from local clients, or from authorized SMTP clients. </p>
+
+<p> Note: this setting will not prevent remote mail header address
+rewriting when mail from a remote client is forwarded by a neighboring
+system. </p>
+
+<blockquote>
+<pre>
+local_header_rewrite_clients = permit_mynetworks,
+ permit_sasl_authenticated permit_tls_clientcerts
+ check_address_map hash:/etc/postfix/pop-before-smtp
+</pre>
+</blockquote>
+
+%PARAM smtpd_tls_cert_file
+
+<p> File with the Postfix SMTP server RSA certificate in PEM format.
+This file may also contain the Postfix SMTP server private RSA key.
+With Postfix &ge; 3.4 the preferred way to configure server keys and
+certificates is via the "smtpd_tls_chain_files" parameter. </p>
+
+<p> Public Internet MX hosts without certificates signed by a "reputable"
+CA must generate, and be prepared to present to most clients, a
+self-signed or private-CA signed certificate. The client will not be
+able to authenticate the server, but unless it is running Postfix 2.3 or
+similar software, it will still insist on a server certificate. </p>
+
+<p> For servers that are <b>not</b> public Internet MX hosts, Postfix
+supports configurations with no certificates. This entails the use of
+just the anonymous TLS ciphers, which are not supported by typical SMTP
+clients. Since some clients may not fall back to plain text after a TLS
+handshake failure, a certificate-less Postfix SMTP server will be unable
+to receive email from some TLS-enabled clients. To avoid accidental
+configurations with no certificates, Postfix enables certificate-less
+operation only when the administrator explicitly sets
+"smtpd_tls_cert_file = none". This ensures that new Postfix SMTP server
+configurations will not accidentally enable TLS without certificates. </p>
+
+<p> Note that server certificates are not optional in TLS 1.3. To run
+without certificates you'd have to disable the TLS 1.3 protocol by
+including '!TLSv1.3' in "smtpd_tls_protocols" and perhaps also
+"smtpd_tls_mandatory_protocols". It is simpler instead to just
+configure a certificate chain. Certificate-less operation is not
+recommended. <p>
+
+<p> Both RSA and DSA certificates are supported. When both types
+are present, the cipher used determines which certificate will be
+presented to the client. For Netscape and OpenSSL clients without
+special cipher choices the RSA certificate is preferred. </p>
+
+<p> To enable a remote SMTP client to verify the Postfix SMTP server
+certificate, the issuing CA certificates must be made available to the
+client. You should include the required certificates in the server
+certificate file, the server certificate first, then the issuing
+CA(s) (bottom-up order). </p>
+
+<p> Example: the certificate for "server.example.com" was issued by
+"intermediate CA" which itself has a certificate of "root CA".
+Create the server.pem file with "cat server_cert.pem intermediate_CA.pem
+root_CA.pem &gt; server.pem". </p>
+
+<p> If you also want to verify client certificates issued by these
+CAs, you can add the CA certificates to the smtpd_tls_CAfile, in which
+case it is not necessary to have them in the smtpd_tls_cert_file,
+smtpd_tls_dcert_file (obsolete) or smtpd_tls_eccert_file. </p>
+
+<p> A certificate supplied here must be usable as an SSL server certificate
+and hence pass the "openssl verify -purpose sslserver ..." test. </p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_cert_file = /etc/postfix/server.pem
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_key_file $smtpd_tls_cert_file
+
+<p> File with the Postfix SMTP server RSA private key in PEM format.
+This file may be combined with the Postfix SMTP server RSA certificate
+file specified with $smtpd_tls_cert_file. With Postfix &ge; 3.4 the
+preferred way to configure server keys and certificates is via the
+"smtpd_tls_chain_files" parameter. </p>
+
+<p> The private key must be accessible without a pass-phrase, i.e. it
+must not be encrypted. File permissions should grant read-only
+access to the system superuser account ("root"), and no access
+to anyone else. </p>
+
+%PARAM smtpd_tls_dcert_file
+
+<p> File with the Postfix SMTP server DSA certificate in PEM format.
+This file may also contain the Postfix SMTP server private DSA key.
+The DSA algorithm is obsolete and should not be used. </p>
+
+<p> See the discussion under smtpd_tls_cert_file for more details.
+</p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_dcert_file = /etc/postfix/server-dsa.pem
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_dkey_file $smtpd_tls_dcert_file
+
+<p> File with the Postfix SMTP server DSA private key in PEM format.
+This file may be combined with the Postfix SMTP server DSA certificate
+file specified with $smtpd_tls_dcert_file. The DSA algorithm is obsolete
+and should not be used. </p>
+
+<p> The private key must be accessible without a pass-phrase, i.e. it
+must not be encrypted. File permissions should grant read-only
+access to the system superuser account ("root"), and no access
+to anyone else. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_CAfile
+
+<p> A file containing (PEM format) CA certificates of root CAs trusted
+to sign either remote SMTP client certificates or intermediate CA
+certificates. These are loaded into memory before the smtpd(8) server
+enters the chroot jail. If the number of trusted roots is large, consider
+using smtpd_tls_CApath instead, but note that the latter directory must
+be present in the chroot jail if the smtpd(8) server is chrooted. This
+file may also be used to augment the server certificate trust chain,
+but it is best to include all the required certificates directly in the
+server certificate file. </p>
+
+<p> Specify "smtpd_tls_CAfile = /path/to/system_CA_file" to use ONLY
+the system-supplied default Certification Authority certificates.
+</p>
+
+<p> Specify "tls_append_default_CA = no" to prevent Postfix from
+appending the system-supplied default CAs and trusting third-party
+certificates. </p>
+
+<p> By default (see smtpd_tls_ask_ccert), client certificates are not
+requested, and smtpd_tls_CAfile should remain empty. If you do make use
+of client certificates, the distinguished names (DNs) of the Certification
+Authorities listed in smtpd_tls_CAfile are sent to the remote SMTP client
+in the client certificate request message. MUAs with multiple client
+certificates may use the list of preferred Certification Authorities
+to select the correct client certificate. You may want to put your
+"preferred" CA or CAs in this file, and install other trusted CAs in
+$smtpd_tls_CApath. </p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_CAfile = /etc/postfix/CAcert.pem
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_CApath
+
+<p> A directory containing (PEM format) CA certificates of root CAs
+trusted to sign either remote SMTP client certificates or intermediate CA
+certificates. Do not forget to create the necessary "hash" links with,
+for example, "$OPENSSL_HOME/bin/c_rehash /etc/postfix/certs". To use
+smtpd_tls_CApath in chroot mode, this directory (or a copy) must be
+inside the chroot jail. </p>
+
+<p> Specify "smtpd_tls_CApath = /path/to/system_CA_directory" to
+use ONLY the system-supplied default Certification Authority certificates.
+</p>
+
+<p> Specify "tls_append_default_CA = no" to prevent Postfix from
+appending the system-supplied default CAs and trusting third-party
+certificates. </p>
+
+<p> By default (see smtpd_tls_ask_ccert), client certificates are
+not requested, and smtpd_tls_CApath should remain empty. In contrast
+to smtpd_tls_CAfile, DNs of Certification Authorities installed
+in $smtpd_tls_CApath are not included in the client certificate
+request message. MUAs with multiple client certificates may use the
+list of preferred Certification Authorities to select the correct
+client certificate. You may want to put your "preferred" CA or
+CAs in $smtpd_tls_CAfile, and install the remaining trusted CAs in
+$smtpd_tls_CApath. </p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_CApath = /etc/postfix/certs
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_loglevel 0
+
+<p> Enable additional Postfix SMTP server logging of TLS activity.
+Each logging level also includes the information that is logged at
+a lower logging level. </p>
+
+<dl compact>
+
+<dt> </dt> <dd> 0 Disable logging of TLS activity. </dd>
+
+<dt> </dt> <dd> 1 Log only a summary message on TLS handshake completion
+&mdash; no logging of client certificate trust-chain verification errors
+if client certificate verification is not required. With Postfix 2.8 and
+earlier, log the summary message, peer certificate summary information
+and unconditionally log trust-chain verification errors. </dd>
+
+<dt> </dt> <dd> 2 Also log levels during TLS negotiation. </dd>
+
+<dt> </dt> <dd> 3 Also log hexadecimal and ASCII dump of TLS negotiation
+process. </dd>
+
+<dt> </dt> <dd> 4 Also log hexadecimal and ASCII dump of complete
+transmission after STARTTLS. </dd>
+
+</dl>
+
+<p> Do not use "smtpd_tls_loglevel = 2" or higher except in case
+of problems. Use of loglevel 4 is strongly discouraged. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_received_header no
+
+<p> Request that the Postfix SMTP server produces Received: message
+headers that include information about the protocol and cipher used,
+as well as the remote SMTP client CommonName and client certificate issuer
+CommonName. This is disabled by default, as the information may
+be modified in transit through other mail servers. Only information
+that was recorded by the final destination can be trusted. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_use_tls no
+
+<p> Opportunistic TLS: announce STARTTLS support to remote SMTP clients,
+but do not require that clients use TLS encryption. </p>
+
+<p> Note: when invoked via "<b>sendmail -bs</b>", Postfix will never offer
+STARTTLS due to insufficient privileges to access the server private
+key. This is intended behavior. </p>
+
+<p> This feature is available in Postfix 2.2 and later. With
+Postfix 2.3 and later use smtpd_tls_security_level instead. </p>
+
+%PARAM smtpd_enforce_tls no
+
+<p> Mandatory TLS: announce STARTTLS support to remote SMTP clients,
+and require that clients use TLS encryption. According to RFC 2487
+this MUST NOT be applied in case of a publicly-referenced SMTP
+server. This option is therefore off by default. </p>
+
+<p> Note 1: "smtpd_enforce_tls = yes" implies "smtpd_tls_auth_only = yes". </p>
+
+<p> Note 2: when invoked via "<b>sendmail -bs</b>", Postfix will never offer
+STARTTLS due to insufficient privileges to access the server private
+key. This is intended behavior. </p>
+
+<p> This feature is available in Postfix 2.2 and later. With
+Postfix 2.3 and later use smtpd_tls_security_level instead. </p>
+
+%PARAM smtpd_tls_wrappermode no
+
+<p> Run the Postfix SMTP server in TLS "wrapper" mode,
+instead of using the STARTTLS command. </p>
+
+<p> If you want to support this service, enable a special port in
+master.cf, and specify "-o smtpd_tls_wrappermode=yes" on the SMTP
+server's command line. Port 465 (submissions/smtps) is reserved for
+this purpose. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_ask_ccert no
+
+<p> Ask a remote SMTP client for a client certificate. This
+information is needed for certificate based mail relaying with,
+for example, the permit_tls_clientcerts feature. </p>
+
+<p> Some clients such as Netscape will either complain if no
+certificate is available (for the list of CAs in $smtpd_tls_CAfile)
+or will offer multiple client certificates to choose from. This
+may be annoying, so this option is "off" by default. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_req_ccert no
+
+<p> With mandatory TLS encryption, require a trusted remote SMTP client
+certificate in order to allow TLS connections to proceed. This
+option implies "smtpd_tls_ask_ccert = yes". </p>
+
+<p> When TLS encryption is optional, this setting is ignored with
+a warning written to the mail log. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_ccert_verifydepth 9
+
+<p> The verification depth for remote SMTP client certificates. A
+depth of 1 is sufficient if the issuing CA is listed in a local CA
+file. </p>
+
+<p> The default verification depth is 9 (the OpenSSL default) for
+compatibility with earlier Postfix behavior. Prior to Postfix 2.5,
+the default value was 5, but the limit was not actually enforced. If
+you have set this to a lower non-default value, certificates with longer
+trust chains may now fail to verify. Certificate chains with 1 or 2
+CAs are common, deeper chains are more rare and any number between 5
+and 9 should suffice in practice. You can choose a lower number if,
+for example, you trust certificates directly signed by an issuing CA
+but not any CAs it delegates to. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_auth_only no
+
+<p> When TLS encryption is optional in the Postfix SMTP server, do
+not announce or accept SASL authentication over unencrypted
+connections. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_session_cache_database
+
+<p> Name of the file containing the optional Postfix SMTP server
+TLS session cache. Specify a database type that supports enumeration,
+such as <b>btree</b> or <b>sdbm</b>; there is no need to support
+concurrent access. The file is created if it does not exist. The smtpd(8)
+daemon does not use this parameter directly, rather the cache is
+implemented indirectly in the tlsmgr(8) daemon. This means that
+per-smtpd-instance master.cf overrides of this parameter are not
+effective. Note that each of the cache databases supported by tlsmgr(8)
+daemon: $smtpd_tls_session_cache_database, $smtp_tls_session_cache_database
+(and with Postfix 2.3 and later $lmtp_tls_session_cache_database), needs to be
+stored separately. It is not at this time possible to store multiple
+caches in a single database. </p>
+
+<p> Note: <b>dbm</b> databases are not suitable. TLS
+session objects are too large. </p>
+
+<p> As of version 2.5, Postfix no longer uses root privileges when
+opening this file. The file should now be stored under the Postfix-owned
+data_directory. As a migration aid, an attempt to open the file
+under a non-Postfix directory is redirected to the Postfix-owned
+data_directory, and a warning is logged. </p>
+
+
+<p> As of Postfix 2.11 the preferred mechanism for session resumption
+is RFC 5077 TLS session tickets, which don't require server-side
+storage. Consequently, for Postfix &ge; 2.11 this parameter should
+generally be left empty. TLS session tickets require an OpenSSL
+library (at least version 0.9.8h) that provides full support for
+this TLS extension. See also smtpd_tls_session_cache_timeout. </p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_session_cache_database = btree:/var/lib/postfix/smtpd_scache
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_tls_session_cache_timeout 3600s
+
+<p> The expiration time of Postfix SMTP server TLS session cache
+information. A cache cleanup is performed periodically
+every $smtpd_tls_session_cache_timeout seconds. As with
+$smtpd_tls_session_cache_database, this parameter is implemented in the
+tlsmgr(8) daemon and therefore per-smtpd-instance master.cf overrides
+are not possible. </p>
+
+<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set
+&le; 0, session caching is disabled, not just via the database, but
+also via RFC 5077 TLS session tickets, which don't require server-side
+storage. If set to a positive value less than 2 minutes, the minimum
+value of 2 minutes is used instead. TLS session tickets require
+an OpenSSL library (at least version 0.9.8h) that provides full
+support for this TLS extension. </p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.2 and later, and updated
+for TLS session ticket support in Postfix 2.11. </p>
+
+%PARAM relay_clientcerts
+
+<p> List of tables with remote SMTP client-certificate fingerprints or
+public key fingerprints (Postfix 2.9 and later) for which the Postfix
+SMTP server will allow access with the permit_tls_clientcerts
+feature. The fingerprint digest algorithm is configurable via the
+smtpd_tls_fingerprint_digest parameter (hard-coded as md5 prior to
+Postfix version 2.5). </p>
+
+<p> The default algorithm is <b>sha256</b> with Postfix &ge; 3.6
+and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix
+&le; 3.5, the default algorithm is <b>md5</b>. The best-practice
+algorithm is now <b>sha256</b>. Recent advances in hash function
+cryptanalysis have led to md5 and sha1 being deprecated in favor of
+sha256. However, as long as there are no known "second pre-image"
+attacks against the older algorithms, their use in this context, though
+not recommended, is still likely safe. </p>
+
+<p> Postfix lookup tables are in the form of (key, value) pairs.
+Since we only need the key, the value can be chosen freely, e.g.
+the name of the user or host:
+D7:04:2F:A7:0B:8C:A5:21:FA:31:77:E1:41:8A:EE:80 lutzpc.at.home </p>
+
+<p> Example: </p>
+
+<pre>
+relay_clientcerts = hash:/etc/postfix/relay_clientcerts
+</pre>
+
+<p>For more fine-grained control, use check_ccert_access to select
+an appropriate access(5) policy for each client.
+See RESTRICTION_CLASS_README.</p>
+
+<p>This feature is available with Postfix version 2.2.</p>
+
+%PARAM smtpd_tls_cipherlist
+
+<p> Obsolete Postfix &lt; 2.3 control for the Postfix SMTP server TLS
+cipher list. It is easy to create interoperability problems by choosing
+a non-default cipher list. Do not use a non-default TLS cipherlist for
+MX hosts on the public Internet. Clients that begin the TLS handshake,
+but are unable to agree on a common cipher, may not be able to send any
+email to the SMTP server. Using a restricted cipher list may be more
+appropriate for a dedicated MSA or an internal mailhub, where one can
+exert some control over the TLS software and settings of the connecting
+clients. </p>
+
+<p> <b>Note:</b> do not use "" quotes around the parameter value. </p>
+
+<p>This feature is available with Postfix version 2.2. It is not used with
+Postfix 2.3 and later; use smtpd_tls_mandatory_ciphers instead. </p>
+
+%PARAM smtpd_tls_dh1024_param_file
+
+<p> File with DH parameters that the Postfix SMTP server should
+use with non-export EDH ciphers. </p>
+
+<p> With Postfix &ge; 3.7, built with OpenSSL version is 3.0.0 or later, if the
+parameter value is either empty or "<b>auto</b>", then the DH parameter
+selection is delegated to the OpenSSL library, which selects appropriate
+parameters based on the TLS handshake. This choice is likely to be the most
+interoperable with SMTP clients using various TLS libraries, and custom local
+parameters are no longer recommended when using Postfix &ge; 3.7 built against
+OpenSSL 3.0.0. </p>
+
+<p> The best-practice choice of parameters uses a 2048-bit prime. This is fine,
+despite the historical "1024" in the parameter name. Do not be tempted to use
+much larger values, performance degrades quickly, and you may also cease to
+interoperate with some mainstream SMTP clients. As of Postfix 3.1, the
+compiled-in default prime is 2048-bits, and it is not strictly necessary,
+though perhaps somewhat beneficial to generate custom DH parameters. </p>
+
+<p> Instead of using the exact same parameter sets as distributed
+with other TLS packages, it is more secure to generate your own
+set of parameters with something like the following commands: </p>
+
+<blockquote>
+<pre>
+openssl dhparam -out /etc/postfix/dh2048.pem 2048
+openssl dhparam -out /etc/postfix/dh1024.pem 1024
+# As of Postfix 3.6, export-grade 512-bit DH parameters are no longer
+# supported or needed.
+openssl dhparam -out /etc/postfix/dh512.pem 512
+</pre>
+</blockquote>
+
+<p> It is safe to share the same DH parameters between multiple
+Postfix instances. If you prefer, you can generate separate
+parameters for each instance. </p>
+
+<p> If you want to take maximal advantage of ciphers that offer <a
+href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see
+the <a href="FORWARD_SECRECY_README.html#quick-start">Getting
+started</a> section of <a
+href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The
+full document conveniently presents all information about Postfix
+"perfect" forward secrecy support in one place: what forward secrecy
+is, how to tweak settings, and what you can expect to see when
+Postfix uses ciphers with forward secrecy. </p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_dh1024_param_file = /etc/postfix/dh2048.pem
+</pre>
+
+<p>This feature is available in Postfix 2.2 and later.</p>
+
+%PARAM smtpd_tls_dh512_param_file
+
+<p> File with DH parameters that the Postfix SMTP server should
+use with export-grade EDH ciphers. The default SMTP server cipher
+grade is "medium" with Postfix releases after the middle of 2015,
+and as a result export-grade cipher suites are by default not used.
+</p>
+
+<p> With Postfix &ge; 3.6 export-grade Diffie-Hellman key exchange
+is no longer supported, and this parameter is silently ignored. </p>
+
+<p> See also the discussion under the smtpd_tls_dh1024_param_file
+configuration parameter. </p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_dh512_param_file = /etc/postfix/dh_512.pem
+</pre>
+
+<p>This feature is available in Postfix 2.2 and later,
+but is ignored in Postfix 3.6 and later.</p>
+
+%PARAM smtpd_starttls_timeout see "postconf -d" output
+
+<p> The time limit for Postfix SMTP server write and read operations
+during TLS startup and shutdown handshake procedures. The current
+default value is stress-dependent. Before Postfix version 2.8, it
+was fixed at 300s. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_cert_file
+
+<p> File with the Postfix SMTP client RSA certificate in PEM format.
+This file may also contain the Postfix SMTP client private RSA key, and
+these may be the same as the Postfix SMTP server RSA certificate and key
+file. With Postfix &ge; 3.4 the preferred way to configure client keys
+and certificates is via the "smtp_tls_chain_files" parameter. </p>
+
+<p> Do not configure client certificates unless you <b>must</b> present
+client TLS certificates to one or more servers. Client certificates are
+not usually needed, and can cause problems in configurations that work
+well without them. The recommended setting is to let the defaults stand: </p>
+
+<blockquote>
+<pre>
+smtp_tls_cert_file =
+smtp_tls_key_file =
+smtp_tls_eccert_file =
+smtp_tls_eckey_file =
+# Obsolete DSA parameters
+smtp_tls_dcert_file =
+smtp_tls_dkey_file =
+# Postfix &ge; 3.4 interface
+smtp_tls_chain_files =
+</pre>
+</blockquote>
+
+<p> The best way to use the default settings is to comment out the above
+parameters in main.cf if present. </p>
+
+<p> To enable remote SMTP servers to verify the Postfix SMTP client
+certificate, the issuing CA certificates must be made available to the
+server. You should include the required certificates in the client
+certificate file, the client certificate first, then the issuing
+CA(s) (bottom-up order). </p>
+
+<p> Example: the certificate for "client.example.com" was issued by
+"intermediate CA" which itself has a certificate issued by "root CA".
+As the "root" super-user create the client.pem file with: </p>
+
+<blockquote>
+<pre>
+# <b>umask 077</b>
+# <b>cat client_key.pem client_cert.pem intermediate_CA.pem &gt; chain.pem </b>
+</pre>
+</blockquote>
+
+<p> If you also want to verify remote SMTP server certificates issued by
+these CAs, you can add the CA certificates to the smtp_tls_CAfile, in
+which case it is not necessary to have them in the smtp_tls_cert_file,
+smtp_tls_dcert_file (obsolete) or smtp_tls_eccert_file. </p>
+
+<p> A certificate supplied here must be usable as an SSL client certificate
+and hence pass the "openssl verify -purpose sslclient ..." test. </p>
+
+<p> Example: </p>
+
+<pre>
+smtp_tls_cert_file = /etc/postfix/chain.pem
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_key_file $smtp_tls_cert_file
+
+<p> File with the Postfix SMTP client RSA private key in PEM format.
+This file may be combined with the Postfix SMTP client RSA certificate
+file specified with $smtp_tls_cert_file. With Postfix &ge; 3.4 the
+preferred way to configure client keys and certificates is via the
+"smtp_tls_chain_files" parameter. </p>
+
+<p> The private key must be accessible without a pass-phrase, i.e. it
+must not be encrypted. File permissions should grant read-only
+access to the system superuser account ("root"), and no access
+to anyone else. </p>
+
+<p> Example: </p>
+
+<pre>
+smtp_tls_key_file = $smtp_tls_cert_file
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_CAfile
+
+<p> A file containing CA certificates of root CAs trusted to sign
+either remote SMTP server certificates or intermediate CA certificates.
+These are loaded into memory before the smtp(8) client enters the
+chroot jail. If the number of trusted roots is large, consider using
+smtp_tls_CApath instead, but note that the latter directory must be
+present in the chroot jail if the smtp(8) client is chrooted. This
+file may also be used to augment the client certificate trust chain,
+but it is best to include all the required certificates directly in
+$smtp_tls_cert_file (or, Postfix &ge; 3.4 $smtp_tls_chain_files). </p>
+
+<p> Specify "smtp_tls_CAfile = /path/to/system_CA_file" to use
+ONLY the system-supplied default Certification Authority certificates.
+</p>
+
+<p> Specify "tls_append_default_CA = no" to prevent Postfix from
+appending the system-supplied default CAs and trusting third-party
+certificates. </p>
+
+<p> Example: </p>
+
+<pre>
+smtp_tls_CAfile = /etc/postfix/CAcert.pem
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_CApath
+
+<p> Directory with PEM format Certification Authority certificates
+that the Postfix SMTP client uses to verify a remote SMTP server
+certificate. Don't forget to create the necessary "hash" links
+with, for example, "$OPENSSL_HOME/bin/c_rehash /etc/postfix/certs".
+</p>
+
+<p> To use this option in chroot mode, this directory (or a copy)
+must be inside the chroot jail. </p>
+
+<p> Specify "smtp_tls_CApath = /path/to/system_CA_directory" to
+use ONLY the system-supplied default Certification Authority certificates.
+</p>
+
+<p> Specify "tls_append_default_CA = no" to prevent Postfix from
+appending the system-supplied default CAs and trusting third-party
+certificates. </p>
+
+<p> Example: </p>
+
+<pre>
+smtp_tls_CApath = /etc/postfix/certs
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_loglevel 0
+
+<p> Enable additional Postfix SMTP client logging of TLS activity.
+Each logging level also includes the information that is logged at
+a lower logging level. </p>
+
+<dl compact>
+
+<dt> </dt> <dd> 0 Disable logging of TLS activity. </dd>
+
+<dt> </dt> <dd> 1 Log only a summary message on TLS handshake completion
+&mdash; no logging of remote SMTP server certificate trust-chain
+verification errors if server certificate verification is not required.
+With Postfix 2.8 and earlier, log the summary message and unconditionally
+log trust-chain verification errors. </dd>
+
+<dt> </dt> <dd> 2 Also log levels during TLS negotiation. </dd>
+
+<dt> </dt> <dd> 3 Also log the hexadecimal and ASCII dump of the
+TLS negotiation process. </dd>
+
+<dt> </dt> <dd> 4 Also log the hexadecimal and ASCII dump of complete
+transmission after STARTTLS. </dd>
+
+</dl>
+
+<p> Do not use "smtp_tls_loglevel = 2" or higher except in case of
+problems. Use of loglevel 4 is strongly discouraged. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_session_cache_database
+
+<p> Name of the file containing the optional Postfix SMTP client
+TLS session cache. Specify a database type that supports enumeration,
+such as <b>btree</b> or <b>sdbm</b>; there is no need to support
+concurrent access. The file is created if it does not exist. The smtp(8)
+daemon does not use this parameter directly, rather the cache is
+implemented indirectly in the tlsmgr(8) daemon. This means that
+per-smtp-instance master.cf overrides of this parameter are not effective.
+Note that each of the cache databases supported by tlsmgr(8) daemon:
+$smtpd_tls_session_cache_database, $smtp_tls_session_cache_database
+(and with Postfix 2.3 and later $lmtp_tls_session_cache_database), needs to
+be stored separately. It is not at this time possible to store multiple
+caches in a single database. </p>
+
+<p> Note: <b>dbm</b> databases are not suitable. TLS
+session objects are too large. </p>
+
+<p> As of version 2.5, Postfix no longer uses root privileges when
+opening this file. The file should now be stored under the Postfix-owned
+data_directory. As a migration aid, an attempt to open the file
+under a non-Postfix directory is redirected to the Postfix-owned
+data_directory, and a warning is logged. </p>
+
+<p> Example: </p>
+
+<pre>
+smtp_tls_session_cache_database = btree:/var/lib/postfix/smtp_scache
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_session_cache_timeout 3600s
+
+<p> The expiration time of Postfix SMTP client TLS session cache
+information. A cache cleanup is performed periodically
+every $smtp_tls_session_cache_timeout seconds. As with
+$smtp_tls_session_cache_database, this parameter is implemented in the
+tlsmgr(8) daemon and therefore per-smtp-instance master.cf overrides
+are not possible. </p>
+
+<p> As of Postfix 2.11 this setting cannot exceed 100 days. If set
+&le; 0, session caching is disabled. If set to a positive value
+less than 2 minutes, the minimum value of 2 minutes is used instead. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_use_tls no
+
+<p> Opportunistic mode: use TLS when a remote SMTP server announces
+STARTTLS support, otherwise send the mail in the clear. Beware:
+some SMTP servers offer STARTTLS even if it is not configured. With
+Postfix &lt; 2.3, if the TLS handshake fails, and no other server is
+available, delivery is deferred and mail stays in the queue. If this
+is a concern for you, use the smtp_tls_per_site feature instead. </p>
+
+<p> This feature is available in Postfix 2.2 and later. With
+Postfix 2.3 and later use smtp_tls_security_level instead. </p>
+
+%PARAM smtp_enforce_tls no
+
+<p> Enforcement mode: require that remote SMTP servers use TLS
+encryption, and never send mail in the clear. This also requires
+that the remote SMTP server hostname matches the information in
+the remote server certificate, and that the remote SMTP server
+certificate was issued by a CA that is trusted by the Postfix SMTP
+client. If the certificate doesn't verify or the hostname doesn't
+match, delivery is deferred and mail stays in the queue. </p>
+
+<p> The server hostname is matched against all names provided as
+dNSNames in the SubjectAlternativeName. If no dNSNames are specified,
+the CommonName is checked. The behavior may be changed with the
+smtp_tls_enforce_peername option. </p>
+
+<p> This option is useful only if you are definitely sure that you
+will only connect to servers that support RFC 2487 _and_ that
+provide valid server certificates. Typical use is for clients that
+send all their email to a dedicated mailhub. </p>
+
+<p> This feature is available in Postfix 2.2 and later. With
+Postfix 2.3 and later use smtp_tls_security_level instead. </p>
+
+%PARAM smtp_tls_enforce_peername yes
+
+<p> With mandatory TLS encryption, require that the remote SMTP
+server hostname matches the information in the remote SMTP server
+certificate. As of RFC 2487 the requirements for hostname checking
+for MTA clients are not specified. </p>
+
+<p> This option can be set to "no" to disable strict peer name
+checking. This setting has no effect on sessions that are controlled
+via the smtp_tls_per_site table. </p>
+
+<p> Disabling the hostname verification can make sense in a closed
+environment where special CAs are created. If not used carefully,
+this option opens the danger of a "man-in-the-middle" attack (the
+CommonName of this attacker will be logged). </p>
+
+<p> This feature is available in Postfix 2.2 and later. With
+Postfix 2.3 and later use smtp_tls_security_level instead. </p>
+
+%PARAM smtp_tls_per_site
+
+<p> Optional lookup tables with the Postfix SMTP client TLS usage
+policy by next-hop destination and by remote SMTP server hostname.
+When both lookups succeed, the more specific per-site policy (NONE,
+MUST, etc.) overrides the less specific one (MAY), and the more secure
+per-site policy (MUST, etc.) overrides the less secure one (NONE).
+With Postfix 2.3 and later smtp_tls_per_site is strongly discouraged:
+use smtp_tls_policy_maps instead. </p>
+
+<p> Use of the bare hostname as the per-site table lookup key is
+discouraged. Always use the full destination nexthop (enclosed in
+[] with a possible ":port" suffix). A recipient domain or MX-enabled
+transport next-hop with no port suffix may look like a bare hostname,
+but is still a suitable <i>destination</i>. </p>
+
+<p> Specify a next-hop destination or server hostname on the left-hand
+side; no wildcards are allowed. The next-hop destination is either
+the recipient domain, or the destination specified with a transport(5)
+table, the relayhost parameter, or the relay_transport parameter.
+On the right hand side specify one of the following keywords: </p>
+
+<dl>
+
+<dt> NONE </dt> <dd> Don't use TLS at all. This overrides a less
+specific <b>MAY</b> lookup result from the alternate host or next-hop
+lookup key, and overrides the global smtp_use_tls, smtp_enforce_tls,
+and smtp_tls_enforce_peername settings. </dd>
+
+<dt> MAY </dt> <dd> Try to use TLS if the server announces support,
+otherwise use an unencrypted connection. This has less precedence
+than a more specific result (including <b>NONE</b>) from the alternate
+host or next-hop lookup key, and has less precedence than the more
+specific global "smtp_enforce_tls = yes" or "smtp_tls_enforce_peername
+= yes". </dd>
+
+<dt> MUST_NOPEERMATCH </dt> <dd> Require TLS encryption, but do not
+require that the remote SMTP server hostname matches the information
+in the remote SMTP server certificate, or that the server certificate
+was issued by a trusted CA. This overrides a less secure <b>NONE</b>
+or a less specific <b>MAY</b> lookup result from the alternate host
+or next-hop lookup key, and overrides the global smtp_use_tls,
+smtp_enforce_tls and smtp_tls_enforce_peername settings. </dd>
+
+<dt> MUST </dt> <dd> Require TLS encryption, require that the remote
+SMTP server hostname matches the information in the remote SMTP
+server certificate, and require that the remote SMTP server certificate
+was issued by a trusted CA. This overrides a less secure <b>NONE</b>
+or <b>MUST_NOPEERMATCH</b> or a less specific <b>MAY</b> lookup
+result from the alternate host or next-hop lookup key, and overrides
+the global smtp_use_tls, smtp_enforce_tls and smtp_tls_enforce_peername
+settings. </dd>
+
+</dl>
+
+<p> The above keywords correspond to the "none", "may", "encrypt" and
+"verify" security levels for the new smtp_tls_security_level parameter
+introduced in Postfix 2.3. Starting with Postfix 2.3, and independently
+of how the policy is specified, the smtp_tls_mandatory_ciphers and
+smtp_tls_mandatory_protocols parameters apply when TLS encryption
+is mandatory. Connections for which encryption is optional typically
+enable all "export" grade and better ciphers (see smtp_tls_ciphers
+and smtp_tls_protocols). </p>
+
+<p> As long as no secure DNS lookup mechanism is available, false
+hostnames in MX or CNAME responses can change the server hostname
+that Postfix uses for TLS policy lookup and server certificate
+verification. Even with a perfect match between the server hostname and
+the server certificate, there is no guarantee that Postfix is connected
+to the right server. See TLS_README (Closing a DNS loophole with obsolete
+per-site TLS policies) for a possible work-around. </p>
+
+<p> This feature is available in Postfix 2.2 and later. With
+Postfix 2.3 and later use smtp_tls_policy_maps instead. </p>
+
+%PARAM smtp_tls_scert_verifydepth 9
+
+<p> The verification depth for remote SMTP server certificates. A depth
+of 1 is sufficient if the issuing CA is listed in a local CA file. </p>
+
+<p> The default verification depth is 9 (the OpenSSL default) for
+compatibility with earlier Postfix behavior. Prior to Postfix 2.5,
+the default value was 5, but the limit was not actually enforced. If
+you have set this to a lower non-default value, certificates with longer
+trust chains may now fail to verify. Certificate chains with 1 or 2
+CAs are common, deeper chains are more rare and any number between 5
+and 9 should suffice in practice. You can choose a lower number if,
+for example, you trust certificates directly signed by an issuing CA
+but not any CAs it delegates to. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_note_starttls_offer no
+
+<p> Log the hostname of a remote SMTP server that offers STARTTLS,
+when TLS is not already enabled for that server. </p>
+
+<p> The logfile record looks like: </p>
+
+<pre>
+postfix/smtp[pid]: Host offered STARTTLS: [name.of.host]
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_cipherlist
+
+<p> Obsolete Postfix &lt; 2.3 control for the Postfix SMTP client TLS
+cipher list. As this feature applies to all TLS security levels, it is easy
+to create interoperability problems by choosing a non-default cipher
+list. Do not use a non-default TLS cipher list on hosts that deliver email
+to the public Internet: you will be unable to send email to servers that
+only support the ciphers you exclude. Using a restricted cipher list
+may be more appropriate for an internal MTA, where one can exert some
+control over the TLS software and settings of the peer servers. </p>
+
+<p> <b>Note:</b> do not use "" quotes around the parameter value. </p>
+
+<p> This feature is available in Postfix version 2.2. It is not used with
+Postfix 2.3 and later; use smtp_tls_mandatory_ciphers instead. </p>
+
+%PARAM smtp_starttls_timeout 300s
+
+<p> Time limit for Postfix SMTP client write and read operations
+during TLS startup and shutdown handshake procedures. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_dkey_file $smtp_tls_dcert_file
+
+<p> File with the Postfix SMTP client DSA private key in PEM format.
+This file may be combined with the Postfix SMTP client DSA certificate
+file specified with $smtp_tls_dcert_file. The DSA algorithm is obsolete
+and should not be used. </p>
+
+<p> The private key must be accessible without a pass-phrase, i.e. it
+must not be encrypted. File permissions should grant read-only
+access to the system superuser account ("root"), and no access
+to anyone else. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_tls_dcert_file
+
+<p> File with the Postfix SMTP client DSA certificate in PEM format.
+This file may also contain the Postfix SMTP client private DSA key.
+The DSA algorithm is obsolete and should not be used. </p>
+
+<p> See the discussion under smtp_tls_cert_file for more details.
+</p>
+
+<p> Example: </p>
+
+<pre>
+smtp_tls_dcert_file = /etc/postfix/client-dsa.pem
+</pre>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM tls_append_default_CA no
+
+<p> Append the system-supplied default Certification Authority
+certificates to the ones specified with *_tls_CApath or *_tls_CAfile.
+The default is "no"; this prevents Postfix from trusting third-party
+certificates and giving them relay permission with
+permit_tls_all_clientcerts. </p>
+
+<p> This feature is available in Postfix 2.4.15, 2.5.11, 2.6.8,
+2.7.2 and later versions. Specify "tls_append_default_CA = yes" for
+backwards compatibility, to avoid breaking certificate verification
+with sites that don't use permit_tls_all_clientcerts. </p>
+
+%PARAM tls_random_exchange_name see "postconf -d" output
+
+<p> Name of the pseudo random number generator (PRNG) state file
+that is maintained by tlsmgr(8). The file is created when it does
+not exist, and its length is fixed at 1024 bytes. </p>
+
+<p> As of version 2.5, Postfix no longer uses root privileges when
+opening this file, and the default file location was changed from
+${config_directory}/prng_exch to ${data_directory}/prng_exch. As
+a migration aid, an attempt to open the file under a non-Postfix
+directory is redirected to the Postfix-owned data_directory, and a
+warning is logged. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM tls_random_source see "postconf -d" output
+
+<p> The external entropy source for the in-memory tlsmgr(8) pseudo
+random number generator (PRNG) pool. Be sure to specify a non-blocking
+source. If this source is not a regular file, the entropy source
+type must be prepended: egd:/path/to/egd_socket for a source with
+EGD compatible socket interface, or dev:/path/to/device for a
+device file. </p>
+
+<p> Note: on OpenBSD systems specify dev:/dev/arandom when dev:/dev/urandom
+gives timeout errors. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM tls_random_bytes 32
+
+<p> The number of bytes that tlsmgr(8) reads from $tls_random_source
+when (re)seeding the in-memory pseudo random number generator (PRNG)
+pool. The default of 32 bytes (256 bits) is good enough for 128bit
+symmetric keys. If using EGD or a device file, a maximum of 255
+bytes is read. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM tls_random_reseed_period 3600s
+
+<p> The maximal time between attempts by tlsmgr(8) to re-seed the
+in-memory pseudo random number generator (PRNG) pool from external
+sources. The actual time between re-seeding attempts is calculated
+using the PRNG, and is between 0 and the time specified. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM tls_random_prng_update_period 3600s
+
+<p> The time between attempts by tlsmgr(8) to save the state of
+the pseudo random number generator (PRNG) to the file specified
+with $tls_random_exchange_name. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM tls_daemon_random_bytes 32
+
+<p> The number of pseudo-random bytes that an smtp(8) or smtpd(8)
+process requests from the tlsmgr(8) server in order to seed its
+internal pseudo random number generator (PRNG). The default of 32
+bytes (equivalent to 256 bits) is sufficient to generate a 128bit
+(or 168bit) session key. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_sasl_tls_security_options $smtp_sasl_security_options
+
+<p> The SASL authentication security options that the Postfix SMTP
+client uses for TLS encrypted SMTP sessions. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtpd_sasl_tls_security_options $smtpd_sasl_security_options
+
+<p> The SASL authentication security options that the Postfix SMTP
+server uses for TLS encrypted SMTP sessions. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM smtp_generic_maps
+
+<p> Optional lookup tables that perform address rewriting in the
+Postfix SMTP client, typically to transform a locally valid address into
+a globally valid address when sending mail across the Internet.
+This is needed when the local machine does not have its own Internet
+domain name, but uses something like <i>localdomain.local</i>
+instead. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> The table format and lookups are documented in generic(5);
+examples are shown in the ADDRESS_REWRITING_README and
+STANDARD_CONFIGURATION_README documents. </p>
+
+<p> This feature is available in Postfix 2.2 and later. </p>
+
+%PARAM message_reject_characters
+
+<p> The set of characters that Postfix will reject in message
+content. The usual C-like escape sequences are recognized: <tt>\a
+\b \f \n \r \t \v \<i>ddd</i></tt> (up to three octal digits) and
+<tt>\\</tt>. </p>
+
+<p> Note 1: this feature does not recognize text that requires MIME
+decoding. It inspects raw message content, just like header_checks
+and body_checks. </p>
+
+<p> Note 2: this feature is disabled with "receive_override_options
+= no_header_body_checks". </p>
+
+<p> Example: </p>
+
+<pre>
+message_reject_characters = \0
+</pre>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM message_strip_characters
+
+<p> The set of characters that Postfix will remove from message
+content. The usual C-like escape sequences are recognized: <tt>\a
+\b \f \n \r \t \v \<i>ddd</i></tt> (up to three octal digits) and
+<tt>\\</tt>. </p>
+
+<p> Note 1: this feature does not recognize text that requires MIME
+decoding. It inspects raw message content, just like header_checks
+and body_checks. </p>
+
+<p> Note 2: this feature is disabled with "receive_override_options
+= no_header_body_checks". </p>
+
+<p> Example: </p>
+
+<pre>
+message_strip_characters = \0
+</pre>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM frozen_delivered_to yes
+
+<p> Update the local(8) delivery agent's idea of the Delivered-To:
+address (see prepend_delivered_header) only once, at the start of
+a delivery attempt; do not update the Delivered-To: address while
+expanding aliases or .forward files. </p>
+
+<p> This feature is available in Postfix 2.3 and later. With older
+Postfix releases, the behavior is as if this parameter is set to
+"no". The old setting can be expensive with deeply nested aliases
+or .forward files. When an alias or .forward file changes the
+Delivered-To: address, it ties up one queue file and one cleanup
+process instance while mail is being forwarded. </p>
+
+%PARAM smtpd_peername_lookup yes
+
+<p> Attempt to look up the remote SMTP client hostname, and verify that
+the name matches the client IP address. A client name is set to
+"unknown" when it cannot be looked up or verified, or when name
+lookup is disabled. Turning off name lookup reduces delays due to
+DNS lookup and increases the maximal inbound delivery rate. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM delay_logging_resolution_limit 2
+
+<p> The maximal number of digits after the decimal point when logging
+sub-second delay values. Specify a number in the range 0..6. </p>
+
+<p> Large delay values are rounded off to an integral number of seconds;
+delay values below the delay_logging_resolution_limit are logged
+as "0", and delay values under 100s are logged with at most two-digit
+precision. </p>
+
+<p> The format of the "delays=a/b/c/d" logging is as follows: </p>
+
+<ul>
+
+<li> a = time from message arrival to last active queue entry
+
+<li> b = time from last active queue entry to connection setup
+
+<li> c = time in connection setup, including DNS, EHLO and STARTTLS
+
+<li> d = time in message transmission
+
+</ul>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM bounce_template_file
+
+<p> Pathname of a configuration file with bounce message templates.
+These override the built-in templates of delivery status notification
+(DSN) messages for undeliverable mail, delayed mail, successful
+delivery, or delivery verification. The bounce(5) manual page
+describes how to edit and test template files. </p>
+
+<p> Template message body text may contain $name references to
+Postfix configuration parameters. The result of $name expansion can
+be previewed with "<b>postconf -b <i>file_name</i></b>" before the file
+is placed into the Postfix configuration directory. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM sender_dependent_relayhost_maps
+
+<p> A sender-dependent override for the global relayhost parameter
+setting. The tables are searched by the envelope sender address and
+@domain. A lookup result of DUNNO terminates the search without
+overriding the global relayhost parameter setting (Postfix 2.6 and
+later). This information is overruled with relay_transport,
+sender_dependent_default_transport_maps, default_transport and with
+the transport(5) table. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> For safety reasons, this feature does not allow $number
+substitutions in regular expression maps. </p>
+
+<p>
+This feature is available in Postfix 2.3 and later.
+</p>
+
+%PARAM empty_address_relayhost_maps_lookup_key &lt;&gt;
+
+<p> The sender_dependent_relayhost_maps search string that will be
+used instead of the null sender address. </p>
+
+<p> This feature is available in Postfix 2.5 and later. With
+earlier versions, sender_dependent_relayhost_maps lookups were
+skipped for the null sender address. </p>
+
+%PARAM address_verify_sender_dependent_relayhost_maps $sender_dependent_relayhost_maps
+
+<p>
+Overrides the sender_dependent_relayhost_maps parameter setting for address
+verification probes.
+</p>
+
+<p>
+This feature is available in Postfix 2.3 and later.
+</p>
+
+%PARAM smtp_sender_dependent_authentication no
+
+<p>
+Enable sender-dependent authentication in the Postfix SMTP client; this is
+available only with SASL authentication, and disables SMTP connection
+caching to ensure that mail from different senders will use the
+appropriate credentials. </p>
+
+<p>
+This feature is available in Postfix 2.3 and later.
+</p>
+
+%PARAM lmtp_lhlo_name $myhostname
+
+<p>
+The hostname to send in the LMTP LHLO command.
+</p>
+
+<p>
+The default value is the machine hostname. Specify a hostname or
+[ip.add.re.ss] or [ip:v6:add:re::ss].
+</p>
+
+<p>
+This information can be specified in the main.cf file for all LMTP
+clients, or it can be specified in the master.cf file for a specific
+client, for example:
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ mylmtp ... lmtp -o lmtp_lhlo_name=foo.bar.com
+</pre>
+</blockquote>
+
+<p>
+This feature is available in Postfix 2.3 and later.
+</p>
+
+%PARAM lmtp_discard_lhlo_keyword_address_maps
+
+<p> Lookup tables, indexed by the remote LMTP server address, with
+case insensitive lists of LHLO keywords (pipelining, starttls,
+auth, etc.) that the Postfix LMTP client will ignore in the LHLO
+response
+from a remote LMTP server. See lmtp_discard_lhlo_keywords for
+details. The table is not indexed by hostname for consistency with
+smtpd_discard_ehlo_keyword_address_maps. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_discard_lhlo_keywords
+
+<p> A case insensitive list of LHLO keywords (pipelining, starttls,
+auth, etc.) that the Postfix LMTP client will ignore in the LHLO
+response
+from a remote LMTP server. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Specify the <b>silent-discard</b> pseudo keyword to prevent
+this action from being logged. </p>
+
+<li> <p> Use the lmtp_discard_lhlo_keyword_address_maps feature to
+discard LHLO keywords selectively. </p>
+
+</ul>
+
+%PARAM lmtp_lhlo_timeout 300s
+
+<p> The Postfix LMTP client time limit for sending the LHLO command,
+and for receiving the initial remote LMTP server response. </p>
+
+<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
+(weeks). The default time unit is s (seconds). </p>
+
+%PARAM lmtp_sasl_tls_security_options $lmtp_sasl_security_options
+
+<p> The LMTP-specific version of the smtp_sasl_tls_security_options
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_sasl_mechanism_filter
+
+<p> The LMTP-specific version of the smtp_sasl_mechanism_filter
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_bind_address
+
+<p> The LMTP-specific version of the smtp_bind_address configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_bind_address6
+
+<p> The LMTP-specific version of the smtp_bind_address6 configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_host_lookup dns
+
+<p> The LMTP-specific version of the smtp_host_lookup configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_connection_cache_destinations
+
+<p> The LMTP-specific version of the smtp_connection_cache_destinations
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_per_site
+
+<p> The LMTP-specific version of the smtp_tls_per_site configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_generic_maps
+
+<p> The LMTP-specific version of the smtp_generic_maps configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_pix_workaround_threshold_time 500s
+
+<p> The LMTP-specific version of the smtp_pix_workaround_threshold_time
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_pix_workaround_delay_time 10s
+
+<p> The LMTP-specific version of the smtp_pix_workaround_delay_time
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_connection_reuse_time_limit 300s
+
+<p> The LMTP-specific version of the smtp_connection_reuse_time_limit
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_starttls_timeout 300s
+
+<p> The LMTP-specific version of the smtp_starttls_timeout configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_line_length_limit 990
+
+<p> The LMTP-specific version of the smtp_line_length_limit
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_mx_address_limit 5
+
+<p> The LMTP-specific version of the smtp_mx_address_limit configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_mx_session_limit 2
+
+<p> The LMTP-specific version of the smtp_mx_session_limit configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_scert_verifydepth 9
+
+<p> The LMTP-specific version of the smtp_tls_scert_verifydepth
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_skip_5xx_greeting yes
+
+<p> The LMTP-specific version of the smtp_skip_5xx_greeting
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_randomize_addresses yes
+
+<p> The LMTP-specific version of the smtp_randomize_addresses
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_quote_rfc821_envelope yes
+
+<p> The LMTP-specific version of the smtp_quote_rfc821_envelope
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_defer_if_no_mx_address_found no
+
+<p> The LMTP-specific version of the smtp_defer_if_no_mx_address_found
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_connection_cache_on_demand yes
+
+<p> The LMTP-specific version of the smtp_connection_cache_on_demand
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_use_tls no
+
+<p> The LMTP-specific version of the smtp_use_tls configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_enforce_tls no
+
+<p> The LMTP-specific version of the smtp_enforce_tls configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_security_level
+
+<p> The LMTP-specific version of the smtp_tls_security_level configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_enforce_peername yes
+
+<p> The LMTP-specific version of the smtp_tls_enforce_peername
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_note_starttls_offer no
+
+<p> The LMTP-specific version of the smtp_tls_note_starttls_offer
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_sender_dependent_authentication no
+
+<p> The LMTP-specific version of the smtp_sender_dependent_authentication
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM connection_cache_protocol_timeout 5s
+
+<p> Time limit for connection cache connect, send or receive
+operations. The time limit is enforced in the client. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_sasl_type cyrus
+
+<p> The SASL plug-in type that the Postfix SMTP server should use
+for authentication. The available types are listed with the
+"<b>postconf -a</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_sasl_type cyrus
+
+<p> The SASL plug-in type that the Postfix SMTP client should use
+for authentication. The available types are listed with the
+"<b>postconf -A</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+
+%PARAM lmtp_sasl_type cyrus
+
+<p> The SASL plug-in type that the Postfix LMTP client should use
+for authentication. The available types are listed with the
+"<b>postconf -A</b>" command. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_sasl_path smtpd
+
+<p> Implementation-specific information that the Postfix SMTP server
+passes through to
+the SASL plug-in implementation that is selected with
+<b>smtpd_sasl_type</b>. Typically this specifies the name of a
+configuration file or rendezvous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. In earlier
+releases it was called <b>smtpd_sasl_application_name</b>. </p>
+
+%PARAM smtpd_sasl_service smtp
+
+<p> The service name that is passed to the SASL plug-in that is
+selected with <b>smtpd_sasl_type</b> and <b>smtpd_sasl_path</b>.
+</p>
+
+<p> This feature is available in Postfix 2.11 and later. Prior
+versions behave as if "<b>smtp</b>" is specified. </p>
+
+%PARAM smtpd_sasl_response_limit 12288
+
+<p> The maximum length of a SASL client's response to a server challenge.
+When the client's "initial response" is longer than the normal limit for
+SMTP commands, the client must omit its initial response, and wait for an
+empty server challenge; it can then send what would have been its "initial
+response" as a response to the empty server challenge. RFC4954 requires the
+server to accept client responses up to at least 12288 octets of
+base64-encoded text. The default value is therefore also the minimum value
+accepted for this parameter.</p>
+
+<p> This feature is available in Postfix 3.4 and later. Prior versions use
+"line_length_limit", which may need to be raised to accommodate larger client
+responses, as may be needed with GSSAPI authentication of Windows AD users
+who are members of many groups. </p>
+
+%PARAM cyrus_sasl_config_path
+
+<p> Search path for Cyrus SASL application configuration files,
+currently used only to locate the $smtpd_sasl_path.conf file.
+Specify zero or more directories separated by a colon character,
+or an empty value to use Cyrus SASL's built-in search path. </p>
+
+<p> This feature is available in Postfix 2.5 and later when compiled
+with Cyrus SASL 2.1.22 or later. </p>
+
+%PARAM smtp_sasl_path
+
+<p> Implementation-specific information that the Postfix SMTP client
+passes through to
+the SASL plug-in implementation that is selected with
+<b>smtp_sasl_type</b>. Typically this specifies the name of a
+configuration file or rendezvous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_sasl_path
+
+<p> Implementation-specific information that is passed through to
+the SASL plug-in implementation that is selected with
+<b>lmtp_sasl_type</b>. Typically this specifies the name of a
+configuration file or rendezvous point. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM plaintext_reject_code 450
+
+<p>
+The numerical Postfix SMTP server response code when a request
+is rejected by the <b>reject_plaintext_session</b> restriction.
+</p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM resolve_numeric_domain no
+
+<p> Resolve "user@ipaddress" as "user@[ipaddress]", instead of
+rejecting the address as invalid. </p>
+
+<p> This feature is available in Postfix 2.3 and later.
+
+%PARAM mailbox_transport_maps
+
+<p> Optional lookup tables with per-recipient message delivery
+transports to use for local(8) mailbox delivery, whether or not the
+recipients are found in the UNIX passwd database. </p>
+
+<p> The precedence of local(8) delivery features from high to low
+is: aliases, .forward files, mailbox_transport_maps, mailbox_transport,
+mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory,
+fallback_transport_maps, fallback_transport and luser_relay. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> For safety reasons, this feature does not allow $number
+substitutions in regular expression maps. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM fallback_transport_maps
+
+<p> Optional lookup tables with per-recipient message delivery
+transports for recipients that the local(8) delivery agent could
+not find in the aliases(5) or UNIX password database. </p>
+
+<p> The precedence of local(8) delivery features from high to low
+is: aliases, .forward files, mailbox_transport_maps, mailbox_transport,
+mailbox_command_maps, mailbox_command, home_mailbox, mail_spool_directory,
+fallback_transport_maps, fallback_transport and luser_relay. </p>
+
+<p> For safety reasons, this feature does not allow $number
+substitutions in regular expression maps. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_cname_overrides_servername version dependent
+
+<p> When the remote SMTP servername is a DNS CNAME, replace the
+servername with the result from CNAME expansion for the purpose of
+logging, SASL password lookup, TLS
+policy decisions, or TLS certificate verification. The value "no"
+hardens Postfix smtp_tls_per_site hostname-based policies against
+false hostname information in DNS CNAME records, and makes SASL
+password file lookups more predictable. This is the default setting
+as of Postfix 2.3. </p>
+
+<p> When DNS CNAME records are validated with secure DNS lookups
+(smtp_dns_support_level = dnssec), they are always allowed to
+override the above servername (Postfix 2.11 and later). </p>
+
+<p> This feature is available in Postfix 2.2.9 and later. </p>
+
+%PARAM lmtp_cname_overrides_servername yes
+
+<p> The LMTP-specific version of the smtp_cname_overrides_servername
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_sasl_tls_verified_security_options $smtp_sasl_tls_security_options
+
+<p> The SASL authentication security options that the Postfix SMTP
+client uses for TLS encrypted SMTP sessions with a verified server
+certificate. </p>
+
+<p> When mail is sent to the public MX host for the recipient's
+domain, server certificates are by default optional, and delivery
+proceeds even if certificate verification fails. For delivery via
+a submission service that requires SASL authentication, it may be
+appropriate to send plaintext passwords only when the connection
+to the server is strongly encrypted <b>and</b> the server identity
+is verified. </p>
+
+<p> The smtp_sasl_tls_verified_security_options parameter makes it
+possible to only enable plaintext mechanisms when a secure connection
+to the server is available. Submission servers subject to this
+policy must either have verifiable certificates or offer suitable
+non-plaintext SASL mechanisms. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM lmtp_sasl_tls_verified_security_options $lmtp_sasl_tls_security_options
+
+<p> The LMTP-specific version of the
+smtp_sasl_tls_verified_security_options configuration parameter.
+See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_connection_cache_time_limit 2s
+
+<p> The LMTP-specific version of the
+smtp_connection_cache_time_limit configuration parameter.
+See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_delay_open_until_valid_rcpt yes
+
+<p> Postpone the start of an SMTP mail transaction until a valid
+RCPT TO command is received. Specify "no" to create a mail transaction
+as soon as the Postfix SMTP server receives a valid MAIL FROM
+command. </p>
+
+<p> With sites that reject lots of mail, the default setting reduces
+the use of
+disk, CPU and memory resources. The downside is that rejected
+recipients are logged with NOQUEUE instead of a mail transaction
+ID. This complicates the logfile analysis of multi-recipient mail.
+</p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_cert_file
+
+<p> The LMTP-specific version of the smtp_tls_cert_file
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_key_file $lmtp_tls_cert_file
+
+<p> The LMTP-specific version of the smtp_tls_key_file
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_dcert_file
+
+<p> The LMTP-specific version of the smtp_tls_dcert_file
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_dkey_file $lmtp_tls_dcert_file
+
+<p> The LMTP-specific version of the smtp_tls_dkey_file
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_CAfile
+
+<p> The LMTP-specific version of the smtp_tls_CAfile
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_CApath
+
+<p> The LMTP-specific version of the smtp_tls_CApath
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_loglevel 0
+
+<p> The LMTP-specific version of the smtp_tls_loglevel
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_session_cache_database
+
+<p> The LMTP-specific version of the smtp_tls_session_cache_database
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_session_cache_timeout 3600s
+
+<p> The LMTP-specific version of the smtp_tls_session_cache_timeout
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_tls_policy_maps
+
+<p> Optional lookup tables with the Postfix SMTP client TLS security
+policy by next-hop destination; when a non-empty value is specified,
+this overrides the obsolete smtp_tls_per_site parameter. See
+TLS_README for a more detailed discussion of TLS security levels.
+</p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> The TLS policy table is indexed by the full next-hop destination,
+which is either the recipient domain, or the verbatim next-hop
+specified in the transport table, $local_transport, $virtual_transport,
+$relay_transport or $default_transport. This includes any enclosing
+square brackets and any non-default destination server port suffix. The
+LMTP socket type prefix (inet: or unix:) is not included in the lookup
+key. </p>
+
+<p> Only the next-hop domain, or $myhostname with LMTP over UNIX-domain
+sockets, is used as the nexthop name for certificate verification. The
+port and any enclosing square brackets are used in the table lookup key,
+but are not used for server name verification. </p>
+
+<p> When the lookup key is a domain name without enclosing square brackets
+or any <i>:port</i> suffix (typically the recipient domain), and the full
+domain is not found in the table, just as with the transport(5) table,
+the parent domain starting with a leading "." is matched recursively. This
+allows one to specify a security policy for a recipient domain and all
+its sub-domains. </p>
+
+<p> The lookup result is a security level, followed by an optional list
+of whitespace and/or comma separated name=value attributes that override
+related main.cf settings. The TLS security levels in order of increasing
+security are: </p>
+
+<dl>
+
+<dt><b><a href="TLS_README.html#client_tls_none">none</a></b></dt>
+<dd>No TLS. No additional attributes are supported at this level. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_may">may</a></b></dt>
+<dd>Opportunistic TLS. Since sending in the clear is acceptable,
+demanding stronger than default TLS security merely reduces
+interoperability. The optional "ciphers", "exclude", and "protocols"
+attributes (available for opportunistic TLS with Postfix &ge; 2.6)
+and "connection_reuse" attribute (Postfix &ge; 3.4) override the
+"smtp_tls_ciphers", "smtp_tls_exclude_ciphers", "smtp_tls_protocols",
+and
+"smtp_tls_connection_reuse" configuration parameters. In the policy table,
+multiple ciphers, protocols or excluded ciphers must be separated by colons,
+as attribute values may not contain whitespace or commas. When opportunistic
+TLS handshakes fail, Postfix retries the connection with TLS disabled.
+This allows mail delivery to sites with non-interoperable TLS
+implementations.</dd>
+
+<dt><b><a href="TLS_README.html#client_tls_encrypt">encrypt</a></b></dt>
+<dd>Mandatory TLS encryption. At this level
+and higher, the optional "protocols" attribute overrides the main.cf
+smtp_tls_mandatory_protocols parameter, the optional "ciphers" attribute
+overrides the main.cf smtp_tls_mandatory_ciphers parameter, the
+optional "exclude" attribute (Postfix &ge; 2.6) overrides the main.cf
+smtp_tls_mandatory_exclude_ciphers parameter, and the optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the
+main.cf smtp_tls_connection_reuse parameter. In the policy table,
+multiple ciphers, protocols or excluded ciphers must be separated by colons,
+as attribute values may not contain whitespace or commas. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_dane">dane</a></b></dt>
+<dd>Opportunistic DANE TLS. The TLS policy for the destination is
+obtained via TLSA records in DNSSEC. If no TLSA records are found,
+the effective security level used is <a
+href="TLS_README.html#client_tls_may">may</a>. If TLSA records are
+found, but none are usable, the effective security level is <a
+href="TLS_README.html#client_tls_encrypt">encrypt</a>. When usable
+TLSA records are obtained for the remote SMTP server, the
+server certificate must match the TLSA records. RFC 7672 (DANE)
+TLS authentication and DNSSEC support is available with Postfix
+2.11 and later. The optional "connection_reuse" attribute (Postfix
+&ge; 3.4) overrides the main.cf smtp_tls_connection_reuse parameter.
+When the effective security level used is <a
+href="TLS_README.html#client_tls_may">may</a>, the optional "ciphers",
+"exclude", and "protocols" attributes (Postfix &ge; 2.6) override the
+"smtp_tls_ciphers", "smtp_tls_exclude_ciphers", and "smtp_tls_protocols"
+configuration parameters.
+When the effective security level used is <a
+href="TLS_README.html#client_tls_encrypt">encrypt</a>, the optional "ciphers",
+"exclude", and "protocols" attributes (Postfix &ge; 2.6) override the
+"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
+"smtp_tls_mandatory_protocols" configuration parameters.
+</dd>
+
+<dt><b><a href="TLS_README.html#client_tls_dane">dane-only</a></b></dt>
+<dd>Mandatory DANE TLS. The TLS policy for the destination is
+obtained via TLSA records in DNSSEC. If no TLSA records are found,
+or none are usable, no connection is made to the server. When
+usable TLSA records are obtained for the remote SMTP server, the
+server certificate must match the TLSA records. RFC 7672 (DANE) TLS
+authentication and DNSSEC support is available with Postfix 2.11
+and later. The optional "ciphers", "exclude", and "protocols" attributes
+(Postfix &ge; 2.6) override the "smtp_tls_mandatory_ciphers",
+"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+configuration parameters. The optional "connection_reuse" attribute
+(Postfix &ge; 3.4) overrides the main.cf smtp_tls_connection_reuse parameter.
+</dd>
+
+<dt><b><a href="TLS_README.html#client_tls_fprint">fingerprint</a></b></dt>
+<dd>Certificate fingerprint
+verification. Available with Postfix 2.5 and later. At this security
+level, there are no trusted Certification Authorities. The certificate
+trust chain, expiration date, ... are not checked. Instead,
+the optional "match" attribute, or else the main.cf
+<b>smtp_tls_fingerprint_cert_match</b> parameter, lists the certificate
+fingerprints or the public key fingerprint (Postfix 2.9 and later)
+of the valid server certificate. The digest
+algorithm used to calculate the fingerprint is selected by the
+<b>smtp_tls_fingerprint_digest</b> parameter. Multiple fingerprints can
+be combined with a "|" delimiter in a single match attribute, or multiple
+match attributes can be employed. The ":" character is not used as a
+delimiter as it occurs between each pair of fingerprint (hexadecimal)
+digits. The optional "ciphers", "exclude", and "protocols" attributes
+(Postfix &ge; 2.6) override the "smtp_tls_mandatory_ciphers",
+"smtp_tls_mandatory_exclude_ciphers", and "smtp_tls_mandatory_protocols"
+configuration parameters. The optional "connection_reuse" attribute
+(Postfix &ge; 3.4) overrides the main.cf smtp_tls_connection_reuse
+parameter. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_verify">verify</a></b></dt>
+<dd>Mandatory TLS verification. At this security
+level, DNS MX lookups are trusted to be secure enough, and the name
+verified in the server certificate is usually obtained indirectly via
+unauthenticated DNS MX lookups. The optional "match" attribute overrides
+the main.cf smtp_tls_verify_cert_match parameter. In the policy table,
+multiple match patterns and strategies must be separated by colons.
+In practice explicit control over matching is more common with the
+"secure" policy, described below. The optional "ciphers", "exclude",
+and "protocols" attributes (Postfix &ge; 2.6) override the
+"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
+"smtp_tls_mandatory_protocols" configuration parameters. The optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_secure">secure</a></b></dt>
+<dd>Secure-channel TLS. At this security level, DNS
+MX lookups, though potentially used to determine the candidate next-hop
+gateway IP addresses, are <b>not</b> trusted to be secure enough for TLS
+peername verification. Instead, the default name verified in the server
+certificate is obtained directly from the next-hop, or is explicitly
+specified via the optional "match" attribute which overrides the
+main.cf smtp_tls_secure_cert_match parameter. In the policy table,
+multiple match patterns and strategies must be separated by colons.
+The match attribute is most useful when multiple domains are supported by
+a common server: the policy entries for additional domains specify matching
+rules for the primary domain certificate. While transport table overrides
+that route the secondary domains to the primary nexthop also allow secure
+verification, they risk delivery to the wrong destination when domains
+change hands or are re-assigned to new gateways. With the "match"
+attribute approach, routing is not perturbed, and mail is deferred if
+verification of a new MX host fails. The optional "ciphers", "exclude",
+and "protocols" attributes (Postfix &ge; 2.6) override the
+"smtp_tls_mandatory_ciphers", "smtp_tls_mandatory_exclude_ciphers", and
+"smtp_tls_mandatory_protocols" configuration parameters. The optional
+"connection_reuse" attribute (Postfix &ge; 3.4) overrides the main.cf
+smtp_tls_connection_reuse parameter. </dd>
+
+</dl>
+
+<p>
+Example:
+</p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+ # Postfix 2.5 and later.
+ #
+ # The default digest is sha256 with Postfix &ge; 3.6 and
+ # compatibility level &ge; 3.
+ #
+ smtp_tls_fingerprint_digest = sha256
+</pre>
+
+<pre>
+/etc/postfix/tls_policy:
+ example.edu none
+ example.mil may
+ example.gov encrypt protocols=TLSv1
+ example.com verify ciphers=high
+ example.net secure
+ .example.net secure match=.example.net:example.net
+ [mail.example.org]:587 secure match=nexthop
+ # Postfix 2.5 and later
+ [thumb.example.org] fingerprint
+ match=b6:b4:72:34:e2:59:cd:...:c2:ca:63:0d:4d:cc:2c:7d:84:de:e6:2f
+ match=51:e9:af:2e:1e:40:1f:...:64:0a:30:35:2d:09:16:31:5a:eb:82:76
+</pre>
+
+<p> <b>Note:</b> The "hostname" strategy if listed in a non-default
+setting of smtp_tls_secure_cert_match or in the "match" attribute
+in the policy table can render the "secure" level vulnerable to
+DNS forgery. Do not use the "hostname" strategy for secure-channel
+configurations in environments where DNS security is not assured. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_tls_mandatory_protocols see "postconf -d" output
+
+<p> TLS protocols that the Postfix SMTP client will use with mandatory
+TLS encryption. In main.cf the values are separated by whitespace,
+commas or colons. In the policy table "protocols" attribute (see
+smtp_tls_policy_maps) the only valid separator is colon. An empty value
+means allow all protocols. </p>
+
+<p> The valid protocol names (see SSL_get_version(3)) are "SSLv2",
+"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" and "TLSv1.3". Starting with
+Postfix 3.6, the default value is "&gt;=TLSv1", which sets TLS 1.0 as
+the lowest supported TLS protocol version (see below). Older releases
+use the "!" exclusion syntax, also described below. </p>
+
+<p> As of Postfix 3.6, the preferred way to limit the range of
+acceptable protocols is to set a lowest acceptable TLS protocol version
+and/or a highest acceptable TLS protocol version. To set the lower
+bound include an element of the form: "&gt;=<i>version</i>" where
+<i>version</i> is a either one of the TLS protocol names listed above,
+or a hexadecimal number corresponding to the desired TLS protocol
+version (0301 for TLS 1.0, 0302 for TLS 1.1, etc.). For the upper
+bound, use "&lt;=<i>version</i>". There must be no whitespace between
+the "&gt;=" or "&lt;=" symbols and the protocol name or number. </p>
+
+<p> Hexadecimal protocol numbers make it possible to specify protocol
+bounds for TLS versions that are known to OpenSSL, but might not be
+known to Postfix. They cannot be used with the legacy exclusion syntax.
+Leading "0" or "0x" prefixes are supported, but not required.
+Therefore, "301", "0301", "0x301" and "0x0301" are all equivalent to
+"TLSv1". Hexadecimal versions unknown to OpenSSL will fail to set the
+upper or lower bound, and a warning will be logged. Hexadecimal
+versions should only be used when Postfix is linked with some future
+version of OpenSSL that supports TLS 1.4 or later, but Postfix does not
+yet support a symbolic name for that protocol version. </p>
+
+<p>Hexadecimal example (Postfix &ge; 3.6):</p>
+<blockquote>
+<pre>
+# Allow only TLS 1.2 through (hypothetical) TLS 1.4, once supported
+# in some future version of OpenSSL (presently a warning is logged).
+smtp_tls_mandatory_protocols = &gt;=TLSv1.2, &lt;=0305
+# Allow only TLS 1.2 and up:
+smtp_tls_mandatory_protocols = &gt;=0x0303
+</pre>
+</blockquote>
+
+<p> With Postfix &lt; 3.6 there is no support for a minimum or maximum
+version, and the protocol range is configured via protocol exclusions.
+To require at least TLS 1.0, set "smtp_tls_mandatory_protocols = !SSLv2,
+!SSLv3". Listing the protocols to include, rather than the protocols to
+exclude, is supported, but not recommended. The exclusion syntax more
+accurately matches the underlying OpenSSL interface. </p>
+
+<p> When using the exclusion syntax, take care to ensure that the range
+of protocols supported by the Postfix SMTP client is contiguous. When
+a protocol version is enabled, disabling any higher version implicitly
+disables all versions above that higher version. Thus, for example: </p>
+
+<blockquote>
+<pre>
+smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1.1
+</pre>
+</blockquote>
+
+<p> also disables any protocol versions higher than TLSv1.1 leaving
+only "TLSv1" enabled. </p>
+
+<p> Support for "TLSv1.3" was introduced in OpenSSL 1.1.1. Disabling
+this protocol via "!TLSv1.3" is supported since Postfix 3.4 (or patch
+releases &ge; 3.0.14, 3.1.10, 3.2.7 and 3.3.2). </p>
+
+<p> While the vast majority of SMTP servers with DANE TLSA records now
+support at least TLS 1.2, a few still only support TLS 1.0. If you use
+"dane" or "dane-only" it is best not to disable TLSv1, except perhaps
+via the policy table for destinations which you are sure will support
+"TLSv1.2". </p>
+
+<p> See the documentation of the smtp_tls_policy_maps parameter and
+TLS_README for more information about security levels. </p>
+
+<p> Example: </p>
+<pre>
+# Preferred syntax with Postfix &ge; 3.6:
+smtp_tls_mandatory_protocols = &gt;=TLSv1.2, &lt;=TLSv1.3
+# Legacy syntax:
+smtp_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+</pre>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_tls_verify_cert_match hostname
+
+<p> How the Postfix SMTP client verifies the server certificate
+peername for the
+"verify" TLS security level. In a "verify" TLS policy table
+($smtp_tls_policy_maps) entry the optional "match" attribute
+overrides this main.cf setting. </p>
+
+<p> This parameter specifies one or more patterns or strategies separated
+by commas, whitespace or colons. In the policy table the only valid
+separator is the colon character. </p>
+
+<p> Patterns specify domain names, or domain name suffixes: </p>
+
+<dl>
+
+<dt><i>example.com</i></dt> <dd> Match the <i>example.com</i> domain,
+i.e. one of the names in the server certificate must be <i>example.com</i>.
+Upper and lower case distinctions are ignored. </dd>
+
+<dt><i>.example.com</i></dt>
+<dd> Match subdomains of the <i>example.com</i> domain, i.e. match
+a name in the server certificate that consists of a non-zero number of
+labels followed by a <i>.example.com</i> suffix. Case distinctions are
+ignored.</dd>
+
+</dl>
+
+<p> Strategies specify a transformation from the next-hop domain
+to the expected name in the server certificate: </p>
+
+<dl>
+
+<dt>nexthop</dt>
+<dd> Match against the next-hop domain, which is either the recipient
+domain, or the transport next-hop configured for the domain stripped of
+any optional socket type prefix, enclosing square brackets and trailing
+port. When MX lookups are not suppressed, this is the original nexthop
+domain prior to the MX lookup, not the result of the MX lookup. For
+LMTP delivery via UNIX-domain sockets, the verified next-hop name is
+$myhostname. This strategy is suitable for use with the "secure"
+policy. Case is ignored.</dd>
+
+<dt>dot-nexthop</dt>
+<dd> As above, but match server certificate names that are subdomains
+of the next-hop domain. Case is ignored.</dd>
+
+<dt>hostname</dt> <dd> Match against the hostname of the server, often
+obtained via an unauthenticated DNS MX lookup. For LMTP delivery via
+UNIX-domain sockets, the verified name is $myhostname. This matches
+the verification strategy of the "MUST" keyword in the obsolete
+smtp_tls_per_site table, and is suitable for use with the "verify"
+security level. When the next-hop name is enclosed in square brackets
+to suppress MX lookups, the "hostname" strategy is the same as the
+"nexthop" strategy. Case is ignored.</dd>
+
+</dl>
+
+<p>
+Sample main.cf setting:
+</p>
+
+<pre>
+smtp_tls_verify_cert_match = hostname, nexthop, dot-nexthop
+</pre>
+
+<p>
+Sample policy table override:
+</p>
+
+<pre>
+example.com verify match=hostname:nexthop
+.example.com verify match=example.com:.example.com:hostname
+</pre>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_tls_secure_cert_match nexthop, dot-nexthop
+
+<p> How the Postfix SMTP client verifies the server certificate
+peername for the "secure" TLS security level. In a "secure" TLS policy table
+($smtp_tls_policy_maps) entry the optional "match" attribute
+overrides this main.cf setting. </p>
+
+<p> This parameter specifies one or more patterns or strategies separated
+by commas, whitespace or colons. In the policy table the only valid
+separator is the colon character. </p>
+
+<p> For a description of the pattern and strategy syntax see the
+smtp_tls_verify_cert_match parameter. The "hostname" strategy should
+be avoided in this context, as in the absence of a secure global DNS, using
+the results of MX lookups in certificate verification is not immune to active
+(man-in-the-middle) attacks on DNS. </p>
+
+<p>
+Sample main.cf setting:
+</p>
+
+<blockquote>
+<pre>
+smtp_tls_secure_cert_match = nexthop
+</pre>
+</blockquote>
+
+<p>
+Sample policy table override:
+</p>
+
+<blockquote>
+<pre>
+example.net secure match=example.com:.example.com
+.example.net secure match=example.com:.example.com
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_policy_maps
+
+<p> The LMTP-specific version of the smtp_tls_policy_maps
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_mandatory_protocols see postconf -d output
+
+<p> The LMTP-specific version of the smtp_tls_mandatory_protocols
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_verify_cert_match hostname
+
+<p> The LMTP-specific version of the smtp_tls_verify_cert_match
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_secure_cert_match nexthop
+
+<p> The LMTP-specific version of the smtp_tls_secure_cert_match
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_tls_mandatory_protocols see "postconf -d" output
+
+<p> TLS protocols accepted by the Postfix SMTP server with mandatory TLS
+encryption. If the list is empty, the server supports all available TLS
+protocol versions. A non-empty value is a list of protocol names to
+include or exclude, separated by whitespace, commas or colons. </p>
+
+<p> The valid protocol names (see SSL_get_version(3)) are "SSLv2",
+"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" and "TLSv1.3". Starting with
+Postfix 3.6, the default value is "&gt;=TLSv1", which sets TLS 1.0 as
+the lowest supported TLS protocol version (see below). Older releases
+use the "!" exclusion syntax, also described below. </p>
+
+<p> As of Postfix 3.6, the preferred way to limit the range of
+acceptable protocols is to set the lowest acceptable TLS protocol
+version and/or the highest acceptable TLS protocol version. To set the
+lower bound include an element of the form: "&gt;=<i>version</i>" where
+<i>version</i> is a either one of the TLS protocol names listed above,
+or a hexadecimal number corresponding to the desired TLS protocol
+version (0301 for TLS 1.0, 0302 for TLS 1.1, etc.). For the upper
+bound, use "&lt;=<i>version</i>". There must be no whitespace between
+the "&gt;=" or "&lt;=" symbols and the protocol name or number. </p>
+
+<p> Hexadecimal protocol numbers make it possible to specify protocol
+bounds for TLS versions that are known to OpenSSL, but might not be
+known to Postfix. They cannot be used with the legacy exclusion syntax.
+Leading "0" or "0x" prefixes are supported, but not required.
+Therefore, "301", "0301", "0x301" and "0x0301" are all equivalent to
+"TLSv1". Hexadecimal versions unknown to OpenSSL will fail to set the
+upper or lower bound, and a warning will be logged. Hexadecimal
+versions should only be used when Postfix is linked with some future
+version of OpenSSL that supports TLS 1.4 or later, but Postfix does not
+yet support a symbolic name for that protocol version. </p>
+
+<p>Hexadecimal example (Postfix &ge; 3.6):</p>
+<blockquote>
+<pre>
+# Allow only TLS 1.2 through (hypothetical) TLS 1.4, once supported
+# in some future version of OpenSSL (presently a warning is logged).
+smtpd_tls_mandatory_protocols = &gt;=TLSv1.2, &lt;=0305
+# Allow only TLS 1.2 and up:
+smtpd_tls_mandatory_protocols = &gt;=0x0303
+</pre>
+</blockquote>
+
+<p> With Postfix &lt; 3.6 there is no support for a minimum or maximum
+version, and the protocol range is configured via protocol exclusions.
+To require at least TLS 1.0, set "smtpd_tls_mandatory_protocols =
+!SSLv2, !SSLv3". Listing the protocols to include, rather than
+protocols to exclude, is supported, but not recommended. The exclusion
+form more accurately matches the underlying OpenSSL interface. </p>
+
+<p> Support for "TLSv1.3" was introduced in OpenSSL 1.1.1. Disabling
+this protocol via "!TLSv1.3" is supported since Postfix 3.4 (or patch
+releases &ge; 3.0.14, 3.1.10, 3.2.7 and 3.3.2). </p>
+
+<p> Example: </p>
+
+<pre>
+# Preferred syntax with Postfix &ge; 3.6:
+smtpd_tls_mandatory_protocols = &gt;=TLSv1.2, &lt;=TLSv1.3
+# Legacy syntax:
+smtpd_tls_mandatory_protocols = !SSLv2, !SSLv3, !TLSv1, !TLSv1.1
+</pre>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_tls_security_level
+
+<p> The default SMTP TLS security level for the Postfix SMTP client.
+When a non-empty value is specified, this overrides the obsolete
+parameters smtp_use_tls, smtp_enforce_tls, and smtp_tls_enforce_peername;
+when no value is specified for smtp_tls_enforce_peername or the obsolete
+parameters, the default SMTP TLS security level is
+<a href="TLS_README.html#client_tls_none">none</a>. </p>
+
+<p> Specify one of the following security levels: </p>
+
+<dl>
+
+<dt><b><a href="TLS_README.html#client_tls_none">none</a></b></dt>
+<dd> No TLS. TLS will not be used unless enabled for specific
+destinations via smtp_tls_policy_maps. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_may">may</a></b></dt>
+<dd> Opportunistic TLS. Use TLS if this is supported by the remote
+SMTP server, otherwise use plaintext. Since
+sending in the clear is acceptable, demanding stronger than default TLS
+security merely reduces interoperability.
+The "smtp_tls_ciphers" and "smtp_tls_protocols" (Postfix &ge; 2.6)
+configuration parameters provide control over the protocols and
+cipher grade used with opportunistic TLS. With earlier releases the
+opportunistic TLS cipher grade is always "export" and no protocols
+are disabled.
+When TLS handshakes fail, the connection is retried with TLS disabled.
+This allows mail delivery to sites with non-interoperable TLS
+implementations. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_encrypt">encrypt</a></b></dt>
+<dd>Mandatory TLS encryption. Since a minimum
+level of security is intended, it is reasonable to be specific about
+sufficiently secure protocol versions and ciphers. At this security level
+and higher, the main.cf parameters smtp_tls_mandatory_protocols and
+smtp_tls_mandatory_ciphers specify the TLS protocols and minimum
+cipher grade which the administrator considers secure enough for
+mandatory encrypted sessions. This security level is not an appropriate
+default for systems delivering mail to the Internet. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_dane">dane</a></b></dt>
+<dd>Opportunistic DANE TLS. At this security level, the TLS policy
+for the destination is obtained via DNSSEC. For TLSA policy to be
+in effect, the destination domain's containing DNS zone must be
+signed and the Postfix SMTP client's operating system must be
+configured to send its DNS queries to a recursive DNS nameserver
+that is able to validate the signed records. Each MX host's DNS
+zone should also be signed, and should publish DANE TLSA (RFC 7672)
+records that specify how that MX host's TLS certificate is to be
+verified. TLSA records do not preempt the normal SMTP MX host
+selection algorithm, if some MX hosts support TLSA and others do
+not, TLS security will vary from delivery to delivery. It is up
+to the domain owner to configure their MX hosts and their DNS
+sensibly. To configure the Postfix SMTP client for DNSSEC lookups
+see the documentation for the smtp_dns_support_level main.cf
+parameter. When DNSSEC-validated TLSA records are not found the
+effective tls security level is "may". When TLSA records are found,
+but are all unusable the effective security level is "encrypt". For
+purposes of protocol and cipher selection, the "dane" security level
+is treated like a "mandatory" TLS security level, and weak ciphers
+and protocols are disabled. Since DANE authenticates server
+certificates the "aNULL" cipher-suites are transparently excluded
+at this level, no need to configure this manually. RFC 7672 (DANE)
+TLS authentication is available with Postfix 2.11 and later. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_dane">dane-only</a></b></dt>
+<dd>Mandatory DANE TLS. This is just like "dane" above, but DANE
+TLSA authentication is required. There is no fallback to "may" or
+"encrypt" when TLSA records are missing or unusable. RFC 7672
+(DANE) TLS authentication is available with Postfix 2.11 and later.
+</dd>
+
+<dt><b><a href="TLS_README.html#client_tls_fprint">fingerprint</a></b></dt>
+<dd>Certificate fingerprint verification.
+At this security level, there are no trusted Certification Authorities.
+The certificate trust chain, expiration date, etc., are
+not checked. Instead, the <b>smtp_tls_fingerprint_cert_match</b>
+parameter lists the certificate fingerprint or public key fingerprint
+(Postfix 2.9 and later) of the valid server certificate. The digest
+algorithm used to calculate the fingerprint is selected by the
+<b>smtp_tls_fingerprint_digest</b> parameter. Available with Postfix
+2.5 and later. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_verify">verify</a></b></dt>
+<dd>Mandatory TLS verification. At this security
+level, DNS MX lookups are trusted to be secure enough, and the name
+verified in the server certificate is usually obtained indirectly
+via unauthenticated DNS MX lookups. The smtp_tls_verify_cert_match
+parameter controls how the server name is verified. In practice explicit
+control over matching is more common at the "secure" level, described
+below. This security level is not an appropriate default for systems
+delivering mail to the Internet. </dd>
+
+<dt><b><a href="TLS_README.html#client_tls_secure">secure</a></b></dt>
+<dd>Secure-channel TLS. At this security level,
+DNS MX lookups, though potentially used to determine the candidate
+next-hop gateway IP addresses, are <b>not</b> trusted to be secure enough
+for TLS peername verification. Instead, the default name verified in
+the server certificate is obtained from the next-hop domain as specified
+in the smtp_tls_secure_cert_match configuration parameter. The default
+matching rule is that a server certificate matches when its name is equal
+to or is a sub-domain of the nexthop domain. This security level is not
+an appropriate default for systems delivering mail to the Internet. </dd>
+
+</dl>
+
+<p>
+Examples:
+</p>
+
+<pre>
+# No TLS. Formerly: smtp_use_tls=no and smtp_enforce_tls=no.
+smtp_tls_security_level = none
+</pre>
+
+<pre>
+# Opportunistic TLS.
+smtp_tls_security_level = may
+# Do not tweak opportunistic ciphers or protocols unless it is essential
+# to do so (if a security vulnerability is found in the SSL library that
+# can be mitigated by disabling a particular protocol or raising the
+# cipher grade).
+smtp_tls_ciphers = medium
+smtp_tls_protocols = &gt;=TLSv1
+# Legacy (Postfix &lt; 3.6) syntax:
+smtp_tls_protocols = !SSLv2, !SSLv3
+</pre>
+
+<pre>
+# Mandatory (high-grade) TLS encryption.
+smtp_tls_security_level = encrypt
+smtp_tls_mandatory_ciphers = high
+</pre>
+
+<pre>
+# Authenticated TLS 1.2 or better matching the nexthop domain or a
+# subdomain.
+smtp_tls_security_level = secure
+smtp_tls_mandatory_ciphers = high
+smtp_tls_mandatory_protocols = &gt;=TLSv1.2
+smtp_tls_secure_cert_match = nexthop, dot-nexthop
+</pre>
+
+<pre>
+# Certificate fingerprint verification (Postfix &ge; 2.5).
+# The CA-less "fingerprint" security level only scales to a limited
+# number of destinations. As a global default rather than a per-site
+# setting, this is practical only when mail for all recipients is sent
+# to a central mail hub.
+relayhost = [mailhub.example.com]
+smtp_tls_security_level = fingerprint
+smtp_tls_mandatory_protocols = &gt;=TLSv1.2
+smtp_tls_mandatory_ciphers = high
+smtp_tls_fingerprint_cert_match =
+ 3D:95:34:51:...:40:99:C0:C1
+ EC:3B:2D:B0:...:A3:9D:72:F6
+</pre>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_milters
+
+<p> A list of Milter (mail filter) applications for new mail that
+arrives via the Postfix smtpd(8) server. Specify space or comma as
+separator. See the MILTER_README document for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM non_smtpd_milters
+
+<p> A list of Milter (mail filter) applications for new mail that
+does not arrive via the Postfix smtpd(8) server. This includes local
+submission via the sendmail(1) command line, new mail that arrives
+via the Postfix qmqpd(8) server, and old mail that is re-injected
+into the queue with "postsuper -r". Specify space or comma as a
+separator. See the MILTER_README document for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_protocol 6
+
+<p> The mail filter protocol version and optional protocol extensions
+for communication with a Milter application; prior to Postfix 2.6
+the default protocol is 2. Postfix
+sends this version number during the initial protocol handshake.
+It should match the version number that is expected by the mail
+filter application (or by its Milter library). </p>
+
+<p>Protocol versions: </p>
+
+<dl compact>
+
+<dt>2</dt> <dd>Use Sendmail 8 mail filter protocol version 2 (default
+with Sendmail version 8.11 .. 8.13 and Postfix version 2.3 ..
+2.5).</dd>
+
+<dt>3</dt> <dd>Use Sendmail 8 mail filter protocol version 3.</dd>
+
+<dt>4</dt> <dd>Use Sendmail 8 mail filter protocol version 4.</dd>
+
+<dt>6</dt> <dd>Use Sendmail 8 mail filter protocol version 6 (default
+with Sendmail version 8.14 and Postfix version 2.6).</dd>
+
+</dl>
+
+<p>Protocol extensions: </p>
+
+<dl compact>
+
+<dt>no_header_reply</dt> <dd> Specify this when the Milter application
+will not reply for each individual message header.</dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_default_action tempfail
+
+<p> The default action when a Milter (mail filter) response is
+unavailable (for example, bad Postfix configuration or Milter
+failure). Specify one of the following: </p>
+
+<dl compact>
+
+<dt>accept</dt> <dd>Proceed as if the mail filter was not present.
+</dd>
+
+<dt>reject</dt> <dd>Reject all further commands in this session
+with a permanent status code.</dd>
+
+<dt>tempfail</dt> <dd>Reject all further commands in this session
+with a temporary status code. </dd>
+
+<dt>quarantine</dt> <dd>Like "accept", but freeze the message in
+the "hold" queue. Available with Postfix 2.6 and later. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_connect_timeout 30s
+
+<p> The time limit for connecting to a Milter (mail filter)
+application, and for negotiating protocol options. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_command_timeout 30s
+
+<p> The time limit for sending an SMTP command to a Milter (mail
+filter) application, and for receiving the response. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_content_timeout 300s
+
+<p> The time limit for sending message content to a Milter (mail
+filter) application, and for receiving the response. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_connect_macros see "postconf -d" output
+
+<p> The macros that are sent to Milter (mail filter) applications
+after completion of an SMTP connection. See MILTER_README
+for a list of available macro names and their meanings. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_helo_macros see "postconf -d" output
+
+<p> The macros that are sent to Milter (mail filter) applications
+after the SMTP HELO or EHLO command. See
+MILTER_README for a list of available macro names and their meanings.
+</p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_mail_macros see "postconf -d" output
+
+<p> The macros that are sent to Milter (mail filter) applications
+after the SMTP MAIL FROM command. See MILTER_README
+for a list of available macro names and their meanings. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_rcpt_macros see "postconf -d" output
+
+<p> The macros that are sent to Milter (mail filter) applications
+after the SMTP RCPT TO command. See MILTER_README
+for a list of available macro names and their meanings. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_data_macros see "postconf -d" output
+
+<p> The macros that are sent to version 4 or higher Milter (mail
+filter) applications after the SMTP DATA command. See MILTER_README
+for a list of available macro names and their meanings. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_end_of_header_macros see "postconf -d" output
+
+<p> The macros that are sent to Milter (mail filter) applications
+after the end of the message header. See MILTER_README for a list
+of available macro names and their meanings. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM milter_end_of_data_macros see "postconf -d" output
+
+<p> The macros that are sent to Milter (mail filter) applications
+after the message end-of-data. See MILTER_README for a list of
+available macro names and their meanings. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_unknown_command_macros see "postconf -d" output
+
+<p> The macros that are sent to version 3 or higher Milter (mail
+filter) applications after an unknown SMTP command. See MILTER_README
+for a list of available macro names and their meanings. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_macro_daemon_name $myhostname
+
+<p> The {daemon_name} macro value for Milter (mail filter) applications.
+See MILTER_README for a list of available macro names and their
+meanings. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM milter_macro_defaults
+
+<p> Optional list of <i>name=value</i> pairs that specify default
+values for arbitrary macros that Postfix may send to Milter
+applications. These defaults are used when there is no corresponding
+information from the message delivery context. </p>
+
+<p> Specify <i>name=value</i> or <i>{name=value}</i> pairs separated
+by comma or whitespace. Enclose a pair in "{}" when a value contains
+comma or whitespace (this form ignores whitespace after the enclosing
+"{", around the "=", and before the enclosing "}"). </p>
+
+<p> This feature is available in Postfix 3.1 and later. </p>
+
+%PARAM milter_macro_v $mail_name $mail_version
+
+<p> The {v} macro value for Milter (mail filter) applications.
+See MILTER_README for a list of available macro names and their
+meanings. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_tls_mandatory_ciphers medium
+
+<p> The minimum TLS cipher grade that the Postfix SMTP server will
+use with mandatory TLS encryption. The default grade ("medium") is
+sufficiently strong that any benefit from globally restricting TLS
+sessions to a more stringent grade is likely negligible, especially
+given the fact that many implementations still do not offer any stronger
+("high" grade) ciphers, while those that do, will always use "high"
+grade ciphers. So insisting on "high" grade ciphers is generally
+counter-productive. Allowing "export" or "low" ciphers is typically
+not a good idea, as systems limited to just these are limited to
+obsolete browsers. No known SMTP clients fail to support at least
+one "medium" or "high" grade cipher. </p>
+
+<p> The following cipher grades are supported: </p>
+
+<dl>
+<dt><b>export</b></dt>
+<dd> Enable "EXPORT" grade or stronger OpenSSL ciphers. The
+underlying cipherlist is specified via the tls_export_cipherlist
+configuration parameter, which you are strongly encouraged not to
+change. This choice is insecure and SHOULD NOT be used. </dd>
+
+<dt><b>low</b></dt>
+<dd> Enable "LOW" grade or stronger OpenSSL ciphers. The underlying
+cipherlist is specified via the tls_low_cipherlist configuration
+parameter, which you are strongly encouraged not to change. This
+choice is insecure and SHOULD NOT be used. </dd>
+
+<dt><b>medium</b></dt>
+<dd> Enable "MEDIUM" grade or stronger OpenSSL ciphers. These use 128-bit
+or longer symmetric bulk-encryption keys. This is the default minimum
+strength for mandatory TLS encryption. The underlying cipherlist is
+specified via the tls_medium_cipherlist configuration parameter, which
+you are strongly encouraged not to change. </dd>
+
+<dt><b>high</b></dt>
+<dd> Enable only "HIGH" grade OpenSSL ciphers. The
+underlying cipherlist is specified via the tls_high_cipherlist
+configuration parameter, which you are strongly encouraged to
+not change. </dd>
+
+<dt><b>null</b></dt>
+<dd> Enable only the "NULL" OpenSSL ciphers, these provide authentication
+without encryption. This setting is only appropriate in the rare
+case that all clients are prepared to use NULL ciphers (not normally
+enabled in TLS clients). The underlying cipherlist is specified via the
+tls_null_cipherlist configuration parameter, which you are strongly
+encouraged not to change. </dd>
+
+</dl>
+
+<p> Cipher types listed in
+smtpd_tls_mandatory_exclude_ciphers or smtpd_tls_exclude_ciphers are
+excluded from the base definition of the selected cipher grade. See
+smtpd_tls_ciphers for cipher controls that apply to opportunistic
+TLS. </p>
+
+<p> The underlying cipherlists for grades other than "null" include
+anonymous ciphers, but these are automatically filtered out if the
+server is configured to ask for remote SMTP client certificates. You are very
+unlikely to need to take any steps to exclude anonymous ciphers, they
+are excluded automatically as required. If you must exclude anonymous
+ciphers even when Postfix does not need or use peer certificates, set
+"smtpd_tls_exclude_ciphers = aNULL". To exclude anonymous ciphers only
+when TLS is enforced, set "smtpd_tls_mandatory_exclude_ciphers = aNULL". </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_tls_exclude_ciphers
+
+<p> List of ciphers or cipher types to exclude from the SMTP server
+cipher list at all TLS security levels. Excluding valid ciphers
+can create interoperability problems. DO NOT exclude ciphers unless it
+is essential to do so. This is not an OpenSSL cipherlist; it is a simple
+list separated by whitespace and/or commas. The elements are a single
+cipher, or one or more "+" separated cipher properties, in which case
+only ciphers matching <b>all</b> the properties are excluded. </p>
+
+<p> Examples (some of these will cause problems): </p>
+
+<blockquote>
+<pre>
+smtpd_tls_exclude_ciphers = aNULL
+smtpd_tls_exclude_ciphers = MD5, DES
+smtpd_tls_exclude_ciphers = DES+MD5
+smtpd_tls_exclude_ciphers = AES256-SHA, DES-CBC3-MD5
+smtpd_tls_exclude_ciphers = kEDH+aRSA
+</pre>
+</blockquote>
+
+<p> The first setting disables anonymous ciphers. The next setting
+disables ciphers that use the MD5 digest algorithm or the (single) DES
+encryption algorithm. The next setting disables ciphers that use MD5 and
+DES together. The next setting disables the two ciphers "AES256-SHA"
+and "DES-CBC3-MD5". The last setting disables ciphers that use "EDH"
+key exchange with RSA authentication. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_tls_mandatory_exclude_ciphers
+
+<p> Additional list of ciphers or cipher types to exclude from the
+Postfix SMTP server cipher list at mandatory TLS security levels.
+This list
+works in addition to the exclusions listed with smtpd_tls_exclude_ciphers
+(see there for syntax details). </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_tls_mandatory_ciphers medium
+
+<p> The minimum TLS cipher grade that the Postfix SMTP client will
+use with
+mandatory TLS encryption. The default value "medium" is suitable
+for most destinations with which you may want to enforce TLS, and
+is beyond the reach of today's cryptanalytic methods. See
+smtp_tls_policy_maps for information on how to configure ciphers
+on a per-destination basis. </p>
+
+<p> The following cipher grades are supported: </p>
+
+<dl>
+<dt><b>export</b></dt>
+<dd> Enable "EXPORT" grade or better OpenSSL ciphers. The underlying
+cipherlist is specified via the tls_export_cipherlist configuration
+parameter, which you are strongly encouraged not to change. This
+choice is insecure and SHOULD NOT be used. </dd>
+
+<dt><b>low</b></dt>
+<dd> Enable "LOW" grade or better OpenSSL ciphers. The underlying
+cipherlist is specified via the tls_low_cipherlist configuration
+parameter, which you are strongly encouraged not to change. This
+choice is insecure and SHOULD NOT be used. </dd>
+
+<dt><b>medium</b></dt>
+<dd> Enable "MEDIUM" grade or better OpenSSL ciphers.
+The underlying cipherlist is specified via the tls_medium_cipherlist
+configuration parameter, which you are strongly encouraged not to change.
+</dd>
+
+<dt><b>high</b></dt>
+<dd> Enable only "HIGH" grade OpenSSL ciphers. This setting may
+be appropriate when all mandatory TLS destinations (e.g. when all
+mail is routed to a suitably capable relayhost) support at least one
+"HIGH" grade cipher. The underlying cipherlist is specified via the
+tls_high_cipherlist configuration parameter, which you are strongly
+encouraged not to change. </dd>
+
+<dt><b>null</b></dt>
+<dd> Enable only the "NULL" OpenSSL ciphers, these provide authentication
+without encryption. This setting is only appropriate in the rare case
+that all servers are prepared to use NULL ciphers (not normally enabled
+in TLS servers). A plausible use-case is an LMTP server listening on a
+UNIX-domain socket that is configured to support "NULL" ciphers. The
+underlying cipherlist is specified via the tls_null_cipherlist
+configuration parameter, which you are strongly encouraged not to
+change. </dd>
+
+</dl>
+
+<p> The underlying cipherlists for grades other than "null" include
+anonymous ciphers, but these are automatically filtered out if the
+Postfix SMTP client is configured to verify server certificates.
+You are very unlikely to need to take any steps to exclude anonymous
+ciphers, they are excluded automatically as necessary. If you must
+exclude anonymous ciphers at the "may" or "encrypt" security levels,
+when the Postfix SMTP client does not need or use peer certificates, set
+"smtp_tls_exclude_ciphers = aNULL". To exclude anonymous ciphers only when
+TLS is enforced, set "smtp_tls_mandatory_exclude_ciphers = aNULL". </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_tls_exclude_ciphers
+
+<p> List of ciphers or cipher types to exclude from the Postfix
+SMTP client cipher
+list at all TLS security levels. This is not an OpenSSL cipherlist, it is
+a simple list separated by whitespace and/or commas. The elements are a
+single cipher, or one or more "+" separated cipher properties, in which
+case only ciphers matching <b>all</b> the properties are excluded. </p>
+
+<p> Examples (some of these will cause problems): </p>
+
+<blockquote>
+<pre>
+smtp_tls_exclude_ciphers = aNULL
+smtp_tls_exclude_ciphers = MD5, DES
+smtp_tls_exclude_ciphers = DES+MD5
+smtp_tls_exclude_ciphers = AES256-SHA, DES-CBC3-MD5
+smtp_tls_exclude_ciphers = kEDH+aRSA
+</pre>
+</blockquote>
+
+<p> The first setting disables anonymous ciphers. The next setting
+disables ciphers that use the MD5 digest algorithm or the (single) DES
+encryption algorithm. The next setting disables ciphers that use MD5 and
+DES together. The next setting disables the two ciphers "AES256-SHA"
+and "DES-CBC3-MD5". The last setting disables ciphers that use "EDH"
+key exchange with RSA authentication. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_tls_mandatory_exclude_ciphers
+
+<p> Additional list of ciphers or cipher types to exclude from the
+Postfix SMTP client cipher list at mandatory TLS security levels. This list
+works in addition to the exclusions listed with smtp_tls_exclude_ciphers
+(see there for syntax details). </p>
+
+<p> Starting with Postfix 2.6, the mandatory cipher exclusions can be
+specified on a per-destination basis via the TLS policy "exclude"
+attribute. See smtp_tls_policy_maps for notes and examples. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM tls_high_cipherlist see "postconf -d" output
+
+<p> The OpenSSL cipherlist for "high" grade ciphers. This defines
+the meaning of the "high" setting in smtpd_tls_ciphers,
+smtpd_tls_mandatory_ciphers, smtp_tls_ciphers, smtp_tls_mandatory_ciphers,
+lmtp_tls_ciphers, and lmtp_tls_mandatory_ciphers. You are strongly
+encouraged not to change this setting. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM tls_medium_cipherlist see "postconf -d" output
+
+<p> The OpenSSL cipherlist for "medium" or higher grade ciphers. This
+defines the meaning of the "medium" setting in smtpd_tls_ciphers,
+smtpd_tls_mandatory_ciphers, smtp_tls_ciphers, smtp_tls_mandatory_ciphers,
+lmtp_tls_ciphers, and lmtp_tls_mandatory_ciphers. This is the
+default cipherlist for mandatory TLS encryption in the TLS client
+(with anonymous ciphers disabled when verifying server certificates).
+This is the default cipherlist for opportunistic TLS with Postfix
+releases after the middle of 2015. You are strongly encouraged not
+to change this setting. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM tls_low_cipherlist see "postconf -d" output
+
+<p> The OpenSSL cipherlist for "low" or higher grade ciphers. This defines
+the meaning of the "low" setting in smtpd_tls_ciphers,
+smtpd_tls_mandatory_ciphers, smtp_tls_ciphers, smtp_tls_mandatory_ciphers,
+lmtp_tls_ciphers, and lmtp_tls_mandatory_ciphers. You are strongly
+encouraged not to change this setting. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM tls_export_cipherlist see "postconf -d" output
+
+<p> The OpenSSL cipherlist for "export" or higher grade ciphers. This
+defines the meaning of the "export" setting in smtpd_tls_ciphers,
+smtpd_tls_mandatory_ciphers, smtp_tls_ciphers, smtp_tls_mandatory_ciphers,
+lmtp_tls_ciphers, and lmtp_tls_mandatory_ciphers. With Postfix
+releases before the middle of 2015 this is the default cipherlist
+for the opportunistic ("may") TLS client security level and also
+the default cipherlist for the SMTP server. You are strongly
+encouraged not to change this setting. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM tls_null_cipherlist eNULL:!aNULL
+
+<p> The OpenSSL cipherlist for "NULL" grade ciphers that provide
+authentication without encryption. This defines the meaning of the "null"
+setting in smtpd_tls_mandatory_ciphers, smtp_tls_mandatory_ciphers and
+lmtp_tls_mandatory_ciphers. You are strongly encouraged not to
+change this setting. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_mandatory_ciphers medium
+
+<p> The LMTP-specific version of the smtp_tls_mandatory_ciphers
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_exclude_ciphers
+
+<p> The LMTP-specific version of the smtp_tls_exclude_ciphers
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM lmtp_tls_mandatory_exclude_ciphers
+
+<p> The LMTP-specific version of the smtp_tls_mandatory_exclude_ciphers
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_tls_security_level
+
+<p> The SMTP TLS security level for the Postfix SMTP server; when
+a non-empty value is specified, this overrides the obsolete parameters
+smtpd_use_tls and smtpd_enforce_tls. This parameter is ignored with
+"smtpd_tls_wrappermode = yes". </p>
+
+<p> Specify one of the following security levels: </p>
+
+<dl>
+
+<dt><b>none</b></dt> <dd> TLS will not be used. </dd>
+
+<dt><b>may</b></dt> <dd> Opportunistic TLS: announce STARTTLS support
+to remote SMTP clients, but do not require that clients use TLS encryption.
+</dd>
+
+<dt><b>encrypt</b></dt> <dd>Mandatory TLS encryption: announce
+STARTTLS support to remote SMTP clients, and require that clients use TLS
+encryption. According to RFC 2487 this MUST NOT be applied in case
+of a publicly-referenced SMTP server. Instead, this option should
+be used only on dedicated servers. </dd>
+
+</dl>
+
+<p> Note 1: the "fingerprint", "verify" and "secure" levels are not
+supported here.
+The Postfix SMTP server logs a warning and uses "encrypt" instead.
+To verify remote SMTP client certificates, see TLS_README for a discussion
+of the smtpd_tls_ask_ccert, smtpd_tls_req_ccert, and permit_tls_clientcerts
+features. </p>
+
+<p> Note 2: The parameter setting "smtpd_tls_security_level =
+encrypt" implies "smtpd_tls_auth_only = yes".</p>
+
+<p> Note 3: when invoked via "sendmail -bs", Postfix will never
+offer STARTTLS due to insufficient privileges to access the server
+private key. This is intended behavior.</p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM internal_mail_filter_classes
+
+<p> What categories of Postfix-generated mail are subject to
+before-queue content inspection by non_smtpd_milters, header_checks
+and body_checks. Specify zero or more of the following, separated
+by whitespace or comma. </p>
+
+<dl>
+
+<dt><b>bounce</b></dt> <dd> Inspect the content of delivery
+status notifications. </dd>
+
+<dt><b>notify</b></dt> <dd> Inspect the content of postmaster
+notifications by the smtp(8) and smtpd(8) processes. </dd>
+
+</dl>
+
+<p> NOTE: It's generally not safe to enable content inspection of
+Postfix-generated email messages. The user is warned. </p>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtpd_tls_always_issue_session_ids yes
+
+<p> Force the Postfix SMTP server to issue a TLS session id, even
+when TLS session caching is turned off (smtpd_tls_session_cache_database
+is empty). This behavior is compatible with Postfix &lt; 2.3. </p>
+
+<p> With Postfix 2.3 and later the Postfix SMTP server can disable
+session id generation when TLS session caching is turned off. This
+keeps remote SMTP clients from caching sessions that almost certainly cannot
+be re-used. </p>
+
+<p> By default, the Postfix SMTP server always generates TLS session
+ids. This works around a known defect in mail client applications
+such as MS Outlook, and may also prevent interoperability issues
+with other MTAs. </p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_always_issue_session_ids = no
+</pre>
+
+<p> This feature is available in Postfix 2.3 and later. </p>
+
+%PARAM smtp_pix_workarounds disable_esmtp, delay_dotcrlf
+
+<p> A list that specifies zero or more workarounds for CISCO PIX
+firewall bugs. These workarounds are implemented by the Postfix
+SMTP client. Workaround names are separated by comma or space, and
+are case insensitive. This parameter setting can be overruled with
+per-destination smtp_pix_workaround_maps settings. </p>
+
+<dl>
+
+<dt><b>delay_dotcrlf</b><dd> Insert a delay before sending
+".&lt;CR&gt;&lt;LF&gt;" after the end of the message content. The
+delay is subject to the smtp_pix_workaround_delay_time and
+smtp_pix_workaround_threshold_time parameter settings. </dd>
+
+<dt><b>disable_esmtp</b><dd> Disable all extended SMTP commands:
+send HELO instead of EHLO. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.4 and later. The default
+settings are backwards compatible with earlier Postfix versions.
+</p>
+
+%PARAM smtp_pix_workaround_maps
+
+<p> Lookup tables, indexed by the remote SMTP server address, with
+per-destination workarounds for CISCO PIX firewall bugs. The table
+is not indexed by hostname for consistency with
+smtp_discard_ehlo_keyword_address_maps. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> This feature is available in Postfix 2.4 and later. </p>
+
+%PARAM lmtp_pix_workarounds
+
+<p> The LMTP-specific version of the smtp_pix_workaround
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.4 and later. </p>
+
+%PARAM smtp_tls_fingerprint_digest see "postconf -d" output
+
+<p> The message digest algorithm used to construct remote SMTP server
+certificate fingerprints. At the "fingerprint" TLS security level
+(<b>smtp_tls_security_level</b> = fingerprint), the server certificate is
+verified by directly matching its certificate fingerprint or its public
+key fingerprint (Postfix 2.9 and later). The fingerprint is the
+message digest of the server certificate (or its public key)
+using the selected
+algorithm. With a digest algorithm resistant to "second pre-image"
+attacks, it is not feasible to create a new public key and a matching
+certificate (or public/private key-pair) that has the same fingerprint. </p>
+
+<p> The default algorithm is <b>sha256</b> with Postfix &ge; 3.6
+and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix
+&le; 3.5, the default algorithm is <b>md5</b>. </p>
+
+<p> The best-practice algorithm is now <b>sha256</b>. Recent advances in hash
+function cryptanalysis have led to md5 and sha1 being deprecated in favor of
+sha256. However, as long as there are no known "second pre-image" attacks
+against the older algorithms, their use in this context, though not
+recommended, is still likely safe. </p>
+
+<p> While additional digest algorithms are often available with OpenSSL's
+libcrypto, only those used by libssl in SSL cipher suites are available to
+Postfix. You'll likely find support for md5, sha1, sha256 and sha512. </p>
+
+<p> To find the fingerprint of a specific certificate file, with a
+specific digest algorithm, run:
+</p>
+
+<blockquote>
+<pre>
+$ openssl x509 -noout -fingerprint -<i>digest</i> -in <i>certfile</i>.pem
+</pre>
+</blockquote>
+
+<p> The text to the right of the "=" sign is the desired fingerprint.
+For example: </p>
+
+<blockquote>
+<pre>
+$ openssl x509 -noout -fingerprint -sha256 -in cert.pem
+SHA256 Fingerprint=D4:6A:AB:19:24:...:BB:A6:CB:66:82:C0:8E:9B:EE:29:A8:1A
+</pre>
+</blockquote>
+
+<p> To extract the public key fingerprint from an X.509 certificate,
+you need to extract the public key from the certificate and compute
+the appropriate digest of its DER (ASN.1) encoding. With OpenSSL
+the "-pubkey" option of the "x509" command extracts the public
+key always in "PEM" format. We pipe the result to another OpenSSL
+command that converts the key to DER and then to the "dgst" command
+to compute the fingerprint. </p>
+
+<p> The actual command to transform the key to DER format depends on the
+version of OpenSSL used. As of OpenSSL 1.0.0, the "pkey" command supports
+all key types. </p>
+<blockquote>
+<pre>
+# OpenSSL &ge; 1.0 with SHA-256 fingerprints.
+$ openssl x509 -in cert.pem -noout -pubkey |
+ openssl pkey -pubin -outform DER |
+ openssl dgst -sha256 -c
+(stdin)= 64:3f:1f:f6:e5:1e:d4:2a:56:...:fc:09:1a:61:98:b5:bc:7c:60:58
+</pre>
+</blockquote>
+
+<p> The Postfix SMTP server and client log the peer (leaf) certificate
+fingerprint and the public key fingerprint when the TLS loglevel is 2 or
+higher. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM smtp_tls_fingerprint_cert_match
+
+<p> List of acceptable remote SMTP server certificate fingerprints for
+the "fingerprint" TLS security level (<b>smtp_tls_security_level</b> =
+fingerprint). At this security level, Certification Authorities are not
+used, and certificate expiration times are ignored. Instead, server
+certificates are verified directly via their certificate fingerprint
+or public key fingerprint (Postfix 2.9 and later). The fingerprint
+is a message digest of the server certificate (or public key). The
+digest algorithm is selected via the <b>smtp_tls_fingerprint_digest</b>
+parameter. </p>
+
+<p> The colons between each pair of nibbles in the fingerprint value
+are optional (Postfix &ge; 3.6). These were required in earlier
+Postfix releases. </p>
+
+<p> When an <b>smtp_tls_policy_maps</b> table entry specifies the
+"fingerprint" security level, any "match" attributes in that entry specify
+the list of valid fingerprints for the corresponding destination. Multiple
+fingerprints can be combined with a "|" delimiter in a single match
+attribute, or multiple match attributes can be employed. </p>
+
+<p> Example: Certificate fingerprint verification with internal mailhub.
+Two matching fingerprints are listed. The relayhost may be multiple
+physical hosts behind a load-balancer, each with its own private/public
+key and self-signed certificate. Alternatively, a single relayhost may
+be in the process of switching from one set of private/public keys to
+another, and both keys are trusted just prior to the transition. </p>
+
+<blockquote>
+<pre>
+relayhost = [mailhub.example.com]
+smtp_tls_security_level = fingerprint
+smtp_tls_fingerprint_digest = sha256
+smtp_tls_fingerprint_cert_match =
+ cd:fc:d8:db:f8:c4:82:96:6c:...:28:71:e8:f5:8d:a5:0d:9b:d4:a6
+ dd:5c:ef:f5:c3:bc:64:25:36:...:99:36:06:ce:40:ef:de:2e:ad:a4
+</pre>
+</blockquote>
+
+<p> Example: Certificate fingerprint verification with selected destinations.
+As in the example above, we show two matching fingerprints: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_policy_maps = hash:/etc/postfix/tls_policy
+ smtp_tls_fingerprint_digest = sha256
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/tls_policy:
+ example.com fingerprint
+ match=51:e9:af:2e:1e:40:1f:...:64:0a:30:35:2d:09:16:31:5a:eb:82:76
+ match=b6:b4:72:34:e2:59:cd:...:c2:ca:63:0d:4d:cc:2c:7d:84:de:e6:2f
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_tls_fingerprint_cert_match
+
+<p> The LMTP-specific version of the smtp_tls_fingerprint_cert_match
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_tls_fingerprint_digest see "postconf -d" output
+
+<p> The LMTP-specific version of the smtp_tls_fingerprint_digest
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM smtpd_tls_fingerprint_digest see "postconf -d" output
+
+<p> The message digest algorithm to construct remote SMTP client-certificate
+fingerprints or public key fingerprints (Postfix 2.9 and later) for
+<b>check_ccert_access</b> and <b>permit_tls_clientcerts</b>. </p>
+
+<p> The default algorithm is <b>sha256</b> with Postfix &ge; 3.6
+and the <b>compatibility_level</b> set to 3.6 or higher. With Postfix
+&le; 3.5, the default algorithm is <b>md5</b>. </p>
+
+<p> The best-practice algorithm is now <b>sha256</b>. Recent advances in hash
+function cryptanalysis have led to md5 and sha1 being deprecated in favor of
+sha256. However, as long as there are no known "second pre-image" attacks
+against the older algorithms, their use in this context, though not
+recommended, is still likely safe. </p>
+
+<p> While additional digest algorithms are often available with OpenSSL's
+libcrypto, only those used by libssl in SSL cipher suites are available to
+Postfix. You'll likely find support for md5, sha1, sha256 and sha512. </p>
+
+<p> To find the fingerprint of a specific certificate file, with a
+specific digest algorithm, run: </p>
+
+<blockquote>
+<pre>
+$ openssl x509 -noout -fingerprint -<i>digest</i> -in <i>certfile</i>.pem
+</pre>
+</blockquote>
+
+<p> The text to the right of "=" sign is the desired fingerprint.
+For example: </p>
+
+<blockquote>
+<pre>
+$ openssl x509 -noout -fingerprint -sha256 -in cert.pem
+SHA256 Fingerprint=D4:6A:AB:19:24:...:A6:CB:66:82:C0:8E:9B:EE:29:A8:1A
+</pre>
+</blockquote>
+
+<p> To extract the public key fingerprint from an X.509 certificate,
+you need to extract the public key from the certificate and compute
+the appropriate digest of its DER (ASN.1) encoding. With OpenSSL
+the "-pubkey" option of the "x509" command extracts the public
+key always in "PEM" format. We pipe the result to another OpenSSL
+command that converts the key to DER and then to the "dgst" command
+to compute the fingerprint. </p>
+
+<p> Example: </p>
+<blockquote>
+<pre>
+$ openssl x509 -in cert.pem -noout -pubkey |
+ openssl pkey -pubin -outform DER |
+ openssl dgst -sha256 -c
+(stdin)= 64:3f:1f:f6:e5:1e:d4:2a:56:8b:fc:09:1a:61:98:b5:bc:7c:60:58
+</pre>
+</blockquote>
+
+<p> The Postfix SMTP server and client log the peer (leaf) certificate
+fingerprint and public key fingerprint when the TLS loglevel is 2 or
+higher. </p>
+
+<p> Example: client-certificate access table, with sha256 fingerprints: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_fingerprint_digest = sha256
+ smtpd_client_restrictions =
+ check_ccert_access hash:/etc/postfix/access,
+ reject
+</pre>
+<pre>
+/etc/postfix/access:
+ # Action folded to next line...
+ AF:88:7C:AD:51:95:6F:36:96:...:01:FB:2E:48:CD:AB:49:25:A2:3B
+ OK
+ 85:16:78:FD:73:6E:CE:70:E0:...:5F:0D:3C:C8:6D:C4:2C:24:59:E1
+ permit_auth_destination
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_pix_workaround_maps
+
+<p> The LMTP-specific version of the smtp_pix_workaround_maps
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.4 and later. </p>
+
+%PARAM detect_8bit_encoding_header yes
+
+<p> Automatically detect 8BITMIME body content by looking at
+Content-Transfer-Encoding: message headers; historically, this
+behavior was hard-coded to be "always on". </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM send_cyrus_sasl_authzid no
+
+<p> When authenticating to a remote SMTP or LMTP server with the
+default setting "no", send no SASL authoriZation ID (authzid); send
+only the SASL authentiCation ID (authcid) plus the authcid's password.
+</p>
+
+<p> The non-default setting "yes" enables the behavior of older
+Postfix versions. These always send a SASL authzid that is equal
+to the SASL authcid, but this causes interoperability problems
+with some SMTP servers. </p>
+
+<p> This feature is available in Postfix 2.4.4 and later. </p>
+
+%PARAM smtpd_client_port_logging no
+
+<p> Enable logging of the remote SMTP client port in addition to
+the hostname and IP address. The logging format is "host[address]:port".
+</p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM qmqpd_client_port_logging no
+
+<p> Enable logging of the remote QMQP client port in addition to
+the hostname and IP address. The logging format is "host[address]:port".
+</p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM smtp_tls_protocols see postconf -d output
+
+<p> TLS protocols that the Postfix SMTP client will use with
+opportunistic TLS encryption. In main.cf the values are separated by
+whitespace, commas or colons. In the policy table "protocols" attribute
+(see smtp_tls_policy_maps) the only valid separator is colon. An empty
+value means allow all protocols. </p>
+
+<p> The valid protocol names (see SSL_get_version(3)) are "SSLv2",
+"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" and "TLSv1.3". Starting with
+Postfix 3.6, the default value is "&gt;=TLSv1", which sets TLS 1.0 as
+the lowest supported TLS protocol version (see below). Older releases
+use the "!" exclusion syntax, also described below. </p>
+
+<p> As of Postfix 3.6, the preferred way to limit the range of
+acceptable protocols is to set the lowest acceptable TLS protocol
+version and/or the highest acceptable TLS protocol version. To set the
+lower bound include an element of the form: "&gt;=<i>version</i>" where
+<i>version</i> is either one of the TLS protocol names listed above,
+or a hexadecimal number corresponding to the desired TLS protocol
+version (0301 for TLS 1.0, 0302 for TLS 1.1, etc.). For the upper
+bound, use "&lt;=<i>version</i>". There must be no whitespace between
+the "&gt;=" or "&lt;=" symbols and the protocol name or number. </p>
+
+<p> Hexadecimal protocol numbers make it possible to specify protocol
+bounds for TLS versions that are known to OpenSSL, but might not be
+known to Postfix. They cannot be used with the legacy exclusion syntax.
+Leading "0" or "0x" prefixes are supported, but not required.
+Therefore, "301", "0301", "0x301" and "0x0301" are all equivalent to
+"TLSv1". Hexadecimal versions unknown to OpenSSL will fail to set the
+upper or lower bound, and a warning will be logged. Hexadecimal
+versions should only be used when Postfix is linked with some future
+version of OpenSSL that supports TLS 1.4 or later, but Postfix does not
+yet support a symbolic name for that protocol version. </p>
+
+<p>Hexadecimal example (Postfix &ge; 3.6):</p>
+<blockquote>
+<pre>
+# Allow only TLS 1.0 through (hypothetical) TLS 1.4, once supported
+# in some future version of OpenSSL (presently a warning is logged).
+smtp_tls_protocols = &gt;=TLSv1, &lt;=0305
+# Allow only TLS 1.0 and up:
+smtp_tls_protocols = &gt;=0x0301
+</pre>
+</blockquote>
+
+<p> With Postfix &lt; 3.6 there is no support for a minimum or maximum
+version, and the protocol range is configured via protocol exclusions.
+To require at least TLS 1.0, set "smtp_tls_protocols = !SSLv2, !SSLv3".
+Listing the protocols to include, rather than protocols to exclude, is
+supported, but not recommended. The exclusion form more accurately
+matches the underlying OpenSSL interface. </p>
+
+<p> When using the exclusion syntax, take care to ensure that the range of
+protocols advertised by an SSL/TLS client is contiguous. When a protocol
+version is enabled, disabling any higher version implicitly disables all
+versions above that higher version. Thus, for example:
+</p>
+<blockquote>
+<pre>
+smtp_tls_protocols = !SSLv2, !SSLv3, !TLSv1.1
+</pre>
+</blockquote>
+<p> also disables any protocols version higher than TLSv1.1 leaving
+only "TLSv1" enabled. </p>
+
+<p> Support for "TLSv1.3" was introduced in OpenSSL 1.1.1. Disabling
+this protocol via "!TLSv1.3" is supported since Postfix 3.4 (or patch
+releases &ge; 3.0.14, 3.1.10, 3.2.7 and 3.3.2). </p>
+
+<p> Example: </p>
+<pre>
+# Preferred syntax with Postfix &ge; 3.6:
+smtp_tls_protocols = &gt;=TLSv1, &lt;=TLSv1.3
+# Legacy syntax:
+smtp_tls_protocols = !SSLv2, !SSLv3
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM smtpd_tls_protocols see postconf -d output
+
+<p> TLS protocols accepted by the Postfix SMTP server with opportunistic
+TLS encryption. If the list is empty, the server supports all available
+TLS protocol versions. A non-empty value is a list of protocol names to
+include or exclude, separated by whitespace, commas or colons. </p>
+
+<p> The valid protocol names (see SSL_get_version(3)) are "SSLv2",
+"SSLv3", "TLSv1", "TLSv1.1", "TLSv1.2" and "TLSv1.3". Starting with
+Postfix 3.6, the default value is "&gt;=TLSv1", which sets TLS 1.0 as
+the lowest supported TLS protocol version (see below). Older releases
+use the "!" exclusion syntax, also described below. </p>
+
+<p> As of Postfix 3.6, the preferred way to limit the range of
+acceptable protocols is to set the lowest acceptable TLS protocol
+version and/or the highest acceptable TLS protocol version. To set the
+lower bound include an element of the form: "&gt;=<i>version</i>" where
+<i>version</i> is a either one of the TLS protocol names listed above,
+or a hexadecimal number corresponding to the desired TLS protocol
+version (0301 for TLS 1.0, 0302 for TLS 1.1, etc.). For the upper
+bound, use "&lt;=<i>version</i>". There must be no whitespace between
+the "&gt;=" or "&lt;=" symbols and the protocol name or number. </p>
+
+<p> Hexadecimal protocol numbers make it possible to specify protocol
+bounds for TLS versions that are known to OpenSSL, but might not be
+known to Postfix. They cannot be used with the legacy exclusion syntax.
+Leading "0" or "0x" prefixes are supported, but not required.
+Therefore, "301", "0301", "0x301" and "0x0301" are all equivalent to
+"TLSv1". Hexadecimal versions unknown to OpenSSL will fail to set the
+upper or lower bound, and a warning will be logged. Hexadecimal
+versions should only be used when Postfix is linked with some future
+version of OpenSSL that supports TLS 1.4 or later, but Postfix does not
+yet support a symbolic name for that protocol version. </p>
+
+<p>Hexadecimal example (Postfix &ge; 3.6):</p>
+<blockquote>
+<pre>
+# Allow only TLS 1.0 through (hypothetical) TLS 1.4, once supported
+# in some future version of OpenSSL (presently a warning is logged).
+smtpd_tls_protocols = &gt;=TLSv1, &lt;=0305
+# Allow only TLS 1.0 and up:
+smtpd_tls_protocols = &gt;=0x0301
+</pre>
+</blockquote>
+
+<p> With Postfix &lt; 3.6 there is no support for a minimum or maximum
+version, and the protocol range is configured via protocol exclusions.
+To require at least TLS 1.0, set "smtpd_tls_protocols = !SSLv2, !SSLv3".
+Listing the protocols to include, rather than protocols to exclude, is
+supported, but not recommended. The exclusion form more accurately
+matches the underlying OpenSSL interface. </p>
+
+<p> Support for "TLSv1.3" was introduced in OpenSSL 1.1.1. Disabling
+this protocol via "!TLSv1.3" is supported since Postfix 3.4 (or patch
+releases &ge; 3.0.14, 3.1.10, 3.2.7 and 3.3.2). </p>
+
+<p> Example: </p>
+<pre>
+# Preferred syntax with Postfix &ge; 3.6:
+smtpd_tls_protocols = &gt;=TLSv1, &lt;=TLSv1.3
+# Legacy syntax:
+smtpd_tls_protocols = !SSLv2, !SSLv3
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM lmtp_tls_protocols see postconf -d output
+
+<p> The LMTP-specific version of the smtp_tls_protocols configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM smtp_tls_ciphers medium
+
+<p> The minimum TLS cipher grade that the Postfix SMTP client
+will use with opportunistic TLS encryption. Cipher types listed in
+smtp_tls_exclude_ciphers are excluded from the base definition of
+the selected cipher grade. The default value is "medium" for
+Postfix releases after the middle of 2015, "export" for older
+releases. </p>
+
+<p> When TLS is mandatory the cipher grade is chosen via the
+smtp_tls_mandatory_ciphers configuration parameter, see there for syntax
+details. See smtp_tls_policy_maps for information on how to configure
+ciphers on a per-destination basis. </p>
+
+<p> This feature is available in Postfix 2.6 and later. With earlier Postfix
+releases only the smtp_tls_mandatory_ciphers parameter is implemented,
+and opportunistic TLS always uses "export" or better (i.e. all) ciphers. </p>
+
+%PARAM smtpd_tls_ciphers medium
+
+<p> The minimum TLS cipher grade that the Postfix SMTP server
+will use with opportunistic TLS encryption. Cipher types listed in
+smtpd_tls_exclude_ciphers are excluded from the base definition of
+the selected cipher grade. The default value is "medium" for Postfix
+releases after the middle of 2015, "export" for older releases.
+</p>
+
+<p> When TLS is mandatory the cipher grade is chosen via the
+smtpd_tls_mandatory_ciphers configuration parameter, see there for syntax
+details. </p>
+
+<p> This feature is available in Postfix 2.6 and later. With earlier Postfix
+releases only the smtpd_tls_mandatory_ciphers parameter is implemented,
+and opportunistic TLS always uses "export" or better (i.e. all) ciphers. </p>
+
+%PARAM lmtp_tls_ciphers medium
+
+<p> The LMTP-specific version of the smtp_tls_ciphers configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM tls_eecdh_auto_curves see "postconf -d" output
+
+<p> The prioritized list of elliptic curves supported by the Postfix
+SMTP client and server. These curves are used by the Postfix SMTP
+server when "smtpd_tls_eecdh_grade = auto". The selected curves
+must be implemented by OpenSSL and be standardized for use in TLS
+(RFC 8422). It is unwise to list only
+"bleeding-edge" curves supported by a small subset of clients. The
+default list is suitable for most users. </p>
+
+<p> Postfix skips curve names that are unknown to OpenSSL, or that
+are known but not yet implemented. This makes it possible to
+"anticipate" support for curves that should be used once they become
+available. In particular, in some OpenSSL versions, the new RFC
+8031 curves "X25519" and "X448" may be known by name, but ECDH
+support for either or both may be missing. These curves may appear
+in the default value of this parameter, even though they'll only
+be usable with later versions of OpenSSL. </p>
+
+<p> This feature is available in Postfix 3.2 and later, when it is
+compiled and linked with OpenSSL 1.0.2 or later on platforms where
+EC algorithms have not been disabled by the vendor. </p>
+
+%PARAM tls_eecdh_strong_curve prime256v1
+
+<p> The elliptic curve used by the Postfix SMTP server for sensibly
+strong
+ephemeral ECDH key exchange. This curve is used by the Postfix SMTP
+server when "smtpd_tls_eecdh_grade = strong". The phrase "sensibly
+strong" means approximately 128-bit security based on best known
+attacks. The selected curve must be implemented by OpenSSL (as
+reported by ecparam(1) with the "-list_curves" option) and be one
+of the curves listed in Section 5.1.1 of RFC 8422. You should not
+generally change this setting. Remote SMTP client implementations
+must support this curve for EECDH key exchange to take place. It
+is unwise to choose only "bleeding-edge" curves supported by only a
+small subset of clients. </p>
+
+<p> The default "strong" curve is rated in NSA <a
+href="https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/">Suite
+B</a> for information classified up to SECRET. </p>
+
+<p> Note: elliptic curve names are poorly standardized; different
+standards groups are assigning different names to the same underlying
+curves. The curve with the X9.62 name "prime256v1" is also known
+under the SECG name "secp256r1", but OpenSSL does not recognize the
+latter name. </p>
+
+<p> If you want to take maximal advantage of ciphers that offer <a
+href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see
+the <a href="FORWARD_SECRECY_README.html#quick-start">Getting
+started</a> section of <a
+href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The
+full document conveniently presents all information about Postfix
+"perfect" forward secrecy support in one place: what forward secrecy
+is, how to tweak settings, and what you can expect to see when
+Postfix uses ciphers with forward secrecy. </p>
+
+<p> This feature is available in Postfix 2.6 and later, when it is
+compiled and linked with OpenSSL 1.0.0 or later on platforms where
+EC algorithms have not been disabled by the vendor. </p>
+
+%PARAM tls_eecdh_ultra_curve secp384r1
+
+<p> The elliptic curve used by the Postfix SMTP server for maximally
+strong
+ephemeral ECDH key exchange. This curve is used by the Postfix SMTP
+server when "smtpd_tls_eecdh_grade = ultra". The phrase "maximally
+strong" means approximately 192-bit security based on best known attacks.
+This additional strength comes at a significant computational cost, most
+users should instead set "smtpd_tls_eecdh_grade = strong". The selected
+curve must be implemented by OpenSSL (as reported by ecparam(1) with the
+"-list_curves" option) and be one of the curves listed in Section 5.1.1
+of RFC 8422. You should not generally change this setting. Remote SMTP
+client implementations must support this curve for EECDH key exchange
+to take place. It is unwise to choose only "bleeding-edge" curves
+supported by only a small subset of clients. </p>
+
+<p> This default "ultra" curve is rated in NSA <a
+href="https://web.archive.org/web/20160330034144/https://www.nsa.gov/ia/programs/suiteb_cryptography/">Suite
+B</a> for information classified up to TOP SECRET. </p>
+
+<p> If you want to take maximal advantage of ciphers that offer <a
+href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see
+the <a href="FORWARD_SECRECY_README.html#quick-start">Getting
+started</a> section of <a
+href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The
+full document conveniently presents all information about Postfix
+"perfect" forward secrecy support in one place: what forward secrecy
+is, how to tweak settings, and what you can expect to see when
+Postfix uses ciphers with forward secrecy. </p>
+
+<p> This feature is available in Postfix 2.6 and later, when it is
+compiled and linked with OpenSSL 1.0.0 or later on platforms where
+EC algorithms have not been disabled by the vendor. </p>
+
+%PARAM smtpd_tls_eecdh_grade see "postconf -d" output
+
+<p> The Postfix SMTP server security grade for ephemeral elliptic-curve
+Diffie-Hellman (EECDH) key exchange. As of Postfix 3.6, the value of
+this parameter is always ignored, and Postfix behaves as though the
+<b>auto</b> value (described below) was chosen.
+</p>
+
+<p> The available choices are: </p>
+
+<dl>
+
+<dt><b>auto</b></dt> <dd> Use the most preferred curve that is
+supported by both the client and the server. This setting requires
+Postfix &ge; 3.2 compiled and linked with OpenSSL &ge; 1.0.2. This
+is the default setting under the above conditions (and the only
+setting used with Postfix &ge; 3.6). </dd>
+
+<dt><b>none</b></dt> <dd> Don't use EECDH. Ciphers based on EECDH key
+exchange will be disabled. This is the default in Postfix versions
+2.6 and 2.7. </dd>
+
+<dt><b>strong</b></dt> <dd> Use EECDH with approximately 128 bits of
+security at a reasonable computational cost. This is the default in
+Postfix versions 2.8&ndash;3.5. </dd>
+
+<dt><b>ultra</b></dt> <dd> Use EECDH with approximately 192 bits of
+security at computational cost that is approximately twice as high
+as 128 bit strength ECC. </dd>
+
+</dl>
+
+<p> If you want to take maximal advantage of ciphers that offer <a
+href="FORWARD_SECRECY_README.html#dfn_fs">forward secrecy</a> see
+the <a href="FORWARD_SECRECY_README.html#quick-start">Getting
+started</a> section of <a
+href="FORWARD_SECRECY_README.html">FORWARD_SECRECY_README</a>. The
+full document conveniently presents all information about Postfix
+"perfect" forward secrecy support in one place: what forward secrecy
+is, how to tweak settings, and what you can expect to see when
+Postfix uses ciphers with forward secrecy. </p>
+
+<p> This feature is available in Postfix 2.6 and later, when it is
+compiled and linked with OpenSSL 1.0.0 or later on platforms
+where EC algorithms have not been disabled by the vendor. </p>
+
+%PARAM smtpd_tls_eccert_file
+
+<p> File with the Postfix SMTP server ECDSA certificate in PEM format.
+This file may also contain the Postfix SMTP server private ECDSA key.
+With Postfix &ge; 3.4 the preferred way to configure server keys and
+certificates is via the "smtpd_tls_chain_files" parameter. </p>
+
+<p> See the discussion under smtpd_tls_cert_file for more details. </p>
+
+<p> Example: </p>
+
+<pre>
+smtpd_tls_eccert_file = /etc/postfix/ecdsa-scert.pem
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later, when Postfix is
+compiled and linked with OpenSSL 1.0.0 or later. </p>
+
+%PARAM smtpd_tls_eckey_file $smtpd_tls_eccert_file
+
+<p> File with the Postfix SMTP server ECDSA private key in PEM format.
+This file may be combined with the Postfix SMTP server ECDSA certificate
+file specified with $smtpd_tls_eccert_file. With Postfix &ge; 3.4 the
+preferred way to configure server keys and certificates is via the
+"smtpd_tls_chain_files" parameter. </p>
+
+<p> The private key must be accessible without a pass-phrase, i.e. it
+must not be encrypted. File permissions should grant read-only
+access to the system superuser account ("root"), and no access
+to anyone else. </p>
+
+<p> This feature is available in Postfix 2.6 and later, when Postfix is
+compiled and linked with OpenSSL 1.0.0 or later. </p>
+
+%PARAM smtp_tls_eccert_file
+
+<p> File with the Postfix SMTP client ECDSA certificate in PEM format.
+This file may also contain the Postfix SMTP client ECDSA private key.
+With Postfix &ge; 3.4 the preferred way to configure client keys and
+certificates is via the "smtp_tls_chain_files" parameter. </p>
+
+<p> See the discussion under smtp_tls_cert_file for more details.
+</p>
+
+<p> Example: </p>
+
+<pre>
+smtp_tls_eccert_file = /etc/postfix/ecdsa-ccert.pem
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later, when Postfix is
+compiled and linked with OpenSSL 1.0.0 or later. </p>
+
+%PARAM smtp_tls_eckey_file $smtp_tls_eccert_file
+
+<p> File with the Postfix SMTP client ECDSA private key in PEM format.
+This file may be combined with the Postfix SMTP client ECDSA certificate
+file specified with $smtp_tls_eccert_file. With Postfix &ge; 3.4 the
+preferred way to configure client keys and certificates is via the
+"smtp_tls_chain_files" parameter. </p>
+
+<p> The private key must be accessible without a pass-phrase, i.e. it
+must not be encrypted. File permissions should grant read-only
+access to the system superuser account ("root"), and no access
+to anyone else. </p>
+
+<p> This feature is available in Postfix 2.6 and later, when Postfix is
+compiled and linked with OpenSSL 1.0.0 or later. </p>
+
+%PARAM lmtp_tls_eccert_file
+
+<p> The LMTP-specific version of the smtp_tls_eccert_file configuration
+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 1.0.0 or later. </p>
+
+%PARAM lmtp_tls_eckey_file
+
+<p> The LMTP-specific version of the smtp_tls_eckey_file configuration
+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 1.0.0 or later. </p>
+
+%PARAM smtp_header_checks
+
+<p> Restricted header_checks(5) tables for the Postfix SMTP client.
+These tables are searched while mail is being delivered. Actions
+that change the delivery time or destination are not available.
+</p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM smtp_mime_header_checks
+
+<p> Restricted mime_header_checks(5) tables for the Postfix SMTP
+client. These tables are searched while mail is being delivered.
+Actions that change the delivery time or destination are not
+available. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM smtp_nested_header_checks
+
+<p> Restricted nested_header_checks(5) tables for the Postfix SMTP
+client. These tables are searched while mail is being delivered.
+Actions that change the delivery time or destination are not
+available. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM smtp_body_checks
+
+<p> Restricted body_checks(5) tables for the Postfix SMTP client.
+These tables are searched while mail is being delivered. Actions
+that change the delivery time or destination are not available.
+</p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM destination_concurrency_feedback_debug no
+
+<p> Make the queue manager's feedback algorithm verbose for performance
+analysis purposes. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM default_destination_concurrency_failed_cohort_limit 1
+
+<p> How many pseudo-cohorts must suffer connection or handshake
+failure before a specific destination is considered unavailable
+(and further delivery is suspended). Specify zero to disable this
+feature. A destination's pseudo-cohort failure count is reset each
+time a delivery completes without connection or handshake failure
+for that specific destination. </p>
+
+<p> A pseudo-cohort is the number of deliveries equal to a destination's
+delivery concurrency. </p>
+
+<p> Use <i>transport</i>_destination_concurrency_failed_cohort_limit to specify
+a transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport. </p>
+
+<p> This feature is available in Postfix 2.5. The default setting
+is compatible with earlier Postfix versions. </p>
+
+%PARAM default_destination_concurrency_negative_feedback 1
+
+<p> The per-destination amount of delivery concurrency negative
+feedback, after a delivery completes with a connection or handshake
+failure. Feedback values are in the range 0..1 inclusive. With
+negative feedback, concurrency is decremented at the beginning of
+a sequence of length 1/feedback. This is unlike positive feedback,
+where concurrency is incremented at the end of a sequence of length
+1/feedback. </p>
+
+<p> As of Postfix version 2.5, negative feedback cannot reduce
+delivery concurrency to zero. Instead, a destination is marked
+dead (further delivery suspended) after the failed pseudo-cohort
+count reaches $default_destination_concurrency_failed_cohort_limit
+(or $<i>transport</i>_destination_concurrency_failed_cohort_limit).
+To make the scheduler completely immune to connection or handshake
+failures, specify a zero feedback value and a zero failed pseudo-cohort
+limit. </p>
+
+<p> Specify one of the following forms: </p>
+
+<dl>
+
+<dt> <b><i>number</i> </b> </dt>
+
+<dt> <b><i>number</i> / <i>number</i> </b> </dt>
+
+<dd> Constant feedback. The value must be in the range 0..1 inclusive.
+The default setting of "1" is compatible with Postfix versions
+before 2.5, where a destination's delivery concurrency is throttled
+down to zero (and further delivery suspended) after a single failed
+pseudo-cohort. </dd>
+
+<dt> <b><i>number</i> / concurrency </b> </dt>
+
+<dd> Variable feedback of "<i>number</i> / (delivery concurrency)".
+The <i>number</i> must be in the range 0..1 inclusive. With
+<i>number</i> equal to "1", a destination's delivery concurrency
+is decremented by 1 after each failed pseudo-cohort. </dd>
+
+<!--
+
+<dt> <b><i>number</i> / sqrt_concurrency </b> </dt>
+
+<dd> Variable feedback of "<i>number</i> / sqrt(delivery concurrency)".
+The <i>number</i> must be in the range 0..1 inclusive. This setting
+may be removed in a future version. </dd>
+
+-->
+
+</dl>
+
+<p> A pseudo-cohort is the number of deliveries equal to a destination's
+delivery concurrency. </p>
+
+<p> Use <i>transport</i>_destination_concurrency_negative_feedback
+to specify a transport-specific override, where <i>transport</i>
+is the master.cf
+name of the message delivery transport. </p>
+
+<p> This feature is available in Postfix 2.5. The default setting
+is compatible with earlier Postfix versions. </p>
+
+%PARAM default_destination_concurrency_positive_feedback 1
+
+<p> The per-destination amount of delivery concurrency positive
+feedback, after a delivery completes without connection or handshake
+failure. Feedback values are in the range 0..1 inclusive. The
+concurrency increases until it reaches the per-destination maximal
+concurrency limit. With positive feedback, concurrency is incremented
+at the end of a sequence with length 1/feedback. This is unlike
+negative feedback, where concurrency is decremented at the start
+of a sequence of length 1/feedback. </p>
+
+<p> Specify one of the following forms: </p>
+
+<dl>
+
+<dt> <b><i>number</i> </b> </dt>
+
+<dt> <b><i>number</i> / <i>number</i> </b> </dt>
+
+<dd> Constant feedback. The value must be in the range 0..1
+inclusive. The default setting of "1" is compatible with Postfix
+versions before 2.5, where a destination's delivery concurrency
+doubles after each successful pseudo-cohort. </dd>
+
+<dt> <b><i>number</i> / concurrency </b> </dt>
+
+<dd> Variable feedback of "<i>number</i> / (delivery concurrency)".
+The <i>number</i> must be in the range 0..1 inclusive. With
+<i>number</i> equal to "1", a destination's delivery concurrency
+is incremented by 1 after each successful pseudo-cohort. </dd>
+
+<!--
+
+<dt> <b><i>number</i> / sqrt_concurrency </b> </dt>
+
+<dd> Variable feedback of "<i>number</i> / sqrt(delivery concurrency)".
+The <i>number</i> must be in the range 0..1 inclusive. This setting
+may be removed in a future version. </dd>
+
+-->
+
+</dl>
+
+<p> A pseudo-cohort is the number of deliveries equal to a destination's
+delivery concurrency. </p>
+
+<p> Use <i>transport</i>_destination_concurrency_positive_feedback
+to specify a transport-specific override, where <i>transport</i>
+is the master.cf name of the message delivery transport. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM transport_destination_concurrency_failed_cohort_limit $default_destination_concurrency_failed_cohort_limit
+
+<p> A transport-specific override for the
+default_destination_concurrency_failed_cohort_limit parameter value,
+where <i>transport</i> is the master.cf name of the message delivery
+transport. </p>
+
+<p> Note: some <i>transport</i>_destination_concurrency_failed_cohort_limit
+parameters will not show up in "postconf" command output before
+Postfix version 2.9. This limitation applies to many parameters
+whose name is a combination of a master.cf service name and a
+built-in suffix (in this case:
+"_destination_concurrency_failed_cohort_limit"). </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM transport_destination_concurrency_positive_feedback $default_destination_concurrency_positive_feedback
+
+<p> A transport-specific override for the
+default_destination_concurrency_positive_feedback parameter value,
+where <i>transport</i> is the master.cf name of the message delivery
+transport. </p>
+
+<p> Note: some <i>transport</i>_destination_concurrency_positive_feedback
+parameters will not show up in "postconf" command output before
+Postfix version 2.9. This limitation applies to many parameters
+whose name is a combination of a master.cf service name and a
+built-in suffix (in this case:
+"_destination_concurrency_positive_feedback"). </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM transport_destination_concurrency_negative_feedback $default_destination_concurrency_negative_feedback
+
+<p> A transport-specific override for the
+default_destination_concurrency_negative_feedback parameter value,
+where <i>transport</i> is the master.cf name of the message delivery
+transport. </p>
+
+<p> Note: some <i>transport</i>_destination_concurrency_negative_feedback
+parameters will not show up in "postconf" command output before
+Postfix version 2.9. This limitation applies to many parameters
+whose name is a combination of a master.cf service name and a
+built-in suffix (in this case:
+"_destination_concurrency_negative_feedback"). </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM transport_initial_destination_concurrency $initial_destination_concurrency
+
+<p> A transport-specific override for the initial_destination_concurrency
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: some <i>transport</i>_initial_destination_concurrency
+parameters will not show up in "postconf" command output before
+Postfix version 2.9. This limitation applies to many parameters
+whose name is a combination of a master.cf service name and a
+built-in suffix (in this case: "_initial_destination_concurrency").
+</p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM transport_destination_concurrency_limit $default_destination_concurrency_limit
+
+<p> A transport-specific override for the
+default_destination_concurrency_limit parameter value, where
+<i>transport</i> is the master.cf name of the message delivery
+transport. </p>
+
+<p> Note: some <i>transport</i>_destination_concurrency_limit
+parameters will not show up in "postconf" command output before
+Postfix version 2.9. This limitation applies to many parameters
+whose name is a combination of a master.cf service name and a
+built-in suffix (in this case: "_destination_concurrency_limit").
+</p>
+
+%PARAM transport_destination_recipient_limit $default_destination_recipient_limit
+
+<p> A transport-specific override for the
+default_destination_recipient_limit parameter value, where
+<i>transport</i> is the master.cf name of the message delivery
+transport. </p>
+
+<p> Note: some <i>transport</i>_destination_recipient_limit parameters
+will not show up in "postconf" command output before Postfix version
+2.9. This limitation applies to many parameters whose name is a
+combination of a master.cf service name and a built-in suffix (in
+this case: "_destination_recipient_limit"). </p>
+
+%PARAM transport_time_limit $command_time_limit
+
+<p> A transport-specific override for the command_time_limit parameter
+value, where <i>transport</i> is the master.cf name of the message
+delivery transport. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> Note: <i>transport</i>_time_limit parameters will not show up
+in "postconf" command output before Postfix version 2.9. This
+limitation applies to many parameters whose name is a combination
+of a master.cf service name and a built-in suffix (in this case:
+"_time_limit"). </p>
+
+%PARAM transport_delivery_slot_cost $default_delivery_slot_cost
+
+<p> A transport-specific override for the default_delivery_slot_cost
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: <i>transport</i>_delivery_slot_cost parameters will not
+show up in "postconf" command output before Postfix version 2.9.
+This limitation applies to many parameters whose name is a combination
+of a master.cf service name and a built-in suffix (in this case:
+"_delivery_slot_cost"). </p>
+
+%PARAM transport_delivery_slot_loan $default_delivery_slot_loan
+
+<p> A transport-specific override for the default_delivery_slot_loan
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: <i>transport</i>_delivery_slot_loan parameters will not
+show up in "postconf" command output before Postfix version 2.9.
+This limitation applies to many parameters whose name is a combination
+of a master.cf service name and a built-in suffix (in this case:
+"_delivery_slot_loan"). </p>
+
+%PARAM transport_delivery_slot_discount $default_delivery_slot_discount
+
+<p> A transport-specific override for the default_delivery_slot_discount
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: <i>transport</i>_delivery_slot_discount parameters will
+not show up in "postconf" command output before Postfix version
+2.9. This limitation applies to many parameters whose name is a
+combination of a master.cf service name and a built-in suffix (in
+this case: "_delivery_slot_discount"). </p>
+
+%PARAM transport_minimum_delivery_slots $default_minimum_delivery_slots
+
+<p> A transport-specific override for the default_minimum_delivery_slots
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: <i>transport</i>_minimum_delivery_slots parameters will
+not show up in "postconf" command output before Postfix version
+2.9. This limitation applies to many parameters whose name is a
+combination of a master.cf service name and a built-in suffix (in
+this case: "_minimum_delivery_slots"). </p>
+
+%PARAM transport_recipient_limit $default_recipient_limit
+
+<p> A transport-specific override for the default_recipient_limit
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: some <i>transport</i>_recipient_limit parameters will not
+show up in "postconf" command output before Postfix version 2.9.
+This limitation applies to many parameters whose name is a combination
+of a master.cf service name and a built-in suffix (in this case:
+"_recipient_limit"). </p>
+
+%PARAM transport_extra_recipient_limit $default_extra_recipient_limit
+
+<p> A transport-specific override for the default_extra_recipient_limit
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: <i>transport</i>_extra_recipient_limit parameters will
+not show up in "postconf" command output before Postfix version
+2.9. This limitation applies to many parameters whose name is a
+combination of a master.cf service name and a built-in suffix (in
+this case: "_extra_recipient_limit"). </p>
+
+%PARAM transport_recipient_refill_limit $default_recipient_refill_limit
+
+<p> A transport-specific override for the default_recipient_refill_limit
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: <i>transport</i>_recipient_refill_limit parameters will
+not show up in "postconf" command output before Postfix version
+2.9. This limitation applies to many parameters whose name is a
+combination of a master.cf service name and a built-in suffix (in
+this case: "_recipient_refill_limit"). </p>
+
+<p> This feature is available in Postfix 2.4 and later. </p>
+
+%PARAM transport_recipient_refill_delay $default_recipient_refill_delay
+
+<p> A transport-specific override for the default_recipient_refill_delay
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: <i>transport</i>_recipient_refill_delay parameters will
+not show up in "postconf" command output before Postfix version
+2.9. This limitation applies to many parameters whose name is a
+combination of a master.cf service name and a built-in suffix (in
+this case: "_recipient_refill_delay"). </p>
+
+<p> This feature is available in Postfix 2.4 and later. </p>
+
+%PARAM default_transport_rate_delay 0s
+
+<p> The default amount of delay that is inserted between individual
+message deliveries over the same message delivery transport,
+regardless of destination. Specify a non-zero value to rate-limit
+those message deliveries to at most one per $default_transport_rate_delay.
+</p>
+
+<p>Use <i>transport</i>_transport_rate_delay to specify a
+transport-specific override, where the initial <i>transport</i> is
+the master.cf name of the message delivery transport. </p>
+
+<p> Example: throttle outbound SMTP mail to at most 3 deliveries
+per minute. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtp_transport_rate_delay = 20s
+</pre>
+
+<p> To enable the delay, specify a non-zero time value (an integral
+value plus an optional one-letter suffix that specifies the time
+unit). </p>
+
+<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
+(weeks). The default time unit is s (seconds). </p>
+
+<p> NOTE: the delay is enforced by the queue manager. </p>
+
+<p> This feature is available in Postfix 3.1 and later. </p>
+
+%PARAM transport_transport_rate_delay $default_transport_rate_delay
+
+<p> A transport-specific override for the default_transport_rate_delay
+parameter value, where the initial <i>transport</i> in the parameter
+name is the master.cf name of the message delivery transport. </p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> Note: <i>transport</i>_transport_rate_delay parameters will
+not show up in "postconf" command output before Postfix version
+2.9. This limitation applies to many parameters whose name is a
+combination of a master.cf service name and a built-in suffix (in
+this case: "_transport_rate_delay"). </p>
+
+%PARAM default_destination_rate_delay 0s
+
+<p> The default amount of delay that is inserted between individual
+message deliveries to the same destination and over the same message
+delivery transport. Specify a non-zero value to rate-limit those
+message deliveries to at most one per $default_destination_rate_delay.
+</p>
+
+<p> The resulting behavior depends on the value of the corresponding
+per-destination recipient limit.
+
+</p>
+
+<ul>
+
+<li> <p> With a corresponding per-destination recipient limit &gt;
+1, the rate delay specifies the time between deliveries to the
+<i>same domain</i>. Different domains are delivered in parallel,
+subject to the process limits specified in master.cf. </p>
+
+<li> <p> With a corresponding per-destination recipient limit equal
+to 1, the rate delay specifies the time between deliveries to the
+<i>same recipient</i>. Different recipients are delivered in
+parallel, subject to the process limits specified in master.cf.
+</p>
+
+</ul>
+
+<p> To enable the delay, specify a non-zero time value (an integral
+value plus an optional one-letter suffix that specifies the time
+unit). </p>
+
+<p> Time units: s (seconds), m (minutes), h (hours), d (days), w
+(weeks). The default time unit is s (seconds). </p>
+
+<p> NOTE: the delay is enforced by the queue manager. The delay
+timer state does not survive "<b>postfix reload</b>" or "<b>postfix
+stop</b>".
+</p>
+
+<p> Use <i>transport</i>_destination_rate_delay to specify a
+transport-specific override, where <i>transport</i> is the master.cf
+name of the message delivery transport.
+</p>
+
+<p> NOTE: with a non-zero _destination_rate_delay, specify a
+<i>transport</i>_destination_concurrency_failed_cohort_limit of 10
+or more to prevent Postfix from deferring all mail for the same
+destination after only one connection or handshake error. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM transport_destination_rate_delay $default_destination_rate_delay
+
+<p> A transport-specific override for the default_destination_rate_delay
+parameter value, where <i>transport</i> is the master.cf name of
+the message delivery transport. </p>
+
+<p> Note: some <i>transport</i>_destination_rate_delay parameters
+will not show up in "postconf" command output before Postfix version
+2.9. This limitation applies to many parameters whose name is a
+combination of a master.cf service name and a built-in suffix (in
+this case: "_destination_rate_delay"). </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM data_directory see "postconf -d" output
+
+<p> The directory with Postfix-writable data files (for example:
+caches, pseudo-random numbers). This directory must be owned by
+the mail_owner account, and must not be shared with non-Postfix
+software. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM stress
+
+<p> This feature is documented in the STRESS_README document. </p>
+
+<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 not 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> Use a per-destination delivery concurrency of 1 (for example,
+"smtp_destination_concurrency_limit = 1",
+"relay_destination_concurrency_limit = 1", etc.), otherwise multiple
+delivery agents may experience a login failure at the same time.
+</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> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </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>
+
+%PARAM unverified_sender_reject_reason
+
+<p> The Postfix SMTP server's reply when rejecting mail with
+reject_unverified_sender. Do not include the numeric SMTP reply
+code or the enhanced status code. By default, the response includes
+actual address verification details.
+
+<p> Example: </p>
+
+<pre>
+unverified_sender_reject_reason = Sender address lookup failed
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unverified_recipient_reject_reason
+
+<p> The Postfix SMTP server's reply when rejecting mail with
+reject_unverified_recipient. Do not include the numeric SMTP reply
+code or the enhanced status code. By default, the response includes
+actual address verification details.
+
+<p> Example: </p>
+
+<pre>
+unverified_recipient_reject_reason = Recipient address lookup failed
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM strict_mailbox_ownership yes
+
+<p> Defer delivery when a mailbox file is not owned by its recipient.
+The default setting is not backwards compatible. </p>
+
+<p> This feature is available in Postfix 2.5.3 and later. </p>
+
+%PARAM proxymap_service_name proxymap
+
+<p> The name of the proxymap read-only table lookup service. This
+service is normally implemented by the proxymap(8) daemon. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM proxywrite_service_name proxywrite
+
+<p> The name of the proxywrite read-write table lookup service.
+This service is normally implemented by the proxymap(8) daemon.
+</p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM master_service_disable
+
+<p> Selectively disable master(8) listener ports by service type
+or by service name and type. Specify a list of service types
+("inet", "unix", "fifo", or "pass") or "name/type" tuples, where
+"name" is the first field of a master.cf entry and "type" is a
+service type. As with other Postfix matchlists, a search stops at
+the first match. Specify "!pattern" to exclude a service from the
+list. By default, all master(8) listener ports are enabled. </p>
+
+<p> Note: this feature does not support "/file/name" or "type:table"
+patterns, nor does it support wildcards such as "*" or "all". This
+is intentional. </p>
+
+<p> Examples: </p>
+
+<pre>
+# With Postfix 2.6..2.10 use '.' instead of '/'.
+# Turn on all master(8) listener ports (the default).
+master_service_disable =
+# Turn off only the main SMTP listener port.
+master_service_disable = smtp/inet
+# Turn off all TCP/IP listener ports.
+master_service_disable = inet
+# Turn off all TCP/IP listener ports except "foo".
+master_service_disable = !foo/inet, inet
+</pre>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM tcp_windowsize 0
+
+<p> An optional workaround for routers that break TCP window scaling.
+Specify a value &gt; 0 and &lt; 65536 to enable this feature. With
+Postfix TCP servers (smtpd(8), qmqpd(8)), this feature is implemented
+by the Postfix master(8) daemon. </p>
+
+<p> To change this parameter without stopping Postfix, you need to
+first terminate all Postfix TCP servers: </p>
+
+<blockquote>
+<pre>
+# postconf -e master_service_disable=inet
+# postfix reload
+</pre>
+</blockquote>
+
+<p> This immediately terminates all processes that accept network
+connections. Next, you enable Postfix TCP servers with the updated
+tcp_windowsize setting: </p>
+
+<blockquote>
+<pre>
+# postconf -e tcp_windowsize=65535 master_service_disable=
+# postfix reload
+</pre>
+</blockquote>
+
+<p> If you skip these steps with a running Postfix system, then the
+tcp_windowsize change will work only for Postfix TCP clients (smtp(8),
+lmtp(8)). </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_directories
+
+<p> An optional list of non-default Postfix configuration directories;
+these directories belong to additional Postfix instances that share
+the Postfix executable files and documentation with the default
+Postfix instance, and that are started, stopped, etc., together
+with the default Postfix instance. Specify a list of pathnames
+separated by comma or whitespace. </p>
+
+<p> When $multi_instance_directories is empty, the postfix(1) command
+runs in single-instance mode and operates on a single Postfix
+instance only. Otherwise, the postfix(1) command runs in multi-instance
+mode and invokes the multi-instance manager specified with the
+multi_instance_wrapper parameter. The multi-instance manager in
+turn executes postfix(1) commands for the default instance and for
+all Postfix instances in $multi_instance_directories. </p>
+
+<p> Currently, this parameter setting is ignored except for the
+default main.cf file. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_wrapper
+
+<p> The pathname of a multi-instance manager command that the
+postfix(1) command invokes when the multi_instance_directories
+parameter value is non-empty. The pathname may be followed by
+initial command arguments separated by whitespace; shell
+metacharacters such as quotes are not supported in this context.
+</p>
+
+<p> The postfix(1) command invokes the manager command with the
+postfix(1) non-option command arguments on the manager command line,
+and with all installation configuration parameters exported into
+the manager command process environment. The manager command in
+turn invokes the postfix(1) command for individual Postfix instances
+as "postfix -c <i>config_directory</i> <i>command</i>". </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_group
+
+<p> The optional instance group name of this Postfix instance. A
+group identifies closely-related Postfix instances that the
+multi-instance manager can start, stop, etc., as a unit. This
+parameter is reserved for the multi-instance manager. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_name
+
+<p> The optional instance name of this Postfix instance. This name
+becomes also the default value for the syslog_name parameter. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM multi_instance_enable no
+
+<p> Allow this Postfix instance to be started, stopped, etc., by a
+multi-instance manager. By default, new instances are created in
+a safe state that prevents them from being started inadvertently.
+This parameter is reserved for the multi-instance manager. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM reject_tempfail_action defer_if_permit
+
+<p> The Postfix SMTP server's action when a reject-type restriction
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> For finer control, see: unverified_recipient_tempfail_action,
+unverified_sender_tempfail_action, unknown_address_tempfail_action,
+and unknown_helo_hostname_tempfail_action. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unverified_recipient_tempfail_action $reject_tempfail_action
+
+<p> The Postfix SMTP server's action when reject_unverified_recipient
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unverified_sender_tempfail_action $reject_tempfail_action
+
+<p> The Postfix SMTP server's action when reject_unverified_sender
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unknown_address_tempfail_action $reject_tempfail_action
+
+<p> The Postfix SMTP server's action when reject_unknown_sender_domain
+or reject_unknown_recipient_domain fail due to a temporary error
+condition. Specify "defer" to defer the remote SMTP client request
+immediately. With the default "defer_if_permit" action, the Postfix
+SMTP server continues to look for opportunities to reject mail, and
+defers the client request only if it would otherwise be accepted.
+</p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM unknown_helo_hostname_tempfail_action $reject_tempfail_action
+
+<p> The Postfix SMTP server's action when reject_unknown_helo_hostname
+fails due to a temporary error condition. Specify "defer" to defer
+the remote SMTP client request immediately. With the default
+"defer_if_permit" action, the Postfix SMTP server continues to look
+for opportunities to reject mail, and defers the client request
+only if it would otherwise be accepted. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM postmulti_start_commands start
+
+<p> The postfix(1) commands that the postmulti(1) instance manager treats
+as "start" commands. For these commands, disabled instances are "checked"
+rather than "started", and failure to "start" a member instance of an
+instance group will abort the start-up of later instances. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM postmulti_stop_commands see "postconf -d" output
+
+<p> The postfix(1) commands that the postmulti(1) instance manager treats
+as "stop" commands. For these commands, disabled instances are skipped,
+and enabled instances are processed in reverse order. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM postmulti_control_commands reload flush
+
+<p> The postfix(1) commands that the postmulti(1) instance manager
+treats as "control" commands, that operate on running instances. For
+these commands, disabled instances are skipped. </p>
+
+<p> This feature is available in Postfix 2.6 and later. </p>
+
+%PARAM lmtp_assume_final no
+
+<p> When a remote LMTP server announces no DSN support, assume that
+the
+server performs final delivery, and send "delivered" delivery status
+notifications instead of "relayed". The default setting is backwards
+compatible to avoid the infinitesimal possibility of breaking
+existing LMTP-based content filters. </p>
+
+%PARAM always_add_missing_headers no
+
+<p> Always add (Resent-) From:, To:, Date: or Message-ID: headers
+when not present. Postfix 2.6 and later add these headers only
+when clients match the local_header_rewrite_clients parameter
+setting. Earlier Postfix versions always add these headers; this
+may break DKIM signatures that cover non-existent headers.
+The undisclosed_recipients_header parameter setting determines
+whether a To: header will be added. </p>
+
+%PARAM lmtp_header_checks
+
+<p> The LMTP-specific version of the smtp_header_checks configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_mime_header_checks
+
+<p> The LMTP-specific version of the smtp_mime_header_checks
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_nested_header_checks
+
+<p> The LMTP-specific version of the smtp_nested_header_checks
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM lmtp_body_checks
+
+<p> The LMTP-specific version of the smtp_body_checks configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.5 and later. </p>
+
+%PARAM milter_header_checks
+
+<p> Optional lookup tables for content inspection of message headers
+that are produced by Milter applications. See the header_checks(5)
+manual page available actions. Currently, PREPEND is not implemented.
+</p>
+
+<p> The following example sends all mail that is marked as SPAM to
+a spam handling machine. Note that matches are case-insensitive
+by default. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ milter_header_checks = pcre:/etc/postfix/milter_header_checks
+</pre>
+
+<pre>
+/etc/postfix/milter_header_checks:
+ /^X-SPAM-FLAG:\s+YES/ FILTER mysmtp:sanitizer.example.com:25
+</pre>
+
+<p> The milter_header_checks mechanism could also be used for
+allowlisting. For example it could be used to skip heavy content
+inspection for DKIM-signed mail from known friendly domains. </p>
+
+<p> This feature is available in Postfix 2.7, and as an optional
+patch for Postfix 2.6. </p>
+
+%PARAM postscreen_cache_map btree:$data_directory/postscreen_cache
+
+<p> Persistent storage for the postscreen(8) server decisions. </p>
+
+<p> To share a postscreen(8) cache between multiple postscreen(8)
+instances, use "postscreen_cache_map = proxy:btree:/path/to/file".
+This requires Postfix version 2.9 or later; earlier proxymap(8)
+implementations don't support cache cleanup. For an alternative
+approach see the memcache_table(5) manpage. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM smtpd_service_name smtpd
+
+<p> The internal service that postscreen(8) hands off allowed
+connections to. In a future version there may be different
+classes of SMTP service. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_post_queue_limit $default_process_limit
+
+<p> The number of clients that can be waiting for service from a
+real Postfix SMTP server process. When this queue is full, all
+clients will
+receive a 421 response. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_pre_queue_limit $default_process_limit
+
+<p> The number of non-allowlisted clients that can be waiting for
+a decision whether they will receive service from a real Postfix
+SMTP server
+process. When this queue is full, all non-allowlisted clients will
+receive a 421 response. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_greet_ttl 1d
+
+<p> The amount of time that postscreen(8) will use the result from
+a successful PREGREET test. During this time, the client IP address
+is excluded from this test. The default is relatively short, because
+a good client can immediately talk to a real Postfix SMTP server. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_cache_retention_time 7d
+
+<p> The amount of time that postscreen(8) will cache an expired
+temporary allowlist entry before it is removed. This prevents clients
+from being logged as "NEW" just because their cache entry expired
+an hour ago. It also prevents the cache from filling up with clients
+that passed some deep protocol test once and never came back. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_cache_cleanup_interval 12h
+
+<p> The amount of time between postscreen(8) cache cleanup runs.
+Cache cleanup increases the load on the cache database and should
+therefore not be run frequently. This feature requires that the
+cache database supports the "delete" and "sequence" operators.
+Specify a zero interval to disable cache cleanup. </p>
+
+<p> After each cache cleanup run, the postscreen(8) daemon logs the
+number of entries that were retained and dropped. A cleanup run is
+logged as "partial" when the daemon terminates early after "<b>postfix
+reload</b>", "<b>postfix stop</b>", or no requests for $max_idle
+seconds. </p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is h (hours). </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_greet_wait normal: 6s, overload: 2s
+
+<p> The amount of time that postscreen(8) will wait for an SMTP
+client to send a command before its turn, and for DNS blocklist
+lookup results to arrive (default: up to 2 seconds under stress,
+up to 6 seconds otherwise). <p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_dnsbl_sites
+
+<p>Optional list of DNS allow/denylist domains, filters and weight
+factors. When the list is non-empty, the dnsblog(8) daemon will
+query these domains with the IP addresses of remote SMTP clients,
+and postscreen(8) will update an SMTP client's DNSBL score with
+each non-error reply. </p>
+
+<p> Caution: when postscreen rejects mail, it replies with the DNSBL
+domain name. Use the postscreen_dnsbl_reply_map feature to hide
+"password" information in DNSBL domain names. </p>
+
+<p> When a client's score is equal to or greater than the threshold
+specified with postscreen_dnsbl_threshold, postscreen(8) can drop
+the connection with the remote SMTP client. </p>
+
+<p> Specify a list of domain=filter*weight entries, separated by
+comma or whitespace. </p>
+
+<ul>
+
+<li> <p> When no "=filter" is specified, postscreen(8) will use any
+non-error DNSBL reply. Otherwise, postscreen(8) uses only DNSBL
+replies that match the filter. The filter has the form d.d.d.d,
+where each d is a number, or a pattern inside [] that contains one
+or more ";"-separated numbers or number..number ranges. </p>
+
+<li> <p> When no "*weight" is specified, postscreen(8) increments
+the remote SMTP client's DNSBL score by 1. Otherwise, the weight must be
+an integral number, and postscreen(8) adds the specified weight to
+the remote SMTP client's DNSBL score. Specify a negative number for
+allowlisting. </p>
+
+<li> <p> When one postscreen_dnsbl_sites entry produces multiple
+DNSBL responses, postscreen(8) applies the weight at most once.
+</p>
+
+</ul>
+
+<p> Examples: </p>
+
+<p> To use example.com as a high-confidence blocklist, and to
+block mail with example.net and example.org only when both agree:
+</p>
+
+<pre>
+postscreen_dnsbl_threshold = 2
+postscreen_dnsbl_sites = example.com*2, example.net, example.org
+</pre>
+
+<p> To filter only DNSBL replies containing 127.0.0.4: </p>
+
+<pre>
+postscreen_dnsbl_sites = example.com=127.0.0.4
+</pre>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_dnsbl_action ignore
+
+<p>The action that postscreen(8) takes when a remote SMTP client's combined
+DNSBL score is equal to or greater than a threshold (as defined
+with the postscreen_dnsbl_sites and postscreen_dnsbl_threshold
+parameters). Specify one of the following: </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default) </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Repeat this test the next time the client connects.
+This option is useful for testing and collecting statistics
+without blocking mail. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_greet_action ignore
+
+<p>The action that postscreen(8) takes when a remote SMTP client speaks
+before its turn within the time specified with the postscreen_greet_wait
+parameter. Specify one of the following: </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default) </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Repeat this test the next time the client connects.
+This option is useful for testing and collecting statistics
+without blocking mail. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. </dd>
+
+</dl>
+
+<p> In either case, postscreen(8) will not allowlist the remote SMTP client
+IP address. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_access_list permit_mynetworks
+
+<p> Permanent allow/denylist for remote SMTP client IP addresses.
+postscreen(8) searches this list immediately after a remote SMTP
+client connects. Specify a comma- or whitespace-separated list of
+commands (in upper or lower case) or lookup tables. The search stops
+upon the first command that fires for the client IP address. </p>
+
+<dl>
+
+<dt> <b> permit_mynetworks </b> </dt> <dd> Allowlist the client and
+terminate the search if the client IP address matches $mynetworks.
+Do not subject the client to any before/after 220 greeting tests.
+Pass the connection immediately to a Postfix SMTP server process.
+<br> Pattern matching of domain names is controlled by the presence
+or absence of "postscreen_access_list" in the
+parent_domain_matches_subdomains parameter value. </dd>
+
+<dt> <b> type:table </b> </dt> <dd> Query the specified lookup
+table. Each table lookup result is an access list, except that
+access lists inside a table cannot specify type:table entries. <br>
+To discourage the use of hash, btree, etc. tables, there is no
+support for substring matching like smtpd(8). Use CIDR tables
+instead. </dd>
+
+<dt> <b> permit </b> </dt> <dd> Allowlist the client and terminate
+the search. Do not subject the client to any before/after 220
+greeting tests. Pass the connection immediately to a Postfix SMTP
+server process. </dd>
+
+<dt> <b> reject </b> </dt> <dd> Denylist the client and terminate
+the search. Subject the client to the action configured with the
+postscreen_denylist_action configuration parameter. </dd>
+
+<dt> <b> dunno </b> </dt> <dd> All postscreen(8) access lists
+implicitly have this command at the end. <br> When <b> dunno </b>
+is executed inside a lookup table, return from the lookup table and
+evaluate the next command. <br> When <b> dunno </b> is executed
+outside a lookup table, terminate the search, and subject the client
+to the configured before/after 220 greeting tests. </dd>
+
+</dl>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_access_list = permit_mynetworks,
+ cidr:/etc/postfix/postscreen_access.cidr
+ # Postfix &lt; 3.6 use postscreen_blacklist_action.
+ postscreen_denylist_action = enforce
+</pre>
+
+<pre>
+/etc/postfix/postscreen_access.cidr:
+ # Rules are evaluated in the order as specified.
+ # Denylist 192.168.* except 192.168.0.1.
+ 192.168.0.1 dunno
+ 192.168.0.0/16 reject
+</pre>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_greet_banner $smtpd_banner
+
+<p> The <i>text</i> in the optional "220-<i>text</i>..." server
+response that
+postscreen(8) sends ahead of the real Postfix SMTP server's "220
+text..." response, in an attempt to confuse bad SMTP clients so
+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.8. </p>
+
+%PARAM postscreen_blacklist_action ignore
+
+<p> Renamed to postscreen_denylist_action in Postfix 3.6. </p>
+
+<p> This feature is available in Postfix 2.8 - 3.5. </p>
+
+%PARAM postscreen_denylist_action ignore
+
+<p> The action that postscreen(8) takes when a remote SMTP client is
+permanently denylisted with the postscreen_access_list parameter.
+Specify one of the following: </p>
+
+<dl>
+
+<dt> <b>ignore</b> (default) </dt>
+
+<dd> Ignore this result. Allow other tests to complete. Repeat
+this test the next time the client connects.
+This option is useful for testing and collecting statistics
+without blocking mail. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+<p> Available as postscreen_blacklist_action in Postfix 2.8 - 3.5. </p>
+
+%PARAM smtpd_command_filter
+
+<p> A mechanism to transform commands from remote SMTP clients.
+This is a last-resort tool to work around client commands that break
+interoperability with the Postfix SMTP server. Other uses involve
+fault injection to test Postfix's handling of invalid commands.
+</p>
+
+<p> Specify the name of a "type:table" lookup table. The search
+string is the SMTP command as received from the remote SMTP client,
+except that initial whitespace and the trailing &lt;CR&gt;&lt;LF&gt;
+are removed. The result value is executed by the Postfix SMTP
+server. </p>
+
+<p> There is no need to use smtpd_command_filter for the following
+cases: </p>
+
+<ul>
+
+<li> <p> Use "resolve_numeric_domain = yes" to accept
+"<i>user@ipaddress</i>". </p>
+
+<li> <p> Postfix already accepts the correct form
+"<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 "RCPT TO:&lt;<i>User
+Name &lt;user@example.com&gt;&gt;</i>". Postfix will ignore the "<i>User
+Name</i>" part and deliver to the <i>&lt;user@example.com&gt;</i> address.
+</p>
+
+</ul>
+
+<p> Examples of problems that can be solved with the smtpd_command_filter
+feature: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtpd_command_filter = pcre:/etc/postfix/command_filter
+</pre>
+
+<pre>
+/etc/postfix/command_filter:
+ # Work around clients that send malformed HELO commands.
+ /^HELO\s*$/ HELO domain.invalid
+</pre>
+
+<pre>
+ # Work around clients that send empty lines.
+ /^\s*$/ NOOP
+</pre>
+
+<pre>
+ # Work around clients that send RCPT TO:&lt;'user@domain'&gt;.
+ # WARNING: do not lose the parameters that follow the address.
+ /^(RCPT\s+TO:\s*&lt;)'([^[:space:]]+)'(&gt;.*)/ $1$2$3
+</pre>
+
+<pre>
+ # Append XVERP to MAIL FROM commands to request VERP-style delivery.
+ # See VERP_README for more information on how to use Postfix VERP.
+ /^(MAIL\s+FROM:\s*&lt;listname@example\.com&gt;.*)/ $1 XVERP
+</pre>
+
+<pre>
+ # Bounce-never mail sink. Use notify_classes=bounce,resource,software
+ # to send bounced mail to the postmaster (with message body removed).
+ /^(RCPT\s+TO:\s*&lt;.*&gt;.*)\s+NOTIFY=\S+(.*)/ $1 NOTIFY=NEVER$2
+ /^(RCPT\s+TO:.*)/ $1 NOTIFY=NEVER
+</pre>
+
+<p> This feature is available in Postfix 2.7. </p>
+
+%PARAM smtp_reply_filter
+
+<p> A mechanism to transform replies from remote SMTP servers one
+line at a time. This is a last-resort tool to work around server
+replies that break interoperability with the Postfix SMTP client.
+Other uses involve fault injection to test Postfix's handling of
+invalid responses. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> In the case of a multi-line reply, the Postfix SMTP client
+uses the final reply line's numerical SMTP reply code and enhanced
+status code. </p>
+
+<li> <p> The numerical SMTP reply code (XYZ) takes precedence over
+the enhanced status code (X.Y.Z). When the enhanced status code
+initial digit differs from the SMTP reply code initial digit, or
+when no enhanced status code is present, the Postfix SMTP client
+uses a generic enhanced status code (X.0.0) instead. </p>
+
+</ul>
+
+<p> Specify the name of a "type:table" lookup table. The search
+string is a single SMTP reply line as received from the remote SMTP
+server, except that the trailing &lt;CR&gt;&lt;LF&gt; are removed.
+When the lookup succeeds, the result replaces the single SMTP reply
+line. </p>
+
+<p> Examples: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtp_reply_filter = pcre:/etc/postfix/reply_filter
+</pre>
+
+<pre>
+/etc/postfix/reply_filter:
+ # Transform garbage into "250-filler..." so that it looks like
+ # one line from a multi-line reply. It does not matter what we
+ # substitute here as long it has the right syntax. The Postfix
+ # SMTP client will use the final line's numerical SMTP reply
+ # code and enhanced status code.
+ !/^([2-5][0-9][0-9]($|[- ]))/ 250-filler for garbage
+</pre>
+
+<p> This feature is available in Postfix 2.7. </p>
+
+%PARAM lmtp_reply_filter
+
+<p> The LMTP-specific version of the smtp_reply_filter
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.7 and later. </p>
+
+%PARAM smtp_tls_block_early_mail_reply no
+
+<p> Try to detect a mail hijacking attack based on a TLS protocol
+vulnerability (CVE-2009-3555), where an attacker prepends malicious
+HELO, MAIL, RCPT, DATA commands to a Postfix SMTP client TLS session.
+The attack would succeed with non-Postfix SMTP servers that reply
+to the malicious HELO, MAIL, RCPT, DATA commands after negotiating
+the Postfix SMTP client TLS session. </p>
+
+<p> This feature is available in Postfix 2.7. </p>
+
+%PARAM lmtp_tls_block_early_mail_reply
+
+<p> The LMTP-specific version of the smtp_tls_block_early_mail_reply
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.7 and later. </p>
+
+%PARAM empty_address_default_transport_maps_lookup_key &lt;&gt;
+
+<p> The sender_dependent_default_transport_maps search string that
+will be used instead of the null sender address. </p>
+
+<p> This feature is available in Postfix 2.7 and later. </p>
+
+%PARAM sender_dependent_default_transport_maps
+
+<p> A sender-dependent override for the global default_transport
+parameter setting. The tables are searched by the envelope sender
+address and @domain. A lookup result of DUNNO terminates the search
+without overriding the global default_transport parameter setting.
+This information is overruled with the transport(5) table. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> Note: this overrides default_transport, not transport_maps, and
+therefore the expected syntax is that of default_transport, not the
+syntax of transport_maps. Specifically, this does not support the
+transport_maps syntax for null transport, null nexthop, or null
+email addresses. </p>
+
+<p> For safety reasons, this feature does not allow $number
+substitutions in regular expression maps. </p>
+
+<p> This feature is available in Postfix 2.7 and later. </p>
+
+%PARAM address_verify_sender_dependent_default_transport_maps $sender_dependent_default_transport_maps
+
+<p> Overrides the sender_dependent_default_transport_maps parameter
+setting for address verification probes. </p>
+
+<p> This feature is available in Postfix 2.7 and later. </p>
+
+%PARAM default_filter_nexthop
+
+<p> When a content_filter or FILTER request specifies no explicit
+next-hop destination, use $default_filter_nexthop instead; when
+that value is empty, use the domain in the recipient address.
+Specify "default_filter_nexthop = $myhostname" for compatibility
+with Postfix version 2.6 and earlier, or specify an explicit next-hop
+destination with each content_filter value or FILTER action. </p>
+
+<p> This feature is available in Postfix 2.7 and later. </p>
+
+%PARAM smtp_address_preference any
+
+<p> The address type ("ipv6", "ipv4" or "any") that the Postfix
+SMTP client will try first, when a destination has IPv6 and IPv4
+addresses with equal MX preference. This feature has no effect
+unless the inet_protocols setting enables both IPv4 and IPv6. </p>
+
+<p> Postfix SMTP client address preference has evolved. With Postfix
+2.8 the default is "ipv6"; earlier implementations are hard-coded
+to prefer IPv6 over IPv4. </p>
+
+<p> Notes for mail delivery between sites that have both IPv4 and
+IPv6 connectivity: </p>
+
+<ul>
+
+<li> <p> The setting "smtp_address_preference = ipv6" is unsafe.
+It can fail to deliver mail when there is an outage that affects
+IPv6, while the destination is still reachable over IPv4. </p>
+
+<li> <p> The setting "smtp_address_preference = any" is safe. With
+this, mail will eventually be delivered even if there is an outage
+that affects IPv6 or IPv4, as long as it does not affect both. </p>
+
+</ul>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM lmtp_address_preference ipv6
+
+<p> The LMTP-specific version of the smtp_address_preference
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM smtp_dns_resolver_options
+
+<p> DNS Resolver options for the Postfix SMTP client. Specify zero
+or more of the following options, separated by comma or whitespace.
+Option names are case-sensitive. Some options refer to domain names
+that are specified in the file /etc/resolv.conf or equivalent. </p>
+
+<dl>
+
+<dt><b>res_defnames</b></dt>
+
+<dd> Append the current domain name to single-component names (those
+that do not contain a "." character). This can produce incorrect
+results, and is the hard-coded behavior prior to Postfix 2.8. </dd>
+
+<dt><b>res_dnsrch</b></dt>
+
+<dd> Search for host names in the current domain and in parent
+domains. This can produce incorrect results and is therefore not
+recommended. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM lmtp_dns_resolver_options
+
+<p> The LMTP-specific version of the smtp_dns_resolver_options
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM postscreen_dnsbl_threshold 1
+
+<p> The inclusive lower bound for blocking a remote SMTP client, based on
+its combined DNSBL score as defined with the postscreen_dnsbl_sites
+parameter. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_dnsbl_whitelist_threshold 0
+
+<p> Renamed to postscreen_dnsbl_allowlist_threshold in Postfix 3.6. </p>
+
+<p> This feature is available in Postfix 2.11 - 3.5. </p>
+
+%PARAM postscreen_dnsbl_allowlist_threshold 0
+
+<p> Allow a remote SMTP client to skip "before" and "after 220
+greeting" protocol tests, based on its combined DNSBL score as
+defined with the postscreen_dnsbl_sites parameter. </p>
+
+<p> Specify a negative value to enable this feature. When a client
+passes the postscreen_dnsbl_allowlist_threshold without having
+failed other tests, all pending or disabled tests are flagged as
+completed with a time-to-live value equal to postscreen_dnsbl_ttl.
+When a test was already completed, its time-to-live value is updated
+if it was less than postscreen_dnsbl_ttl. </p>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+<p> Available as postscreen_dnsbl_whitelist_threshold in Postfix 2.11
+- 3.5. </p>
+
+%PARAM postscreen_command_count_limit 20
+
+<p> The limit on the total number of commands per SMTP session for
+postscreen(8)'s built-in SMTP protocol engine. This SMTP engine
+defers or rejects all attempts to deliver mail, therefore there is
+no need to enforce separate limits on the number of junk commands
+and error commands. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_command_time_limit normal: 300s, overload: 10s
+
+<p> The time limit to read an entire command line with postscreen(8)'s
+built-in SMTP protocol engine. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_dnsbl_ttl 1h
+
+<p> The amount of time that postscreen(8) will use the result from
+a successful DNS-based reputation test before a client
+IP address is required to pass that test again. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is h (hours). </p>
+
+<p> This feature is available in Postfix 2.8-3.0. It was
+replaced by postscreen_dnsbl_max_ttl in Postfix 3.1. </p>
+
+%PARAM postscreen_dnsbl_min_ttl 60s
+
+<p> The minimum amount of time that postscreen(8) will use the
+result from a successful DNS-based reputation test before a
+client IP address is required to pass that test again. If the DNS
+reply specifies a larger TTL value, that value will be used unless
+it would be larger than postscreen_dnsbl_max_ttl. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 3.1. </p>
+
+%PARAM postscreen_dnsbl_max_ttl ${postscreen_dnsbl_ttl?{$postscreen_dnsbl_ttl}:{1}}h
+
+<p> The maximum amount of time that postscreen(8) will use the
+result from a successful DNS-based reputation test before a
+client IP address is required to pass that test again. If the DNS
+reply specifies a shorter TTL value, that value will be used unless
+it would be smaller than postscreen_dnsbl_min_ttl. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is h (hours). </p>
+
+<p> This feature is available in Postfix 3.1. The default setting
+is backwards-compatible with older Postfix versions. </p>
+
+%PARAM postscreen_pipelining_action enforce
+
+<p> The action that postscreen(8) takes when a remote SMTP client
+sends
+multiple commands instead of sending one command and waiting for
+the server to respond. Specify one of the following: </p>
+
+<dl>
+
+<dt> <b>ignore</b> </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Do <i>not</i> repeat this test before the result from some
+other test expires.
+This option is useful for testing and collecting statistics
+without blocking mail permanently. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_pipelining_ttl 30d
+
+<p> The amount of time that postscreen(8) will use the result from
+a successful "pipelining" SMTP protocol test. During this time, the
+client IP address is excluded from this test. The default is
+long because a good client must disconnect after it passes the test,
+before it can talk to a real Postfix SMTP server. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_pipelining_enable no
+
+<p> Enable "pipelining" SMTP protocol tests in the postscreen(8)
+server. These tests are expensive: a good client must disconnect
+after it passes the test, before it can talk to a real Postfix SMTP
+server. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_watchdog_timeout 10s
+
+<p> How much time a postscreen(8) process may take to respond to
+a remote SMTP client command or to perform a cache operation before it
+is terminated by a built-in watchdog timer. This is a safety
+mechanism that prevents postscreen(8) from becoming non-responsive
+due to a bug in Postfix itself or in system software. To avoid
+false alarms and unnecessary cache corruption this limit cannot be
+set under 10s. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_helo_required $smtpd_helo_required
+
+<p> Require that a remote SMTP client sends HELO or EHLO before
+commencing a MAIL transaction. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_forbidden_commands $smtpd_forbidden_commands
+
+<p> List of commands that the postscreen(8) server considers in
+violation of the SMTP protocol. See smtpd_forbidden_commands for
+syntax, and postscreen_non_smtp_command_action for possible actions.
+</p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_disable_vrfy_command $disable_vrfy_command
+
+<p> Disable the SMTP VRFY command in the postscreen(8) daemon. See
+disable_vrfy_command for details. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_non_smtp_command_action drop
+
+<p> The action that postscreen(8) takes when a remote SMTP client sends
+non-SMTP commands as specified with the postscreen_forbidden_commands
+parameter. Specify one of the following: </p>
+
+<dl>
+
+<dt> <b>ignore</b> </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Do <i>not</i> repeat this test before the result from some
+other test expires.
+This option is useful for testing and collecting statistics
+without blocking mail permanently. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. This action is the
+same as with the Postfix SMTP server's smtpd_forbidden_commands
+feature. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_non_smtp_command_ttl 30d
+
+<p> The amount of time that postscreen(8) will use the result from
+a successful "non_smtp_command" SMTP protocol test. During this
+time, the client IP address is excluded from this test. The default
+is long because a client must disconnect after it passes the test,
+before it can talk to a real Postfix SMTP server. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_non_smtp_command_enable no
+
+<p> Enable "non-SMTP command" tests in the postscreen(8) server. These
+tests are expensive: a client must disconnect after it passes the
+test, before it can talk to a real Postfix SMTP server. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_dnsbl_reply_map
+
+<p> A mapping from an actual DNSBL domain name which includes a secret
+password, to the DNSBL domain name that postscreen will reply with
+when it rejects mail. When no mapping is found, the actual DNSBL
+domain will be used. </p>
+
+<p> For maximal stability it is best to use a file that is read
+into memory such as pcre:, regexp: or texthash: (texthash: is similar
+to hash:, except a) there is no need to run postmap(1) before the
+file can be used, and b) texthash: does not detect changes after
+the file is read). </p>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ postscreen_dnsbl_reply_map = texthash:/etc/postfix/dnsbl_reply
+</pre>
+
+<pre>
+/etc/postfix/dnsbl_reply:
+ secret.zen.spamhaus.org zen.spamhaus.org
+</pre>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_dnsbl_timeout 10s
+
+<p> The time limit for DNSBL or DNSWL lookups. This is separate from
+the timeouts in the dnsblog(8) daemon which are defined by system
+resolver(3) routines. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 3.0. </p>
+%PARAM postscreen_bare_newline_action ignore
+
+<p> The action that postscreen(8) takes when a remote SMTP client sends
+a bare newline character, that is, a newline not preceded by carriage
+return. Specify one of the following: </p>
+
+<dl>
+
+<dt> <b>ignore</b> </dt>
+
+<dd> Ignore the failure of this test. Allow other tests to complete.
+Do <i>not</i> repeat this test before the result from some
+other test expires.
+This option is useful for testing and collecting statistics
+without blocking mail permanently. </dd>
+
+<dt> <b>enforce</b> </dt>
+
+<dd> Allow other tests to complete. Reject attempts to deliver mail
+with a 550 SMTP reply, and log the helo/sender/recipient information.
+Repeat this test the next time the client connects. </dd>
+
+<dt> <b>drop</b> </dt>
+
+<dd> Drop the connection immediately with a 521 SMTP reply. Repeat
+this test the next time the client connects. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_bare_newline_ttl 30d
+
+<p> The amount of time that postscreen(8) will use the result from
+a successful "bare newline" SMTP protocol test. During this
+time, the client IP address is excluded from this test. The default
+is long because a remote SMTP client must disconnect after it passes
+the test,
+before it can talk to a real Postfix SMTP server. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is d (days). </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_bare_newline_enable no
+
+<p> Enable "bare newline" SMTP protocol tests in the postscreen(8)
+server. These tests are expensive: a remote SMTP client must
+disconnect after
+it passes the test, before it can talk to a real Postfix SMTP server.
+</p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM postscreen_client_connection_count_limit $smtpd_client_connection_count_limit
+
+<p> How many simultaneous connections any remote SMTP client is
+allowed to have
+with the postscreen(8) daemon. By default, this limit is the same
+as with the Postfix SMTP server. Note that the triage process can
+take several seconds, with the time spent in postscreen_greet_wait
+delay, and with the time spent talking to the postscreen(8) built-in
+dummy SMTP protocol engine. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM dnsblog_reply_delay 0s
+
+<p> A debugging aid to artificially delay DNS responses. </p>
+
+<p> This feature is available in Postfix 2.8. </p>
+
+%PARAM reset_owner_alias no
+
+<p> Reset the local(8) delivery agent's idea of the owner-alias
+attribute, when delivering mail to a child alias that does not have
+its own owner alias. </p>
+
+<p> This feature is available in Postfix 2.8 and later. With older
+Postfix releases, the behavior is as if this parameter is set to
+"yes". </p>
+
+<p> As documented in aliases(5), when an alias <i>name</i> has a
+companion alias named owner-<i>name</i>, this will replace the
+envelope sender address, so that delivery errors will be
+reported to the owner alias instead of the sender. This configuration
+is recommended for mailing lists. <p>
+
+<p> A less known property of the owner alias is that it also forces
+the local(8) delivery agent to write local and remote addresses
+from alias expansion to a new queue file, instead of attempting to
+deliver mail to local addresses as soon as they come out of alias
+expansion. </p>
+
+<p> Writing local addresses from alias expansion to a new queue
+file allows for robust handling of temporary delivery errors: errors
+with one local member have no effect on deliveries to other members
+of the list. On the other hand, delivery to local addresses as
+soon as they come out of alias expansion is fragile: a temporary
+error with one local address from alias expansion will cause the
+entire alias to be expanded repeatedly until the error goes away,
+or until the message expires in the queue. In that case, a problem
+with one list member results in multiple message deliveries to other
+list members. </p>
+
+<p> The default behavior of Postfix 2.8 and later is to keep the
+owner-alias attribute of the parent alias, when delivering mail to
+a child alias that does not have its own owner alias. Then, local
+addresses from that child alias will be written to a new queue file,
+and a temporary error with one local address will not affect delivery
+to other mailing list members. </p>
+
+<p> Unfortunately, older Postfix releases reset the owner-alias
+attribute when delivering mail to a child alias that does not have
+its own owner alias. To be precise, this resets only the decision
+to create a new queue file, not the decision to override the envelope
+sender address. The local(8) delivery agent then attempts to
+deliver local addresses as soon as they come out of child alias
+expansion. If delivery to any address from child alias expansion
+fails with a temporary error condition, the entire mailing list may
+be expanded repeatedly until the mail expires in the queue, resulting
+in multiple deliveries of the same message to mailing list members.
+</p>
+
+%PARAM qmgr_ipc_timeout 60s
+
+<p> The time limit for the queue manager to send or receive information
+over an internal communication channel. The purpose is to break
+out of deadlock situations. If the time limit is exceeded the
+software either retries or aborts the operation. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM qmgr_daemon_timeout 1000s
+
+<p> How much time a Postfix queue manager process may take to handle
+a request before it is terminated by a built-in watchdog timer.
+</p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tls_preempt_cipherlist no
+
+<p> With SSLv3 and later, use the Postfix SMTP server's cipher
+preference order instead of the remote client's cipher preference
+order. </p>
+
+<p> By default, the OpenSSL server selects the client's most preferred
+cipher that the server supports. With SSLv3 and later, the server may
+choose its own most preferred cipher that is supported (offered) by
+the client. Setting "tls_preempt_cipherlist = yes" enables server cipher
+preferences. </p>
+
+<p> While server cipher selection may in some cases lead to a more secure
+or performant cipher choice, there is some risk of interoperability
+issues. In the past, some SSL clients have listed lower priority ciphers
+that they did not implement correctly. If the server chooses a cipher
+that the client prefers less, it may select a cipher whose client
+implementation is flawed. Most notably Windows 2003 Microsoft
+Exchange servers have flawed implementations of DES-CBC3-SHA, which
+OpenSSL considers stronger than RC4-SHA. Enabling server cipher-suite
+selection may create interoperability issues with Windows 2003
+Microsoft Exchange clients. </p>
+
+<p> This feature is available in Postfix 2.8 and later, in combination
+with OpenSSL 0.9.7 and later. </p>
+
+%PARAM tls_disable_workarounds see "postconf -d" output
+
+<p> List or bit-mask of OpenSSL bug work-arounds to disable. </p>
+
+<p> The OpenSSL toolkit includes a set of work-arounds for buggy SSL/TLS
+implementations. Applications, such as Postfix, that want to maximize
+interoperability ask the OpenSSL library to enable the full set of
+recommended work-arounds. </p>
+
+<p> From time to time, it is discovered that a work-around creates a
+security issue, and should no longer be used. If upgrading OpenSSL
+to a fixed version is not an option or an upgrade is not available
+in a timely manner, or in closed environments where no buggy clients
+or servers exist, it may be appropriate to disable some or all of the
+OpenSSL interoperability work-arounds. This parameter specifies which
+bug work-arounds to disable. </p>
+
+<p> If the value of the parameter is a hexadecimal long integer starting
+with "0x", the bug work-arounds corresponding to the bits specified in
+its value are removed from the <b>SSL_OP_ALL</b> work-around bit-mask
+(see openssl/ssl.h and SSL_CTX_set_options(3)). You can specify more
+bits than are present in SSL_OP_ALL, excess bits are ignored. Specifying
+0xFFFFFFFF disables all bug-workarounds on a 32-bit system. This should
+also be sufficient on 64-bit systems, until OpenSSL abandons support
+for 32-bit systems and starts using the high 32 bits of a 64-bit
+bug-workaround mask. </p>
+
+<p> Otherwise, the parameter is a white-space or comma separated list
+of specific named bug work-arounds chosen from the list below. It
+is possible that your OpenSSL version includes new bug work-arounds
+added after your Postfix source code was last updated, in that case
+you can only disable one of these via the hexadecimal syntax above. </p>
+
+<dl>
+
+<dt><b>CRYPTOPRO_TLSEXT_BUG</b></dt> <dd>New with GOST support in
+OpenSSL 1.0.0.</dd>
+
+<dt><b>DONT_INSERT_EMPTY_FRAGMENTS</b></dt> <dd>See
+SSL_CTX_set_options(3)</dd>
+
+<dt><b>LEGACY_SERVER_CONNECT</b></dt> <dd>See SSL_CTX_set_options(3)</dd>
+
+<dt><b>MICROSOFT_BIG_SSLV3_BUFFER</b></dt> <dd>See
+SSL_CTX_set_options(3)</dd>
+
+<dt><b>MICROSOFT_SESS_ID_BUG</b></dt> <dd>See SSL_CTX_set_options(3)</dd>
+
+<dt><b>MSIE_SSLV2_RSA_PADDING</b></dt> <dd> also aliased as
+<b>CVE-2005-2969</b>. Postfix 2.8 disables this work-around by
+default with OpenSSL versions that may predate the fix. Fixed in
+OpenSSL 0.9.7h and OpenSSL 0.9.8a.</dd>
+
+<dt><b>NETSCAPE_CHALLENGE_BUG</b></dt> <dd>See SSL_CTX_set_options(3)</dd>
+
+<dt><b>NETSCAPE_REUSE_CIPHER_CHANGE_BUG</b></dt> <dd> also aliased
+as <b>CVE-2010-4180</b>. Postfix 2.8 disables this work-around by
+default with OpenSSL versions that may predate the fix. Fixed in
+OpenSSL 0.9.8q and OpenSSL 1.0.0c.</dd>
+
+<dt><b>SSLEAY_080_CLIENT_DH_BUG</b></dt> <dd>See
+SSL_CTX_set_options(3)</dd>
+
+<dt><b>SSLREF2_REUSE_CERT_TYPE_BUG</b></dt> <dd>See
+SSL_CTX_set_options(3)</dd>
+
+<dt><b>TLS_BLOCK_PADDING_BUG</b></dt> <dd>See SSL_CTX_set_options(3)</dd>
+
+<dt><b>TLS_D5_BUG</b></dt> <dd>See SSL_CTX_set_options(3)</dd>
+
+<dt><b>TLS_ROLLBACK_BUG</b></dt> <dd>See SSL_CTX_set_options(3).
+This is disabled in OpenSSL 0.9.7 and later. Nobody should still
+be using 0.9.6! </dd>
+
+<dt><b>TLSEXT_PADDING</b></dt><dd>Postfix &ge; 3.4. See SSL_CTX_set_options(3).</dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tls_legacy_public_key_fingerprints no
+
+<p> A temporary migration aid for sites that use certificate
+<i>public-key</i> fingerprints with Postfix 2.9.0..2.9.5, which use
+an incorrect algorithm. This parameter has no effect on the certificate
+fingerprint support that is available since Postfix 2.2. </p>
+
+<p> Specify "tls_legacy_public_key_fingerprints = yes" temporarily,
+pending a migration from configuration files with incorrect Postfix
+2.9.0..2.9.5 certificate public-key finger prints, to the correct
+fingerprints used by Postfix 2.9.6 and later. To compute the correct
+certificate public-key fingerprints, see TLS_README. </p>
+
+<p> This feature is available in Postfix 2.9.6 and later. </p>
+
+%PARAM tlsproxy_watchdog_timeout 10s
+
+<p> How much time a tlsproxy(8) process may take to process local
+or remote I/O before it is terminated by a built-in watchdog timer.
+This is a safety mechanism that prevents tlsproxy(8) from becoming
+non-responsive due to a bug in Postfix itself or in system software.
+To avoid false alarms and unnecessary cache corruption this limit
+cannot be set under 10s. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.8 and later </p>
+
+%PARAM postscreen_discard_ehlo_keywords $smtpd_discard_ehlo_keywords
+
+<p> A case insensitive list of EHLO keywords (pipelining, starttls,
+auth, etc.) that the postscreen(8) server will not send in the EHLO
+response to a remote SMTP client. See smtpd_discard_ehlo_keywords
+for details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM postscreen_discard_ehlo_keyword_address_maps $smtpd_discard_ehlo_keyword_address_maps
+
+<p> Lookup tables, indexed by the remote SMTP client address, with
+case insensitive lists of EHLO keywords (pipelining, starttls, auth,
+etc.) that the postscreen(8) server will not send in the EHLO response
+to a remote SMTP client. See smtpd_discard_ehlo_keywords for details.
+The table is not searched by hostname for robustness reasons. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM postscreen_use_tls $smtpd_use_tls
+
+<p> Opportunistic TLS: announce STARTTLS support to remote SMTP clients,
+but do not require that clients use TLS encryption. </p>
+
+<p> This feature is available in Postfix 2.8 and later.
+Preferably, use postscreen_tls_security_level instead. </p>
+
+%PARAM postscreen_enforce_tls $smtpd_enforce_tls
+
+<p> Mandatory TLS: announce STARTTLS support to remote SMTP clients, and
+require that clients use TLS encryption. See smtpd_postscreen_enforce_tls
+for details. </p>
+
+<p> This feature is available in Postfix 2.8 and later.
+Preferably, use postscreen_tls_security_level instead. </p>
+
+%PARAM postscreen_tls_security_level $smtpd_tls_security_level
+
+<p> The SMTP TLS security level for the postscreen(8) server; when
+a non-empty value is specified, this overrides the obsolete parameters
+postscreen_use_tls and postscreen_enforce_tls. See smtpd_tls_security_level
+for details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_enforce_tls $smtpd_enforce_tls
+
+<p> Mandatory TLS: announce STARTTLS support to remote SMTP clients, and
+require that clients use TLS encryption. See smtpd_enforce_tls for
+further details. Use tlsproxy_tls_security_level instead. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_CAfile $smtpd_tls_CAfile
+
+<p> A file containing (PEM format) CA certificates of root CAs
+trusted to sign either remote SMTP client certificates or intermediate
+CA certificates. See smtpd_tls_CAfile for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_CApath $smtpd_tls_CApath
+
+<p> A directory containing (PEM format) CA certificates of root CAs
+trusted to sign either remote SMTP client certificates or intermediate
+CA certificates. See smtpd_tls_CApath for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_always_issue_session_ids $smtpd_tls_always_issue_session_ids
+
+<p> Force the Postfix tlsproxy(8) server to issue a TLS session id,
+even when TLS session caching is turned off. See
+smtpd_tls_always_issue_session_ids for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_ask_ccert $smtpd_tls_ask_ccert
+
+<p> Ask a remote SMTP client for a client certificate. See
+smtpd_tls_ask_ccert for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_ccert_verifydepth $smtpd_tls_ccert_verifydepth
+
+<p> The verification depth for remote SMTP client certificates. A
+depth of 1 is sufficient if the issuing CA is listed in a local CA
+file. See smtpd_tls_ccert_verifydepth for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_cert_file $smtpd_tls_cert_file
+
+<p> File with the Postfix tlsproxy(8) server RSA certificate in PEM
+format. This file may also contain the Postfix tlsproxy(8) server
+private RSA key. See smtpd_tls_cert_file for further details. With
+Postfix &ge; 3.4 the preferred way to configure tlsproxy server keys and
+certificates is via the "tlsproxy_tls_chain_files" parameter. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_ciphers $smtpd_tls_ciphers
+
+<p> The minimum TLS cipher grade that the Postfix tlsproxy(8) server
+will use with opportunistic TLS encryption. See smtpd_tls_ciphers
+for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_dcert_file $smtpd_tls_dcert_file
+
+<p> File with the Postfix tlsproxy(8) server DSA certificate in PEM
+format. This file may also contain the Postfix tlsproxy(8) server
+private DSA key. DSA is obsolete and should not be used. See
+smtpd_tls_dcert_file for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_dh1024_param_file $smtpd_tls_dh1024_param_file
+
+<p> File with DH parameters that the Postfix tlsproxy(8) server
+should use with non-export EDH ciphers. See smtpd_tls_dh1024_param_file
+for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_dh512_param_file $smtpd_tls_dh512_param_file
+
+<p> File with DH parameters that the Postfix tlsproxy(8) server
+should use with export-grade EDH ciphers. See smtpd_tls_dh512_param_file
+for further details. The default SMTP server cipher grade is
+"medium" with Postfix releases after the middle of 2015, and as a
+result export-grade cipher suites are by default not used. </p>
+
+<p> With Postfix &ge; 3.6 export-grade Diffie-Hellman key exchange
+is no longer supported, and this parameter is silently ignored. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_dkey_file $smtpd_tls_dkey_file
+
+<p> File with the Postfix tlsproxy(8) server DSA private key in PEM
+format. This file may be combined with the Postfix tlsproxy(8) server
+DSA certificate file specified with $smtpd_tls_dcert_file. DSA is
+obsolete and should not be used. See smtpd_tls_dkey_file for further
+details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_eccert_file $smtpd_tls_eccert_file
+
+<p> File with the Postfix tlsproxy(8) server ECDSA certificate in PEM
+format. This file may also contain the Postfix tlsproxy(8) server
+private ECDSA key. See smtpd_tls_eccert_file for further details. With
+Postfix &ge; 3.4 the preferred way to configure tlsproxy server keys and
+certificates is via the "tlsproxy_tls_chain_files" parameter. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_eckey_file $smtpd_tls_eckey_file
+
+<p> File with the Postfix tlsproxy(8) server ECDSA private key in PEM
+format. This file may be combined with the Postfix tlsproxy(8) server
+ECDSA certificate file specified with $smtpd_tls_eccert_file. See
+smtpd_tls_eckey_file for further details. With Postfix &ge; 3.4 the
+preferred way to configure tlsproxy server keys and certificates is via
+the "tlsproxy_tls_chain_files" parameter. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_eecdh_grade $smtpd_tls_eecdh_grade
+
+<p> The Postfix tlsproxy(8) server security grade for ephemeral
+elliptic-curve Diffie-Hellman (EECDH) key exchange. See
+smtpd_tls_eecdh_grade for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_exclude_ciphers $smtpd_tls_exclude_ciphers
+
+<p> List of ciphers or cipher types to exclude from the tlsproxy(8)
+server cipher list at all TLS security levels. See
+smtpd_tls_exclude_ciphers for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_fingerprint_digest $smtpd_tls_fingerprint_digest
+
+<p> The message digest algorithm to construct remote SMTP
+client-certificate
+fingerprints. See smtpd_tls_fingerprint_digest for further details.
+</p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_key_file $smtpd_tls_key_file
+
+<p> File with the Postfix tlsproxy(8) server RSA private key in PEM
+format. This file may be combined with the Postfix tlsproxy(8) server
+RSA certificate file specified with $smtpd_tls_cert_file. See
+smtpd_tls_key_file for further details. With Postfix &ge; 3.4 the
+preferred way to configure tlsproxy server keys and certificates is via
+the "tlsproxy_tls_chain_files" parameter. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_loglevel $smtpd_tls_loglevel
+
+<p> Enable additional Postfix tlsproxy(8) server logging of TLS
+activity. Each logging level also includes the information that
+is logged at a lower logging level. See smtpd_tls_loglevel for
+further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_mandatory_ciphers $smtpd_tls_mandatory_ciphers
+
+<p> The minimum TLS cipher grade that the Postfix tlsproxy(8) server
+will use with mandatory TLS encryption. See smtpd_tls_mandatory_ciphers
+for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_mandatory_exclude_ciphers $smtpd_tls_mandatory_exclude_ciphers
+
+<p> Additional list of ciphers or cipher types to exclude from the
+tlsproxy(8) server cipher list at mandatory TLS security levels.
+See smtpd_tls_mandatory_exclude_ciphers for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_mandatory_protocols $smtpd_tls_mandatory_protocols
+
+<p> The SSL/TLS protocols accepted by the Postfix tlsproxy(8) server
+with mandatory TLS encryption. If the list is empty, the server
+supports all available SSL/TLS protocol versions. See
+smtpd_tls_mandatory_protocols for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_protocols $smtpd_tls_protocols
+
+<p> List of TLS protocols that the Postfix tlsproxy(8) server will
+exclude or include with opportunistic TLS encryption. See
+smtpd_tls_protocols for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_req_ccert $smtpd_tls_req_ccert
+
+<p> With mandatory TLS encryption, require a trusted remote SMTP
+client certificate in order to allow TLS connections to proceed.
+See smtpd_tls_req_ccert for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_security_level $smtpd_tls_security_level
+
+<p> The SMTP TLS security level for the Postfix tlsproxy(8) server;
+when a non-empty value is specified, this overrides the obsolete
+parameters smtpd_use_tls and smtpd_enforce_tls. See
+smtpd_tls_security_level for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_tls_session_cache_timeout $smtpd_tls_session_cache_timeout
+
+<p> Obsolete expiration time of Postfix tlsproxy(8) server TLS session
+cache information. Since the cache is shared with smtpd(8) and managed
+by tlsmgr(8), there is only one expiration time for the SMTP server cache
+shared by all three services, namely smtpd_tls_session_cache_timeout. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_use_tls $smtpd_use_tls
+
+<p> Opportunistic TLS: announce STARTTLS support to remote SMTP clients,
+but do not require that clients use TLS encryption. See smtpd_use_tls
+for further details. Use tlsproxy_tls_security_level instead. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM smtpd_reject_footer
+
+<p> Optional information that is appended after each Postfix SMTP
+server
+4XX or 5XX response. </p>
+
+<p> The following example uses "\c" at the start of the template
+(supported in Postfix 2.10 and later) to suppress the line break
+between the reply text and the footer text. With earlier Postfix
+versions, the footer text always begins on a new line, and the "\c"
+is output literally. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtpd_reject_footer = \c. For assistance, call 800-555-0101.
+ Please provide the following information in your problem report:
+ time ($localtime), client ($client_address) and server
+ ($server_name).
+</pre>
+
+<p> Server response: </p>
+
+<pre>
+ 550-5.5.1 &lt;user@example&gt; Recipient address rejected: User
+ unknown. For assistance, call 800-555-0101. Please provide the
+ following information in your problem report: time (Jan 4 15:42:00),
+ client (192.168.1.248) and server (mail1.example.com).
+</pre>
+
+<p> Note: the above text is meant to make it easier to find the
+Postfix logfile records for a failed SMTP session. The text itself
+is not logged to the Postfix SMTP server's maillog file. </p>
+
+<p> Be sure to keep the text as short as possible. Long text may
+be truncated before it is logged to the remote SMTP client's maillog
+file, or before it is returned to the sender in a delivery status
+notification. </p>
+
+<p> The template text is not subject to Postfix configuration
+parameter $name expansion. Instead, this feature supports a limited
+number of $name attributes in the footer text. These attributes are
+replaced with their current value for the SMTP session. </p>
+
+<p> Note: specify $$name in footer text that is looked up from
+regexp: or pcre:-based smtpd_reject_footer_maps, otherwise the
+Postfix server will not use the footer text and will log a warning
+instead. </p>
+
+<dl>
+
+<dt> <b>client_address</b> </dt> <dd> The Client IP address that
+is logged in the maillog file. </dd>
+
+<dt> <b>client_port</b> </dt> <dd> The client TCP port that is
+logged in the maillog file. </dd>
+
+<dt> <b>localtime</b> </dt> <dd> The server local time (Mmm dd
+hh:mm:ss) that is logged in the maillog file. </dd>
+
+<dt> <b>server_name</b> </dt> <dd> The server's myhostname value.
+This attribute is made available for sites with multiple MTAs
+(perhaps behind a load-balancer), where the server name can help
+the server support team to quickly find the right log files. </dd>
+
+</dl>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> NOT SUPPORTED are other attributes such as sender, recipient,
+or main.cf parameters. </p>
+
+<li> <p> For safety reasons, text that does not match
+$smtpd_expansion_filter is censored. </p>
+
+</ul>
+
+<p> This feature supports the two-character sequence \n as a request
+for a line break in the footer text. Postfix automatically inserts
+after each line break the three-digit SMTP reply code (and optional
+enhanced status code) from the original Postfix reject message.
+</p>
+
+<p> To work around mail software that mis-handles multi-line replies,
+specify the two-character sequence \c at the start of the template.
+This suppresses the line break between the reply text and the footer
+text (Postfix 2.10 and later). </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM smtpd_reject_footer_maps
+
+<p> Lookup tables, indexed by the complete Postfix SMTP server 4xx or
+5xx response, with reject footer templates. See smtpd_reject_footer
+for details. </p>
+
+<p>
+Specify zero or more "type:name" lookup tables, separated by
+whitespace or comma. Tables will be searched in the specified order
+until a match is found.
+</p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM postscreen_expansion_filter see "postconf -d" output
+
+<p> List of characters that are permitted in postscreen_reject_footer
+attribute expansions. See smtpd_expansion_filter for further
+details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM postscreen_reject_footer $smtpd_reject_footer
+
+<p> Optional information that is appended after a 4XX or 5XX
+postscreen(8) server
+response. See smtpd_reject_footer for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM postscreen_reject_footer_maps $smtpd_reject_footer_maps
+
+<p> Optional lookup table for information that is appended after a 4XX
+or 5XX postscreen(8) server response. See smtpd_reject_footer_maps for
+further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM postscreen_command_filter $smtpd_command_filter
+
+<p> A mechanism to transform commands from remote SMTP clients.
+See smtpd_command_filter for further details. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM dnsblog_service_name dnsblog
+
+<p> The name of the dnsblog(8) service entry in master.cf. This
+service performs DNS allow/denylist lookups. </p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM tlsproxy_service_name tlsproxy
+
+<p> The name of the tlsproxy(8) service entry in master.cf. This
+service performs plaintext &lt;=&gt; TLS ciphertext conversion. <p>
+
+<p> This feature is available in Postfix 2.8 and later. </p>
+
+%PARAM smtpd_per_record_deadline normal: no, overload: yes
+
+<p> Change the behavior of the smtpd_timeout and smtpd_starttls_timeout
+time limits, from a
+time limit per read or write system call, to a time limit to send
+or receive a complete record (an SMTP command line, SMTP response
+line, SMTP message content line, or TLS protocol message). This
+limits the impact from hostile peers that trickle data one byte at
+a time. </p>
+
+<p> Note: when per-record deadlines are enabled, a short timeout
+may cause problems with TLS over very slow network connections.
+The reasons are that a TLS protocol message can be up to 16 kbytes
+long (with TLSv1), and that an entire TLS protocol message must be
+sent or received within the per-record deadline. </p>
+
+<p> This feature is available in Postfix 2.9-3.6. With older
+Postfix releases, the behavior is as if this parameter is set to
+"no". Postfix 3.7 and later use smtpd_per_request_deadline. </p>
+
+%PARAM smtp_per_record_deadline no
+
+<p> Change the behavior of the smtp_*_timeout time limits, from a
+time limit per read or write system call, to a time limit to send
+or receive a complete record (an SMTP command line, SMTP response
+line, SMTP message content line, or TLS protocol message). This
+limits the impact from hostile peers that trickle data one byte at
+a time. </p>
+
+<p> Note: when per-record deadlines are enabled, a short timeout
+may cause problems with TLS over very slow network connections.
+The reasons are that a TLS protocol message can be up to 16 kbytes
+long (with TLSv1), and that an entire TLS protocol message must be
+sent or received within the per-record deadline. </p>
+
+<p> This feature is available in Postfix 2.9-3.6. With older
+Postfix releases, the behavior is as if this parameter is set to
+"no". Postfix 3.7 and later use smtp_per_request_deadline. </p>
+
+%PARAM lmtp_per_record_deadline no
+
+<p> The LMTP-specific version of the smtp_per_record_deadline
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.9 and later. </p>
+
+%PARAM postscreen_whitelist_interfaces static:all
+
+<p> Renamed to postscreen_allowlist_interfaces in Postfix 3.6. </p>
+
+<p> This feature is available in Postfix 2.9 - 3.5. </p>
+
+%PARAM postscreen_allowlist_interfaces static:all
+
+<p> A list of local postscreen(8) server IP addresses where a
+non-allowlisted remote SMTP client can obtain postscreen(8)'s temporary
+allowlist status. This status is required before the client can
+talk to a Postfix SMTP server process. By default, a client can
+obtain postscreen(8)'s allowlist status on any local postscreen(8)
+server IP address. </p>
+
+<p> When postscreen(8) listens on both primary and backup MX
+addresses, the postscreen_allowlist_interfaces parameter can be
+configured to give the temporary allowlist status only when a client
+connects to a primary MX address. Once a client is allowlisted it
+can talk to a Postfix SMTP server on any address. Thus, clients
+that connect only to backup MX addresses will never become allowlisted,
+and will never be allowed to talk to a Postfix SMTP server process.
+</p>
+
+<p> Specify a list of network addresses or network/netmask patterns,
+separated by commas and/or whitespace. The netmask specifies the
+number of bits in the network part of a host address. Continue long
+lines by starting the next line with whitespace. </p>
+
+<p> You can also specify "/file/name" or "type:table" patterns. A
+"/file/name" pattern is replaced by its contents; a "type:table"
+lookup table is matched when a table entry matches a lookup string
+(the lookup result is ignored). </p>
+
+<p> The list is matched left to right, and the search stops on the
+first match. Specify "!pattern" to exclude an address or network
+block from the list. </p>
+
+<p> Note: IP version 6 address information must be specified inside
+[] in the postscreen_allowlist_interfaces value, and in files
+specified with "/file/name". IP version 6 addresses contain the
+":" character, and would otherwise be confused with a "type:table"
+pattern. </p>
+
+<p> Example: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Don't allowlist connections to the backup IP address.
+ # Postfix &lt; 3.6 use postscreen_whitelist_interfaces.
+ postscreen_allowlist_interfaces = !168.100.189.8, static:all
+</pre>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+<p> Available as postscreen_whitelist_interfaces in Postfix 2.9 - 3.5. </p>
+
+%PARAM postscreen_upstream_proxy_protocol
+
+<p> The name of the proxy protocol used by an optional before-postscreen
+proxy agent. When a proxy agent is used, this protocol conveys local
+and remote address and port information. Specify
+"postscreen_upstream_proxy_protocol = haproxy" to enable the haproxy
+protocol; version 2 is supported with Postfix 3.5 and later. <p>
+
+<p> This feature is available in Postfix 2.10 and later. </p>
+
+%PARAM postscreen_upstream_proxy_timeout 5s
+
+<p> The time limit for the proxy protocol specified with the
+postscreen_upstream_proxy_protocol parameter. </p>
+
+<p> This feature is available in Postfix 2.10 and later. </p>
+
+%PARAM smtpd_upstream_proxy_protocol
+
+<p> The name of the proxy protocol used by an optional before-smtpd
+proxy agent. When a proxy agent is used, this protocol conveys local
+and remote address and port information. Specify
+"smtpd_upstream_proxy_protocol = haproxy" to enable the haproxy
+protocol; version 2 is supported with Postfix 3.5 and later. </p>
+
+<p> NOTE: To use the nginx proxy with smtpd(8), enable the XCLIENT
+protocol with smtpd_authorized_xclient_hosts. This supports SASL
+authentication in the proxy agent (Postfix 2.9 and later). <p>
+
+<p> This feature is available in Postfix 2.10 and later. </p>
+
+%PARAM smtpd_upstream_proxy_timeout 5s
+
+<p> The time limit for the proxy protocol specified with the
+smtpd_upstream_proxy_protocol parameter. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.10 and later. </p>
+
+%PARAM enable_long_queue_ids no
+
+<p> Enable long, non-repeating, queue IDs (queue file names). The
+benefit of non-repeating names is simpler logfile analysis and
+easier queue migration (there is no need to run "postsuper" to
+change queue file names that don't match their message file inode
+number). </p>
+
+<p> Note: see below for how to convert long queue file names to
+Postfix &le; 2.8. </p>
+
+<p> Changing the parameter value to "yes" has the following effects:
+</p>
+
+<ul>
+
+<li> <p> Existing queue file names are not affected. </p>
+
+<li> <p> New queue files are created with names such as 3Pt2mN2VXxznjll.
+These are encoded in a 52-character alphabet that contains digits
+(0-9), upper-case letters (B-Z) and lower-case letters (b-z). For
+safety reasons the vowels (AEIOUaeiou) are excluded from the alphabet.
+The name format is: 6 or more characters for the time in seconds,
+4 characters for the time in microseconds, the 'z'; the remainder
+is the file inode number encoded in the first 51 characters of the
+52-character alphabet. </p>
+
+<li> <p> New messages have a Message-ID header with
+<i>queueID</i>@<i>myhostname</i>. </p>
+
+<li> <p> The mailq (postqueue -p) output has a wider Queue ID column.
+The number of whitespace-separated fields is not changed. <p>
+
+<li> <p> The hash_queue_depth algorithm uses the first characters
+of the queue file creation time in microseconds, after conversion
+into hexadecimal representation. This produces the same queue hashing
+behavior as if the queue file name was created with "enable_long_queue_ids
+= no". </p>
+
+</ul>
+
+<p> Changing the parameter value to "no" has the following effects:
+</p>
+
+<ul>
+
+<li> <p> Existing long queue file names are renamed to the short
+form (while running "postfix reload" or "postsuper"). </p>
+
+<li> <p> New queue files are created with names such as C3CD21F3E90
+from a hexadecimal alphabet that contains digits (0-9) and upper-case
+letters (A-F). The name format is: 5 characters for the time in
+microseconds; the remainder is the file inode number. </p>
+
+<li> <p> New messages have a Message-ID header with
+<i>YYYYMMDDHHMMSS.queueid</i>@<i>myhostname</i>, where
+<i>YYYYMMDDHHMMSS</i> are the year, month, day, hour, minute and
+second.
+
+<li> <p> The mailq (postqueue -p) output has the same format as
+with Postfix &le; 2.8. <p>
+
+<li> <p> The hash_queue_depth algorithm uses the first characters
+of the queue file name, with the hexadecimal representation of the
+file creation time in microseconds. </p>
+
+</ul>
+
+<p> Before migration to Postfix &le; 2.8, the following commands
+are required to convert long queue file names into short names: </p>
+
+<pre>
+# postfix stop
+# postconf enable_long_queue_ids=no
+# postsuper
+</pre>
+
+<p> Repeat the postsuper command until it reports no more queue file
+name changes. </p>
+
+<p> This feature is available in Postfix 2.9 and later. </p>
+
+%PARAM sendmail_fix_line_endings always
+
+<p> Controls how the Postfix sendmail command converts email message
+line endings from &lt;CR&gt;&lt;LF&gt; into UNIX format (&lt;LF&gt;).
+</p>
+
+<dl>
+
+<dt> <b>always</b> </dt> <dd> Always convert message lines ending
+in &lt;CR&gt;&lt;LF&gt;. This setting is the default with Postfix
+2.9 and later. </dd>
+
+<dt> <b>strict</b> </dt> <dd> Convert message lines ending in
+&lt;CR&gt;&lt;LF&gt; only if the first input line ends in
+&lt;CR&gt;&lt;LF&gt;. This setting is backwards-compatible with
+Postfix 2.8 and earlier. </dd>
+
+<dt> <b>never</b> </dt> <dd> Never convert message lines ending in
+&lt;CR&gt;&lt;LF&gt;. This setting exists for completeness only.
+</dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.9 and later. </p>
+
+%PARAM smtp_send_dummy_mail_auth no
+
+<p> Whether or not to append the "AUTH=&lt;&gt;" option to the MAIL
+FROM command in SASL-authenticated SMTP sessions. The default is
+not to send this, to avoid problems with broken remote SMTP servers.
+Before Postfix 2.9 the behavior is as if "smtp_send_dummy_mail_auth
+= yes".
+
+<p> This feature is available in Postfix 2.9 and later. </p>
+
+%PARAM lmtp_send_dummy_mail_auth no
+
+<p> The LMTP-specific version of the smtp_send_dummy_mail_auth
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.9 and later. </p>
+
+%PARAM address_verify_sender_ttl 0s
+
+<p> The time between changes in the time-dependent portion of address
+verification probe sender addresses. The time-dependent portion is
+appended to the localpart of the address specified with the
+address_verify_sender parameter. This feature is ignored when the
+probe sender addresses is the null sender, i.e. the address_verify_sender
+value is empty or &lt;&gt;. </p>
+
+<p> Historically, the probe sender address was fixed. This has
+caused such addresses to end up on spammer mailing lists, and has
+resulted in wasted network and processing resources. </p>
+
+<p> To enable time-dependent probe sender addresses, specify a
+non-zero time value. Specify a value of at least several hours,
+to avoid problems with senders that use greylisting. Avoid nice
+TTL values, to make the result less predictable. </p>
+
+<p> Specify a non-negative time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 2.9 and later. </p>
+
+%PARAM smtp_address_verify_target rcpt
+
+<p> In the context of email address verification, the SMTP protocol
+stage that determines whether an email address is deliverable.
+Specify one of "rcpt" or "data". The latter is needed with remote
+SMTP servers that reject recipients after the DATA command. Use
+transport_maps to apply this feature selectively: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ transport_maps = hash:/etc/postfix/transport
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/transport:
+ smtp-domain-that-verifies-after-data smtp-data-target:
+ lmtp-domain-that-verifies-after-data lmtp-data-target:
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/master.cf:
+ smtp-data-target unix - - n - - smtp
+ -o smtp_address_verify_target=data
+ lmtp-data-target unix - - n - - lmtp
+ -o lmtp_address_verify_target=data
+</pre>
+</blockquote>
+
+<p> Unselective use of the "data" target does no harm, but will
+result in unnecessary "lost connection after DATA" events at remote
+SMTP/LMTP servers. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM lmtp_address_verify_target rcpt
+
+<p> The LMTP-specific version of the smtp_address_verify_target
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM daemon_table_open_error_is_fatal no
+
+<p> How a Postfix daemon process handles errors while opening lookup
+tables: gradual degradation or immediate termination. </p>
+
+<dl>
+
+<dt> <b> no </b> (default) </dt> <dd> <p> Gradual degradation: a
+daemon process logs a message of type "error" and continues execution
+with reduced functionality. Features that do not depend on the
+unavailable table will work normally, while features that depend
+on the table will result in a type "warning" message. <br> When
+the notify_classes parameter value contains the "data" class, the
+Postfix SMTP server and client will report transcripts of sessions
+with an error because a table is unavailable. </p> </dd>
+
+<dt> <b> yes </b> (historical behavior) </dt> <dd> <p> Immediate
+termination: a daemon process logs a type "fatal" message and
+terminates immediately. This option reduces the number of possible
+code paths through Postfix, and may therefore be slightly more
+secure than the default. </p> </dd>
+
+</dl>
+
+<p> For the sake of sanity, the number of type "error" messages is
+limited to 13 over the lifetime of a daemon process. </p>
+
+<p> This feature is available in Postfix 2.9 and later. </p>
+
+%PARAM smtpd_log_access_permit_actions
+
+<p> Enable logging of the named "permit" actions in SMTP server
+access lists (by default, the SMTP server logs "reject" actions but
+not "permit" actions). This feature does not affect conditional
+actions such as "defer_if_permit". </p>
+
+<p> Specify a list of "permit" action names, "/file/name" or
+"type:table" patterns, separated by commas and/or whitespace. The
+list is matched left to right, and the search stops on the first
+match. A "/file/name" pattern is replaced by its contents; a
+"type:table" lookup table is matched when a name matches a lookup
+key (the lookup result is ignored). Continue long lines by starting
+the next line with whitespace. Specify "!pattern" to exclude a name
+from the list. </p>
+
+<p> Examples: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Log all "permit" actions.
+ smtpd_log_access_permit_actions = static:all
+</pre>
+
+<pre>
+/etc/postfix/main.cf:
+ # Log "permit_dnswl_client" only.
+ smtpd_log_access_permit_actions = permit_dnswl_client
+</pre>
+
+<p> This feature is available in Postfix 2.10 and later. </p>
+
+%PARAM smtp_dns_support_level
+
+<p> Level of DNS support in the Postfix SMTP client. With
+"smtp_dns_support_level" left at its empty default value, the legacy
+"disable_dns_lookups" parameter controls whether DNS is enabled in
+the Postfix SMTP client, otherwise the legacy parameter is ignored.
+</p>
+
+<p> Specify one of the following: </p>
+
+<dl>
+
+<dt><b>disabled</b></dt>
+
+<dd>Disable DNS lookups. No MX lookups are performed and hostname
+to address lookups are unconditionally "native". This setting is
+not appropriate for hosts that deliver mail to the public Internet.
+Some obsolete how-to documents recommend disabling DNS lookups in
+some configurations with content_filters. This is no longer required
+and strongly discouraged. </dd>
+
+<dt><b>enabled</b></dt>
+
+<dd>Enable DNS lookups. Nexthop destination domains not enclosed
+in "[]" will be subject to MX lookups. If "dns" and "native" are
+included in the "smtp_host_lookup" parameter value, DNS will be
+queried first to resolve MX-host A records, followed by "native"
+lookups if no answer is found in DNS. </dd>
+
+<dt><b>dnssec</b></dt>
+
+<dd>Enable <a href="https://tools.ietf.org/html/rfc4033">DNSSEC</a>
+lookups. The "dnssec" setting differs from the "enabled" setting
+above in the following ways: <ul> <li>Any MX lookups will set
+RES_USE_DNSSEC and RES_USE_EDNS0 to request DNSSEC-validated
+responses. If the MX response is DNSSEC-validated the corresponding
+hostnames are considered validated. <li> The address lookups of
+validated hostnames are also validated, (provided of course
+"smtp_host_lookup" includes "dns", see below). <li>Temporary
+failures in DNSSEC-enabled hostname-to-address resolution block any
+"native" lookups. Additional "native" lookups only happen when
+DNSSEC lookups hard-fail (NODATA or NXDOMAIN). </ul> </dd>
+
+</dl>
+
+<p> The Postfix SMTP client considers non-MX "[nexthop]" and
+"[nexthop]:port" destinations equivalent to statically-validated
+MX records of the form "nexthop. IN MX 0 nexthop." Therefore,
+with "dnssec" support turned on, validated hostname-to-address
+lookups apply to the nexthop domain of any "[nexthop]" or
+"[nexthop]:port" destination. This is also true for LMTP "inet:host"
+and "inet:host:port" destinations, as LMTP hostnames are never
+subject to MX lookups. </p>
+
+<p>The "dnssec" setting is recommended only if you plan to use the
+<a href="TLS_README.html#client_tls_dane">dane</a> or <a
+href="TLS_README.html#client_tls_dane">dane-only</a> TLS security
+level, otherwise enabling DNSSEC support in Postfix offers no
+additional security. Postfix DNSSEC support relies on an upstream
+recursive nameserver that validates DNSSEC signatures. Such a DNS
+server will always filter out forged DNS responses, even when Postfix
+itself is not configured to use DNSSEC. </p>
+
+<p> When using Postfix DANE support the "smtp_host_lookup" parameter
+should include "dns", as <a
+href="https://tools.ietf.org/html/rfc7672">DANE</a> is not applicable
+to hosts resolved via "native" lookups. </p>
+
+<p> As mentioned above, Postfix is not a validating <a
+href="https://tools.ietf.org/html/rfc4035#section-4.9">stub
+resolver</a>; it relies on the system's configured DNSSEC-validating
+<a href="https://tools.ietf.org/html/rfc4035#section-3.2">recursive
+nameserver</a> to perform all DNSSEC validation. Since this
+nameserver's DNSSEC-validated responses will be fully trusted, it
+is strongly recommended that the MTA host have a local DNSSEC-validating
+recursive caching nameserver listening on a loopback address, and
+be configured to use only this nameserver for all lookups. Otherwise,
+Postfix may remain subject to man-in-the-middle attacks that forge
+responses from the recursive nameserver</p>
+
+<p>DNSSEC support requires a version of Postfix compiled against a
+reasonably-modern DNS resolver(3) library that implements the
+RES_USE_DNSSEC and RES_USE_EDNS0 resolver options. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM lmtp_dns_support_level
+
+<p> The LMTP-specific version of the smtp_dns_support_level
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM smtp_tls_trust_anchor_file
+
+<p> Zero or more PEM-format files with trust-anchor certificates
+and/or public keys. If the parameter is not empty the root CAs in
+CAfile and CApath are no longer trusted. Rather, the Postfix SMTP
+client will only trust certificate-chains signed by one of the
+trust-anchors contained in the chosen files. The specified
+trust-anchor certificates and public keys are not subject to
+expiration, and need not be (self-signed) root CAs. They may, if
+desired, be intermediate certificates. Therefore, these certificates
+also may be found "in the middle" of the trust chain presented by
+the remote SMTP server, and any untrusted issuing parent certificates
+will be ignored. Specify a list of pathnames separated by comma
+or whitespace. </p>
+
+<p> Whether specified in main.cf, or on a per-destination basis,
+the trust-anchor PEM file must be accessible to the Postfix SMTP
+client in the chroot jail if applicable. The trust-anchor file
+should contain only certificates and public keys, no private key
+material, and must be readable by the non-privileged $mail_owner
+user. This allows destinations to be bound to a set of specific
+CAs or public keys without trusting the same CAs for all destinations.
+</p>
+
+<p> The main.cf parameter supports single-purpose Postfix installations
+that send mail to a fixed set of SMTP peers. At most sites, if
+trust-anchor files are used at all, they will be specified on a
+per-destination basis via the "tafile" attribute of the "verify"
+and "secure" levels in smtp_tls_policy_maps. </p>
+
+<p> The underlying mechanism is in support of RFC 7672 (DANE TLSA),
+which defines mechanisms for an SMTP client MTA to securely determine
+server TLS certificates via DNS. </p>
+
+<p> If you want your trust anchors to be public keys, with OpenSSL
+you can extract a single PEM public key from a PEM X.509 file
+containing a single certificate, as follows: </p>
+
+<blockquote>
+<pre>
+$ openssl x509 -in cert.pem -out ta-key.pem -noout -pubkey
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM lmtp_tls_trust_anchor_file
+
+<p> The LMTP-specific version of the smtp_tls_trust_anchor_file
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM tls_dane_trust_anchor_digest_enable yes
+
+<p> Enable support for RFC 6698 (DANE TLSA) DNS records that contain
+digests of trust-anchors with certificate usage "2". Do not change
+this setting from its default value. </p>
+
+<p> This feature is available in Postfix 2.11 through 3.1. It has
+been withdrawn in Postfix 3.2, as trust-anchor TLSA records are now
+widely used and have proved sufficiently reliable. Postfix 3.2 and
+later ignore this configuration parameter and behaves as though it
+were set to "yes". </p>
+
+%PARAM tls_wildcard_matches_multiple_labels yes
+
+<p> Match multiple DNS labels with "*" in wildcard certificates.
+</p>
+
+<p> Some mail service providers prepend the customer domain name
+to a base domain for which they have a wildcard TLS certificate.
+For example, the MX records for example.com hosted by example.net
+may be: </p>
+
+<blockquote>
+<pre>
+example.com. IN MX 0 example.com.mx1.example.net.
+example.com. IN MX 0 example.com.mx2.example.net.
+</pre>
+</blockquote>
+
+<p> and the TLS certificate may be for "*.example.net". The "*"
+then corresponds with multiple labels in the mail server domain
+name. While multi-label wildcards are not widely supported, and
+are not blessed by any standard, there is little to be gained by
+disallowing their use in this context. </p>
+
+<p> Notes: <p>
+
+<ul>
+
+<li> <p> In a certificate name, the "*" is special only when it is
+used as the first label. </p>
+
+<li> <p> While Postfix (2.11 or later) can match "*" with multiple
+domain name labels, other implementations likely will not. </p>
+
+<li> <p> Earlier Postfix implementations behave as if
+"tls_wildcard_matches_multiple_labels = no". </p>
+
+</ul>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM tls_ssl_options
+
+<p> List or bit-mask of OpenSSL options to enable. </p>
+
+<p> The OpenSSL toolkit provides a set of options that applications
+can enable to tune the OpenSSL behavior. Some of these work around
+bugs in other implementations and are on by default. You can use
+the tls_disable_workarounds parameter to selectively disable some
+or all of the bug work-arounds, making OpenSSL more strict at the
+cost of non-interoperability with SSL clients or servers that exhibit
+the bugs. </p>
+
+<p> Other options are off by default, and typically enable or disable
+features rather than bug work-arounds. These may be turned on (with
+care) via the tls_ssl_options parameter. The value is a white-space
+or comma separated list of named options chosen from the list below.
+The names are not case-sensitive, you can use lower-case if you
+prefer. The upper case values below match the corresponding macro
+name in the ssl.h header file with the SSL_OP_ prefix removed. It
+is possible that your OpenSSL version includes new options added
+after your Postfix source code was last updated, in that case you
+can only enable one of these via the hexadecimal syntax below. </p>
+
+<p> You should only enable features via the hexadecimal mask when
+the need to control the feature is critical (to deal with a new
+vulnerability or a serious interoperability problem). Postfix DOES
+NOT promise backwards compatible behavior with respect to the mask
+bits. A feature enabled via the mask in one release may be enabled
+by other means in a later release, and the mask bit will then be
+ignored. Therefore, use of the hexadecimal mask is only a temporary
+measure until a new Postfix or OpenSSL release provides a better
+solution. </p>
+
+<p> If the value of the parameter is a hexadecimal long integer
+starting with "0x", the options corresponding to the bits specified
+in its value are enabled (see openssl/ssl.h and SSL_CTX_set_options(3)).
+You can only enable options not already controlled by other Postfix
+settings. For example, you cannot disable protocols or enable
+server cipher preference. Do not attempt to enable all features by
+specifying 0xFFFFFFFF, this is unlikely to be a good idea. Some
+bug work-arounds are also valid here, allowing them to be re-enabled
+if/when they're no longer enabled by default. The supported values
+include: </p>
+
+<dl>
+
+<dt><b>ENABLE_MIDDLEBOX_COMPAT</b></dt> <dd>Postfix &ge; 3.4. See
+SSL_CTX_set_options(3).</dd>
+
+<dt><b>LEGACY_SERVER_CONNECT</b></dt> <dd>See SSL_CTX_set_options(3).</dd>
+
+<dt><b>NO_TICKET</b></dt> <dd>Enabled by default when needed in
+fully-patched Postfix &ge; 2.7. Not needed at all for Postfix &ge;
+2.11, unless for some reason you do not want to support TLS session
+resumption. Best not set explicitly. See SSL_CTX_set_options(3).</dd>
+
+<dt><b>NO_COMPRESSION</b></dt> <dd>Disable SSL compression even if
+supported by the OpenSSL library. Compression is CPU-intensive,
+and compression before encryption does not always improve security. </dd>
+
+<dt><b>NO_RENEGOTIATION</b></dt> <dd>Postfix &ge; 3.4. This can
+reduce opportunities for a potential CPU exhaustion attack. See
+SSL_CTX_set_options(3).</dd>
+
+<dt><b>NO_SESSION_RESUMPTION_ON_RENEGOTIATION</b></dt> <dd>Postfix
+&ge; 3.4. See SSL_CTX_set_options(3).</dd>
+
+<dt><b>PRIORITIZE_CHACHA</b></dt> <dd>Postfix &ge; 3.4. See SSL_CTX_set_options(3).</dd>
+
+</dl>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM tlsmgr_service_name tlsmgr
+
+<p> The name of the tlsmgr(8) service entry in master.cf. This
+service maintains TLS session caches and other information in support
+of TLS. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM lmtp_connection_reuse_count_limit 0
+
+<p> The LMTP-specific version of the smtp_connection_reuse_count_limit
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM smtp_connection_reuse_count_limit 0
+
+<p> When SMTP connection caching is enabled, the number of times
+that an SMTP session may be reused before it is closed, or zero (no
+limit). With a reuse count limit of N, a connection is used up to
+N+1 times. </p>
+
+<p> NOTE: This feature is unsafe. When a high-volume destination
+has multiple inbound MTAs, then the slowest inbound MTA will attract
+the most connections to that destination. This limitation does not
+exist with the smtp_connection_reuse_time_limit feature. </p>
+
+<p> This feature is available in Postfix 2.11. </p>
+
+%PARAM lmtp_tls_force_insecure_host_tlsa_lookup no
+
+<p> The LMTP-specific version of the smtp_tls_force_insecure_host_tlsa_lookup
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM smtp_tls_force_insecure_host_tlsa_lookup no
+
+<p> Lookup the associated DANE TLSA RRset even when a hostname is
+not an alias and its address records lie in an unsigned zone. This
+is unlikely to ever yield DNSSEC validated results, since child
+zones of unsigned zones are also unsigned in the absence of DLV or
+locally configured non-root trust-anchors. We anticipate that such
+mechanisms will not be used for just the "_tcp" subdomain of a host.
+Suppressing the TLSA RRset lookup reduces latency and avoids potential
+interoperability problems with nameservers for unsigned zones that
+are not prepared to handle the new TLSA RRset. </p>
+
+<p> This feature is available in Postfix 2.11. </p>
+
+%PARAM tls_dane_digest_agility on
+
+<p> Configure RFC7671 DANE TLSA digest algorithm agility.
+Do not change this setting from its default value. </p>
+
+<p> See Section 8 of RFC7671 for correct key rotation procedures. </p>
+
+<p> This feature is available in Postfix 2.11 through 3.1. Postfix
+3.2 and later ignore this configuration parameter and behave as
+though it were set to "on". </p>
+
+%PARAM tls_dane_digests sha512 sha256
+
+<p> DANE TLSA (RFC 6698, RFC 7671, RFC 7672) resource-record "matching
+type" digest algorithms in descending preference order. All the
+specified algorithms must be supported by the underlying OpenSSL
+library, otherwise the Postfix SMTP client will not support DANE
+TLSA security. </p>
+
+<p> Specify a list of digest names separated by commas and/or
+whitespace. Each digest name may be followed by an optional
+"=&lt;number&gt;" suffix. For example, "sha512" may instead be specified
+as "sha512=2" and "sha256" may instead be specified as "sha256=1".
+The optional number must match the <a
+href="https://www.iana.org/assignments/dane-parameters/dane-parameters.xhtml#matching-types"
+>IANA</a> assigned TLSA matching type number the algorithm in question.
+Postfix will check this constraint for the algorithms it knows about.
+Additional matching type algorithms registered with IANA can be added
+with explicit numbers provided they are supported by OpenSSL. </p>
+
+<p> Invalid list elements are logged with a warning and disable DANE
+support. TLSA RRs that specify digests not included in the list are
+ignored with a warning. </p>
+
+<p> Note: It is unwise to omit sha256 from the digest list. This
+digest algorithm is the only mandatory to implement digest algorithm
+in RFC 6698, and many servers are expected to publish TLSA records
+with just sha256 digests. Unless one of the standard digests is
+seriously compromised and servers have had ample time to update their
+TLSA records you should not omit any standard digests, just arrange
+them in order from strongest to weakest. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM tls_session_ticket_cipher Postfix &ge; 3.0: aes-256-cbc, Postfix &lt; 3.0: aes-128-cbc
+
+<p> Algorithm used to encrypt RFC5077 TLS session tickets. This
+algorithm must use CBC mode, have a 128-bit block size, and must
+have a key length between 128 and 256 bits. The default is
+aes-256-cbc. Overriding the default to choose a different algorithm
+is discouraged. </p>
+
+<p> Setting this parameter empty disables session ticket support
+in the Postfix SMTP server. Another way to disable session ticket
+support is via the tls_ssl_options parameter. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM tls_fast_shutdown_enable yes
+
+<p> A workaround for implementations that hang Postfix while shutting
+down a TLS session, until Postfix times out. With this enabled,
+Postfix will not wait for the remote TLS peer to respond to a TLS
+'close' notification. This behavior is recommended for TLSv1.0 and
+later. </p>
+
+%PARAM default_delivery_status_filter
+
+<p> Optional filter to replace the delivery status code or explanatory
+text of successful or unsuccessful deliveries. This does not allow
+the replacement of a successful status code (2.X.X) with an
+unsuccessful status code (4.X.X or 5.X.X) or vice versa. </p>
+
+<p> Note: the (smtp|lmtp)_delivery_status_filter is applied only
+once per recipient: when delivery is successful, when delivery is
+rejected with 5XX, or when there are no more alternate MX or A
+destinations. Use smtp_reply_filter or lmtp_reply_filter to inspect
+responses for all delivery attempts. </p>
+
+<p> The following parameters can be used to implement a filter for
+specific delivery agents: lmtp_delivery_status_filter,
+local_delivery_status_filter, pipe_delivery_status_filter,
+smtp_delivery_status_filter or virtual_delivery_status_filter. These
+parameters support the same filter syntax as described here. </p>
+
+<p> Specify zero or more "type:table" lookup table names, separated
+by comma or whitespace. For each successful or unsuccessful delivery
+to a recipient, the tables are queried in the specified order with
+one line of text that is structured as follows: </p>
+
+<blockquote>
+enhanced-status-code SPACE explanatory-text
+</blockquote>
+
+<p> The first table match wins. The lookup result must have the
+same structure as the query, a successful status code (2.X.X) must
+be replaced with a successful status code, an unsuccessful status
+code (4.X.X or 5.X.X) must be replaced with an unsuccessful status
+code, and the explanatory text field must be non-empty. Other results
+will result in a warning. </p>
+
+<p> Example 1: convert specific soft TLS errors into hard errors,
+by overriding the first number in the enhanced status code. </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_delivery_status_filter = pcre:/etc/postfix/smtp_dsn_filter
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/smtp_dsn_filter:
+ /^4(\.\d+\.\d+ TLS is required, but host \S+ refused to start TLS: .+)/
+ 5$1
+ /^4(\.\d+\.\d+ TLS is required, but was not offered by host .+)/
+ 5$1
+ # Do not change the following into hard bounces. They may
+ # result from a local configuration problem.
+ # 4.\d+.\d+ TLS is required, but our TLS engine is unavailable
+ # 4.\d+.\d+ TLS is required, but unavailable
+ # 4.\d+.\d+ Cannot start TLS: handshake failure
+</pre>
+</blockquote>
+
+<p> Example 2: censor the per-recipient delivery status text so
+that it does not reveal the destination command or filename
+when a remote sender requests confirmation of successful delivery.
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ local_delivery_status_filter = pcre:/etc/postfix/local_dsn_filter
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/local_dsn_filter:
+ /^(2\S+ delivered to file).+/ $1
+ /^(2\S+ delivered to command).+/ $1
+</pre>
+</blockquote>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> This feature will NOT override the soft_bounce safety net. </p>
+
+<li> <p> This feature will change the enhanced status code and text
+that is logged to the maillog file, and that is reported to the
+sender in delivery confirmation or non-delivery notifications.
+</p>
+
+</ul>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtp_delivery_status_filter $default_delivery_status_filter
+
+<p> Optional filter for the smtp(8) delivery agent to change the
+delivery status code or explanatory text of successful or unsuccessful
+deliveries. See default_delivery_status_filter for details. </p>
+
+<p> NOTE: This feature modifies Postfix SMTP client error or non-error
+messages that may or may not be derived from remote SMTP server
+responses. In contrast, the smtp_reply_filter feature modifies
+remote SMTP server responses only. </p>
+
+%PARAM lmtp_delivery_status_filter
+
+<p> The LMTP-specific version of the smtp_delivery_status_filter
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM pipe_delivery_status_filter $default_delivery_status_filter
+
+<p> Optional filter for the pipe(8) delivery agent to change the
+delivery status code or explanatory text of successful or unsuccessful
+deliveries. See default_delivery_status_filter for details. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM virtual_delivery_status_filter $default_delivery_status_filter
+
+<p> Optional filter for the virtual(8) delivery agent to change the
+delivery status code or explanatory text of successful or unsuccessful
+deliveries. See default_delivery_status_filter for details. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM local_delivery_status_filter $default_delivery_status_filter
+
+<p> Optional filter for the local(8) delivery agent to change the
+status code or explanatory text of successful or unsuccessful
+deliveries. See default_delivery_status_filter for details. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM shlib_directory see 'postconf -d' output
+
+<p> The location of Postfix dynamically-linked libraries
+(libpostfix-*.so), and the default location of Postfix database
+plugins (postfix-*.so) that have a relative pathname in the
+dynamicmaps.cf file. The shlib_directory parameter defaults to
+"no" when Postfix dynamically-linked libraries and database plugins
+are disabled at compile time, otherwise it typically defaults to
+/usr/lib/postfix or /usr/local/lib/postfix. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> The directory specified with shlib_directory should contain
+only Postfix-related files. Postfix dynamically-linked libraries
+and database plugins should not be installed in a "public" system
+directory such as /usr/lib or /usr/local/lib. Linking Postfix
+dynamically-linked library files or database plugins into non-Postfix
+programs is not supported. Postfix dynamically-linked libraries
+and database plugins implement a Postfix-internal API that changes
+without maintaining compatibility. </p>
+
+<li> <p> You can change the shlib_directory value after Postfix is
+built. However, you may have to run ldconfig or equivalent to prevent
+Postfix programs from failing because the libpostfix-*.so files are
+not found. No ldconfig command is needed if you keep the libpostfix-*.so
+files in the compiled-in default $shlib_directory location. </p>
+
+</ul>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM meta_directory see 'postconf -d' output
+
+<p> The location of non-executable files that are shared among
+multiple Postfix instances, such as postfix-files, dynamicmaps.cf,
+and the multi-instance template files main.cf.proto and master.cf.proto.
+This directory should contain only Postfix-related files. Typically,
+the meta_directory parameter has the same default as the config_directory
+parameter (/etc/postfix or /usr/local/etc/postfix). </p>
+
+<p> For backwards compatibility with Postfix versions 2.6..2.11,
+specify "meta_directory = $daemon_directory" in main.cf before
+installing or upgrading Postfix, or specify "meta_directory =
+/path/name" on the "make makefiles", "make install" or "make upgrade"
+command line. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtpd_policy_service_default_action 451 4.3.5 Server configuration problem
+
+<p> The default action when an SMTPD policy service request fails.
+Specify "DUNNO" to behave as if the failed SMTPD policy service
+request was not sent, and to continue processing other access
+restrictions, if any. </p>
+
+<p> Limitations: </p>
+
+<ul>
+
+<li> <p> This parameter may specify any value that would be a valid
+SMTPD policy server response (or access(5) map lookup result). An
+access(5) map or policy server in this parameter value may need to
+be declared in advance with a restriction_class setting. </p>
+
+<li> <p> If the specified action invokes another check_policy_service
+request, that request will have the built-in default action. </p>
+
+</ul>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtpd_policy_service_try_limit 2
+
+<p> The maximal number of attempts to send an SMTPD policy service
+request before giving up. Specify a value greater than zero. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtpd_policy_service_retry_delay 1s
+
+<p> The delay between attempts to resend a failed SMTPD policy
+service request. Specify a value greater than zero. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtputf8_enable yes
+
+<p> Enable preliminary SMTPUTF8 support for the protocols described
+in RFC 6531, RFC 6532, and RFC 6533. This requires that Postfix is
+built to support these protocols. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM strict_smtputf8 no
+
+<p> Enable stricter enforcement of the SMTPUTF8 protocol. The Postfix
+SMTP server accepts UTF8 sender or recipient addresses only when
+the client requests an SMTPUTF8 mail transaction. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtputf8_autodetect_classes sendmail, verify
+
+<p> Detect that a message requires SMTPUTF8 support for the specified
+mail origin classes. This is a workaround to avoid chicken-and-egg
+problems during the initial SMTPUTF8 roll-out in environments with
+pre-existing mail flows that contain UTF8. Those mail flows should
+not break because Postfix suddenly refuses to deliver such mail
+to down-stream MTAs that don't announce SMTPUTF8 support. </p>
+
+<p> The problem is that Postfix cannot rely solely on the sender's
+declaration that a message requires SMTPUTF8 support, because UTF8
+may be introduced during local processing (for example, the client
+hostname in Postfix's Received: header, adding @$myorigin or
+.$mydomain to an incomplete address, address rewriting, alias
+expansion, automatic BCC recipients, local forwarding, and changes
+made by header checks or Milter applications). </p>
+
+<p> For now, the default is to enable "SMTPUTF8 required" autodetection
+only for Postfix sendmail command-line submissions and address
+verification probes. This may change once SMTPUTF8 support achieves
+world domination. However, sites that add UTF8 content via local
+processing (see above) should autodetect the need for SMTPUTF8
+support for all email.</p>
+
+<p> Specify one or more of the following: </p>
+
+<dl compact>
+
+<dt> <b> sendmail </b> </dt> <dd> Submission with the Postfix
+sendmail(1) command. </dd>
+
+<dt> <b> smtpd </b> </dt> <dd> Mail received with the smtpd(8)
+daemon. </dd>
+
+<dt> <b> qmqpd </b> </dt> <dd> Mail received with the qmqpd(8)
+daemon. </dd>
+
+<dt> <b> forward </b> </dt> <dd> Local forwarding or aliasing. When
+a message is received with "SMTPUTF8 required", then the forwarded
+(aliased) message always has "SMTPUTF8 required". </dd>
+
+<dt> <b> bounce </b> </dt> <dd> Submission by the bounce(8) daemon.
+When a message is received with "SMTPUTF8 required", then the
+delivery status notification always has "SMTPUTF8 required". </dd>
+
+<dt> <b> notify </b> </dt> <dd> Postmaster notification from the
+smtp(8) or smtpd(8) daemon. </dd>
+
+<dt> <b> verify </b> </dt> <dd> Address verification probe from the
+verify(8) daemon. </dd>
+
+<dt> <b> all </b> </dt> <dd> Enable SMTPUTF8 autodetection for all
+mail. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM compatibility_level 0
+
+<p> A safety net that causes Postfix to run with backwards-compatible
+default settings after an upgrade to a newer Postfix version. </p>
+
+<p> With backwards compatibility turned on (the main.cf compatibility_level
+value is less than the Postfix built-in value), Postfix looks for
+settings that are left at their implicit default value, and logs a
+message when a backwards-compatible default setting is required.
+</p>
+
+<blockquote>
+<pre>
+using backwards-compatible default setting <i>name=value</i>
+ to [accept a specific client request]
+<nroffescape .sp>
+using backwards-compatible default setting <i>name=value</i>
+ to [enable specific Postfix behavior]
+</pre>
+</blockquote>
+
+<p> See COMPATIBILITY_README for specific message details. If such
+a message is logged in the context of a legitimate request, the
+system administrator should make the backwards-compatible setting
+permanent in main.cf or master.cf, for example: </p>
+
+<blockquote>
+<pre>
+# <b>postconf</b> <i>name=value</i>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> When no more backwards-compatible settings need to be made
+permanent, the administrator should turn off backwards compatibility
+by updating the compatibility_level setting in main.cf:</p>
+
+<blockquote>
+<pre>
+# <b>postconf compatibility_level=<i>N</i></b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> For <i>N</i> specify the number that is logged in your postfix(1)
+warning message: </p>
+
+<blockquote>
+<pre>
+warning: To disable backwards compatibility use "postconf
+ compatibility_level=<i>N</i>" and "postfix reload"
+</pre>
+</blockquote>
+
+<p> Starting with Postfix version 3.6, the compatibility level in
+the above warning message is the Postfix version that introduced
+the last incompatible change. The level is formatted as
+<i>major.minor.patch</i>, where <i>patch</i> is usually omitted and
+defaults to zero. Earlier compatibility levels are 0, 1 and 2. </p>
+
+<p> NOTE: this also introduces support for the "&lt;level",
+"&lt;=level", and other operators to compare compatibility levels.
+With the standard operators "&lt;", "&lt;=", etc., compatibility
+level "3.10" would be smaller than "3.9" which is undesirable. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM message_drop_headers bcc, content-length, resent-bcc, return-path
+
+<p> Names of message headers that the cleanup(8) daemon will remove
+after applying header_checks(5) and before invoking Milter applications.
+The default setting is compatible with Postfix &lt; 3.0. </p>
+
+<p> Specify a list of header names, separated by comma or space.
+Names are matched in a case-insensitive manner. The list of supported
+header names is limited only by available memory. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtpd_dns_reply_filter
+
+<p> Optional filter for Postfix SMTP server DNS lookup results.
+See smtp_dns_reply_filter for details including an example.
+</p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM lmtp_dns_reply_filter
+
+<p> Optional filter for Postfix LMTP client DNS lookup results.
+See smtp_dns_reply_filter for details including an example. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+#%PARAM postscreen_dns_reply_filter
+#
+#<p> Optional filter for postscreen(8) DNS lookup results.
+#See smtp_dns_reply_filter for details including an example.
+#</p>
+#
+#<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtp_dns_reply_filter
+
+<p> Optional filter for Postfix SMTP client DNS lookup results.
+Specify zero or more lookup tables. The lookup tables are searched
+in the given order for a match with the DNS lookup result, converted
+to the following form: </p>
+
+<pre>
+ <i>name ttl class type preference value</i>
+</pre>
+
+<p> The <i>class</i> field is always "IN", the <i>preference</i>
+field exists only for MX records, the names of hosts, domains, etc.
+end in ".", and those names are in ASCII form (xn--mumble form in
+the case of UTF8 names). </p>
+
+<p> When a match is found, the table lookup result specifies an
+action. By default, the table query and the action name are
+case-insensitive. Currently, only the <b>IGNORE</b> action is
+implemented. </p>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Postfix DNS reply filters have no effect on implicit DNS
+lookups through nsswitch.conf or equivalent mechanisms. </p>
+
+<li> <p> The Postfix SMTP/LMTP client uses smtp_dns_reply_filter
+and lmtp_dns_reply_filter only to discover a remote SMTP or LMTP
+service (record types MX, A, AAAA, and TLSA). These lookups are
+also made to implement the features reject_unverified_sender and
+reject_unverified_recipient. </p>
+
+<li> <p> The Postfix SMTP/LMTP client defers mail delivery when
+a filter removes all lookup results from a successful query. </p>
+
+<li> <p> Postfix SMTP server uses smtpd_dns_reply_filter only to
+look up MX, A, AAAA, and TXT records to implement the features
+reject_unknown_helo_hostname, reject_unknown_sender_domain,
+reject_unknown_recipient_domain, reject_rbl_*, and reject_rhsbl_*.
+</p>
+
+<li> <p> The Postfix SMTP server logs a warning or defers mail
+delivery when a filter removes all lookup results from a successful
+query. </p>
+
+</ul>
+
+<p> Example: ignore Google AAAA records in Postfix SMTP client DNS
+lookups, because Google sometimes hard-rejects mail from IPv6 clients
+with valid PTR etc. records. </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtp_dns_reply_filter = pcre:/etc/postfix/smtp_dns_reply_filter
+</pre>
+
+<pre>
+/etc/postfix/smtp_dns_reply_filter:
+ # /domain ttl IN AAAA address/ action, all case-insensitive.
+ # Note: the domain name ends in ".".
+ /^\S+\.google\.com\.\s+\S+\s+\S+\s+AAAA\s+/ IGNORE
+</pre>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtp_tls_wrappermode no
+
+<p> Request that the Postfix SMTP client connects using the
+SUBMISSIONS/SMTPS protocol instead of using the STARTTLS command. </p>
+
+<p> This mode requires "smtp_tls_security_level = encrypt" or
+stronger. </p>
+
+<p> Example: deliver all remote mail via a provider's server
+"mail.example.com". </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Client-side SMTPS requires "encrypt" or stronger.
+ smtp_tls_security_level = encrypt
+ smtp_tls_wrappermode = yes
+ # The [] suppress MX lookups.
+ relayhost = [mail.example.com]:465
+</pre>
+
+<p> More examples are in TLS_README, including examples for older
+Postfix versions. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM lmtp_tls_wrappermode no
+
+<p> The LMTP-specific version of the smtp_tls_wrappermode configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.0 and later. </p>
+
+%PARAM smtp_tls_connection_reuse no
+
+<p> Try to make multiple deliveries per TLS-encrypted connection.
+This uses the tlsproxy(8) service to encrypt an SMTP connection,
+uses the scache(8) service to save that connection, and relies on
+hints from the qmgr(8) daemon. </p>
+
+<p> See "<a href="TLS_README.html#client_tls_reuse">Client-side
+TLS connection reuse</a>" for background details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM lmtp_tls_connection_reuse no
+
+<p> The LMTP-specific version of the smtp_tls_connection_reuse configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM virtual_alias_address_length_limit 1000
+
+<p>
+The maximal length of an email address after virtual alias expansion.
+This stops virtual aliasing loops that increase the address length
+exponentially.
+</p>
+
+<p>
+This feature is available in Postfix 3.0 and later.
+</p>
+
+%PARAM dns_ncache_ttl_fix_enable no
+
+<p> Enable a workaround for future libc incompatibility. The Postfix
+implementation of RFC 2308 negative reply caching relies on the
+promise that res_query() and res_search() invoke res_send(), which
+returns the server response in an application buffer even if the
+requested record does not exist. If this promise is broken, specify
+"yes" to enable a workaround for DNS reputation lookups. </p>
+
+<p>
+This feature is available in Postfix 3.1 and later.
+</p>
+
+%PARAM smtpd_policy_service_policy_context
+
+<p> Optional information that the Postfix SMTP server specifies in
+the "policy_context" attribute of a policy service request (originally,
+to share the same service endpoint among multiple check_policy_service
+clients). </p>
+
+<p>
+This feature is available in Postfix 3.1 and later.
+</p>
+
+%PARAM smtp_tls_dane_insecure_mx_policy see "postconf -d" output
+
+<p> The TLS policy for MX hosts with "secure" TLSA records when the
+nexthop destination security level is <b>dane</b>, but the MX
+record was found via an "insecure" MX lookup. The choices are:
+</p>
+
+<dl>
+<dt><b>may</b></dt>
+<dd> The TLSA records will be ignored and TLS will be optional. If
+the MX host does not appear to support STARTTLS, or the STARTTLS
+handshake fails, mail may be sent in the clear. </dd>
+<dt><b>encrypt</b></dt>
+<dd> The TLSA records will signal a requirement to use TLS. While
+TLS encryption will be required, authentication will not be performed.
+</dd>
+<dt><b>dane</b></dt>
+<dd>The TLSA records will be used just as with "secure" MX records.
+TLS encryption will be required, and, if at least one of the TLSA
+records is "usable", authentication will be required. When
+authentication succeeds, it will be logged only as "Trusted", not
+"Verified", because the MX host name could have been forged. </dd>
+</dl>
+
+<p> The default setting for Postfix &ge; 3.6 is "dane" with
+"smtp_tls_security_level = dane", otherwise "may". This behavior
+was backported to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21.
+With earlier Postfix versions the default setting was always "dane".
+</p>
+
+<p> Though with "insecure" MX records an active attacker can
+compromise SMTP transport security by returning forged MX records,
+such attacks are "tamper-evident" since any forged MX hostnames
+will be recorded in the mail logs. Attackers who place a high value
+on staying hidden may be deterred from forging MX records. </p>
+
+<p>
+This feature is available in Postfix 3.1 and later. The <b>may</b>
+policy is backwards-compatible with earlier Postfix versions.
+</p>
+
+%PARAM openssl_path openssl
+
+<p>
+The location of the OpenSSL command line program openssl(1). This
+is used by the "<b>postfix tls</b>" command to create private keys,
+certificate signing requests, self-signed certificates, and to
+compute public key digests for DANE TLSA records. In multi-instance
+environments, this parameter is always determined from the configuration
+of the default Postfix instance.
+</p>
+
+<p> Example: </p>
+
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ # NetBSD pkgsrc:
+ openssl_path = /usr/pkg/bin/openssl
+ # Local build:
+ openssl_path = /usr/local/bin/openssl
+</pre>
+</blockquote>
+
+<p>
+This feature is available in Postfix 3.1 and later.
+</p>
+
+%PARAM address_verify_pending_request_limit see "postconf -d" output
+
+<p> A safety limit that prevents address verification requests from
+overwhelming the Postfix queue. By default, the number of pending
+requests is limited to 1/4 of the active queue maximum size
+(qmgr_message_active_limit). The queue manager enforces the limit
+by tempfailing requests that exceed the limit. This affects only
+unknown addresses and inactive addresses that have expired, because
+the verify(8) daemon automatically refreshes an active address
+before it expires. </p>
+
+<p> This feature is available in Postfix 3.1 and later. </p>
+
+%PARAM smtpd_milter_maps
+
+<p> Lookup tables with Milter settings per remote SMTP client IP
+address. The lookup result overrides the smtpd_milters setting,
+and has the same syntax. </p>
+
+<p> Note: lookup tables cannot return empty responses. Specify a
+lookup result of DISABLE (case does not matter) to indicate that
+Milter support should be disabled. </p>
+
+<p> Example to disable Milters for local clients: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ smtpd_milter_maps = cidr:/etc/postfix/smtpd_milter_map
+ smtpd_milters = inet:host:port, { inet:host:port, ... }, ...
+</pre>
+
+<pre>
+/etc/postfix/smtpd_milter_map:
+ # Disable Milters for local clients.
+ 127.0.0.0/8 DISABLE
+ 192.168.0.0/16 DISABLE
+ ::/64 DISABLE
+ 2001:db8::/32 DISABLE
+</pre>
+
+<p> This feature is available in Postfix 3.2 and later. </p>
+
+%PARAM enable_idna2003_compatibility no
+
+<p> Enable 'transitional' compatibility between IDNA2003 and IDNA2008,
+when converting UTF-8 domain names to/from the ASCII form that is
+used for DNS lookups. Specify "yes" for compatibility with Postfix
+&le; 3.1 (not recommended). This affects the conversion of domain
+names that contain for example the German sz and the Greek zeta.
+See http://unicode.org/cldr/utility/idna.jsp for more examples.
+</p>
+
+<p> This feature is available in Postfix 3.2 and later. </p>
+
+%PARAM smtp_balance_inet_protocols yes
+
+<p> When a remote destination resolves to a combination of IPv4 and
+IPv6 addresses, ensure that the Postfix SMTP client can try both
+address types before it runs into the smtp_mx_address_limit. </p>
+
+<p> This avoids an interoperability problem when a destination resolves
+to primarily IPv6 addresses, the smtp_address_limit feature eliminates
+most or all IPv4 addresses, and the destination is not reachable over
+IPv6. </p>
+
+<p> This feature is available in Postfix 3.3 and later. </p>
+
+%PARAM lmtp_balance_inet_protocols yes
+
+<p> The LMTP-specific version of the smtp_balance_inet_protocols
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.3 and later. </p>
+
+%PARAM header_from_format standard
+
+<p> The format of the Postfix-generated <b>From:</b> header. This
+setting affects the appearance of 'full name' information when a
+local program such as /bin/mail submits a message without a From:
+header through the Postfix sendmail(1) command. </p>
+
+<p> Specify one of the following: </p>
+
+<dl>
+
+<dt><b>standard</b> (default)</dt> <dd> Produce a header formatted
+as "<b>From:</b> <i>name</i><b> &lt;</b><i>address</i><b>&gt;</b>".
+This is the default as of Postfix 3.3.</dd>
+
+<dt><b>obsolete</b></dt> <dd>Produce a header formatted as "<b>From:</b>
+<i>address</i> <b>(</b><i>name</i><b>)</b>". This is the behavior
+prior to Postfix 3.3. </dd>
+
+</dl>
+
+<p> Notes: </p>
+
+<ul>
+
+<li> <p> Postfix generates the format "<b>From:</b> <i>address</i>"
+when <i>name</i> information is unavailable or the envelope sender
+address is empty. This is the same behavior as prior to Postfix
+3.3. </p>
+
+<li> <p> In the <b>standard</b> form, the <i>name</i> will be quoted
+if it contains <b>specials</b> as defined in RFC 5322, or the "!%"
+address operators. </p>
+
+<li> <p> The Postfix sendmail(1) command gets <i>name</i> information
+from the <b>-F</b> command-line option, from the <b>NAME</b>
+environment variable, or from the UNIX password file. </p>
+
+</ul>
+
+<p> This feature is available in Postfix 3.3 and later. </p>
+
+%PARAM tlsproxy_client_CAfile $smtp_tls_CAfile
+
+<p> A file containing CA certificates of root CAs trusted to sign
+either remote TLS server certificates or intermediate CA certificates.
+See smtp_tls_CAfile for further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_CApath $smtp_tls_CApath
+
+<p> Directory with PEM format Certification Authority certificates
+that the Postfix tlsproxy(8) client uses to verify a remote TLS
+server certificate. See smtp_tls_CApath for further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_cert_file $smtp_tls_cert_file
+
+<p> File with the Postfix tlsproxy(8) client RSA certificate in PEM
+format. See smtp_tls_cert_file for further details. The preferred way
+to configure tlsproxy client keys and certificates is via the
+"tlsproxy_client_chain_files" parameter. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_key_file $smtp_tls_key_file
+
+<p> File with the Postfix tlsproxy(8) client RSA private key in PEM
+format. See smtp_tls_key_file for further details. The preferred way to
+configure tlsproxy client keys and certificates is via the
+"tlsproxy_client_chain_files" parameter. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_dcert_file $smtp_tls_dcert_file
+
+<p> File with the Postfix tlsproxy(8) client DSA certificate in PEM
+format. See smtp_tls_dcert_file for further details. DSA is obsolete and
+should not be used. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_dkey_file $smtp_tls_dkey_file
+
+<p> File with the Postfix tlsproxy(8) client DSA private key in PEM
+format. See smtp_tls_dkey_file for further details. DSA is obsolete and
+should not be used. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_eccert_file $smtp_tls_eccert_file
+
+<p> File with the Postfix tlsproxy(8) client ECDSA certificate in PEM
+format. See smtp_tls_eccert_file for further details. The preferred way
+to configure tlsproxy client keys and certificates is via the
+"tlsproxy_client_chain_files" parameter. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_eckey_file $smtp_tls_eckey_file
+
+<p> File with the Postfix tlsproxy(8) client ECDSA private key in PEM
+format. See smtp_tls_eckey_file for further details. The preferred way
+to configure tlsproxy client keys and certificates is via the
+"tlsproxy_client_chain_files" parameter. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_fingerprint_digest $smtp_tls_fingerprint_digest
+
+<p> The message digest algorithm used to construct remote TLS server
+certificate fingerprints. See smtp_tls_fingerprint_digest for
+further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_loglevel $smtp_tls_loglevel
+
+<p> Enable additional Postfix tlsproxy(8) client logging of TLS
+activity. See smtp_tls_loglevel for further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_loglevel_parameter smtp_tls_loglevel
+
+<p> The name of the parameter that provides the tlsproxy_client_loglevel
+value. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_scert_verifydepth $smtp_tls_scert_verifydepth
+
+<p> The verification depth for remote TLS server certificates.
+See smtp_tls_scert_verifydepth for further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_level $smtp_tls_security_level
+
+<p> The default TLS security level for the Postfix tlsproxy(8)
+client. See smtp_tls_security_level for further details. </p>
+
+<p> This feature is available in Postfix 3.4 - 3.6. It was
+renamed to tlsproxy_client_security_level in Postfix 3.7. </p>
+
+%PARAM tlsproxy_client_security_level $smtp_tls_security_level
+
+<p> The default TLS security level for the Postfix tlsproxy(8)
+client. See smtp_tls_security_level for further details. </p>
+
+<p> This feature is available in Postfix 3.7 and later. It
+was previously called tlsproxy_client_level. </p>
+
+%PARAM tlsproxy_client_per_site $smtp_tls_per_site
+
+<p> Optional lookup tables with the Postfix tlsproxy(8) client TLS
+usage policy by next-hop destination and by remote TLS server
+hostname. See smtp_tls_per_site for further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_policy $smtp_tls_policy_maps
+
+<p> Optional lookup tables with the Postfix tlsproxy(8) client TLS
+security policy by next-hop destination. See smtp_tls_policy_maps
+for further details. </p>
+
+<p> This feature is available in Postfix 3.4 - 3.6. It was
+renamed to tlsproxy_client_policy_maps in Postfix 3.7. </p>
+
+%PARAM tlsproxy_client_policy_maps $smtp_tls_policy_maps
+
+<p> Optional lookup tables with the Postfix tlsproxy(8) client TLS
+security policy by next-hop destination. See smtp_tls_policy_maps
+for further details. </p>
+
+<p> This feature is available in Postfix 3.7 and later. It
+was previously called tlsproxy_client_policy. </p>
+
+%PARAM tlsproxy_client_use_tls $smtp_use_tls
+
+<p> Opportunistic mode: use TLS when a remote server announces TLS
+support. See smtp_use_tls for further details. Use
+tlsproxy_client_security_level instead. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_enforce_tls $smtp_enforce_tls
+
+<p> Enforcement mode: require that SMTP servers use TLS encryption.
+See smtp_enforce_tls for further details. Use
+tlsproxy_client_security_level instead. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM smtpd_tls_chain_files
+
+<p> List of one or more PEM files, each holding one or more private keys
+directly followed by a corresponding certificate chain. The file names
+are separated by commas and/or whitespace. This parameter obsoletes the
+legacy algorithm-specific key and certificate file settings. When this
+parameter is non-empty, the legacy parameters are ignored, and a warning
+is logged if any are also non-empty. </p>
+
+<p> With the proliferation of multiple private key algorithms&mdash;which,
+as of OpenSSL 1.1.1, include DSA (obsolete), RSA, ECDSA, Ed25519
+and Ed448&mdash;it is increasingly impractical to use separate
+parameters to configure the key and certificate chain for each
+algorithm. Therefore, Postfix now supports storing multiple keys and
+corresponding certificate chains in a single file or in a set of files.
+
+<p> Each key must appear <b>immediately before</b> the corresponding
+certificate, optionally followed by additional issuer certificates that
+complete the certificate chain for that key. When multiple files are
+specified, they are equivalent to a single file that is concatenated
+from those files in the given order. Thus, while a key must always
+precede its certificate and issuer chain, it can be in a separate file,
+so long as that file is listed immediately before the file that holds
+the corresponding certificate chain. Once all the files are
+concatenated, the sequence of PEM objects must be: <i>key1, cert1,
+[chain1], key2, cert2, [chain2], ..., keyN, certN, [chainN].</i> </p>
+
+<p> Storing the private key in the same file as the corresponding
+certificate is more reliable. With the key and certificate in separate
+files, there is a chance that during key rollover a Postfix process
+might load a private key and certificate from separate files that don't
+match. Various operational errors may even result in a persistent
+broken configuration in which the certificate does not match the private
+key. </p>
+
+<p> The file or files must contain at most one key of each type. If,
+for example, two or more RSA keys and corresponding chains are listed,
+depending on the version of OpenSSL either only the last one will be
+used or a configuration error may be detected. Note that while
+"Ed25519" and "Ed448" are considered separate algorithms, the various
+ECDSA curves (typically one of prime256v1, secp384r1 or secp521r1) are
+considered as different parameters of a single "ECDSA" algorithm, so it
+is not presently possible to configure keys for more than one ECDSA
+curve. </p>
+
+<p> RSA is still the most widely supported algorithm. Presently (late
+2018), ECDSA support is common, but not yet universal, and Ed25519 and
+Ed448 support is mostly absent. Therefore, an RSA key should generally
+be configured, along with any additional keys for the other algorithms
+when desired. </p>
+
+<p>
+Example (separate files for each key and corresponding certificate chain):
+</p>
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_chain_files =
+ ${config_directory}/ed25519.pem,
+ ${config_directory}/ed448.pem,
+ ${config_directory}/rsa.pem
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/ed25519.pem:
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIEJfbbO4BgBQGBg9NAbIJaDBqZb4bC4cOkjtAH+Efbz3
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIBKzCB3qADAgECAhQaw+rflRreYuUZBp0HuNn/e5rMZDAFBgMrZXAwFDESMBAG
+ ...
+ nC0egv51YPDWxEHom4QA
+ -----END CERTIFICATE-----
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/ed448.pem:
+ -----BEGIN PRIVATE KEY-----
+ MEcCAQAwBQYDK2VxBDsEOQf+m0P+G0qi+NZ0RolyeiE5zdlPQR8h8y4jByBifpIe
+ LNler7nzHQJ1SLcOiXFHXlxp/84VZuh32A==
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIBdjCB96ADAgECAhQSv4oP972KypOZPNPF4fmsiQoRHzAFBgMrZXEwFDESMBAG
+ ...
+ pQcWsx+4J29e6YWH3Cy/CdUaexKP4RPCZDrPX7bk5C2BQ+eeYOxyThMA
+ -----END CERTIFICATE-----
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/rsa.pem:
+ -----BEGIN PRIVATE KEY-----
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc4QusgkahH9rL
+ ...
+ ahQkZ3+krcaJvDSMgvu0tDc=
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIC+DCCAeCgAwIBAgIUIUkrbk1GAemPCT8i9wKsTGDH7HswDQYJKoZIhvcNAQEL
+ ...
+ Rirz15HGVNTK8wzFd+nulPzwUo6dH2IU8KazmyRi7OGvpyrMlm15TRE2oyE=
+ -----END CERTIFICATE-----
+</pre>
+</blockquote>
+
+<p>
+Example (all keys and certificates in a single file):
+</p>
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtpd_tls_chain_files = ${config_directory}/chains.pem
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/chains.pem:
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIEJfbbO4BgBQGBg9NAbIJaDBqZb4bC4cOkjtAH+Efbz3
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIBKzCB3qADAgECAhQaw+rflRreYuUZBp0HuNn/e5rMZDAFBgMrZXAwFDESMBAG
+ ...
+ nC0egv51YPDWxEHom4QA
+ -----END CERTIFICATE-----
+ -----BEGIN PRIVATE KEY-----
+ MEcCAQAwBQYDK2VxBDsEOQf+m0P+G0qi+NZ0RolyeiE5zdlPQR8h8y4jByBifpIe
+ LNler7nzHQJ1SLcOiXFHXlxp/84VZuh32A==
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIBdjCB96ADAgECAhQSv4oP972KypOZPNPF4fmsiQoRHzAFBgMrZXEwFDESMBAG
+ ...
+ pQcWsx+4J29e6YWH3Cy/CdUaexKP4RPCZDrPX7bk5C2BQ+eeYOxyThMA
+ -----END CERTIFICATE-----
+ -----BEGIN PRIVATE KEY-----
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc4QusgkahH9rL
+ ...
+ ahQkZ3+krcaJvDSMgvu0tDc=
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIC+DCCAeCgAwIBAgIUIUkrbk1GAemPCT8i9wKsTGDH7HswDQYJKoZIhvcNAQEL
+ ...
+ Rirz15HGVNTK8wzFd+nulPzwUo6dH2IU8KazmyRi7OGvpyrMlm15TRE2oyE=
+ -----END CERTIFICATE-----
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM smtp_tls_chain_files
+
+<p> List of one or more PEM files, each holding one or more private keys
+directly followed by a corresponding certificate chain. The file names
+are separated by commas and/or whitespace. This parameter obsoletes the
+legacy algorithm-specific key and certificate file settings. When this
+parameter is non-empty, the legacy parameters are ignored, and a warning
+is logged if any are also non-empty. </p>
+
+<p> With the proliferation of multiple private key algorithms&mdash;which,
+as of OpenSSL 1.1.1, include DSA (obsolete), RSA, ECDSA, Ed25519
+and Ed448&mdash;it is increasingly impractical to use separate
+parameters to configure the key and certificate chain for each
+algorithm. Therefore, Postfix now supports storing multiple keys and
+corresponding certificate chains in a single file or in a set of files.
+
+<p> Each key must appear <b>immediately before</b> the corresponding
+certificate, optionally followed by additional issuer certificates that
+complete the certificate chain for that key. When multiple files are
+specified, they are equivalent to a single file that is concatenated
+from those files in the given order. Thus, while a key must always
+precede its certificate and issuer chain, it can be in a separate file,
+so long as that file is listed immediately before the file that holds
+the corresponding certificate chain. Once all the files are
+concatenated, the sequence of PEM objects must be: <i>key1, cert1,
+[chain1], key2, cert2, [chain2], ..., keyN, certN, [chainN].</i> </p>
+
+<p> Storing the private key in the same file as the corresponding
+certificate is more reliable. With the key and certificate in separate
+files, there is a chance that during key rollover a Postfix process
+might load a private key and certificate from separate files that don't
+match. Various operational errors may even result in a persistent
+broken configuration in which the certificate does not match the private
+key. </p>
+
+<p> The file or files must contain at most one key of each type. If,
+for example, two or more RSA keys and corresponding chains are listed,
+depending on the version of OpenSSL either only the last one will be
+used or a configuration error may be detected. Note that while
+"Ed25519" and "Ed448" are considered separate algorithms, the various
+ECDSA curves (typically one of prime256v1, secp384r1 or secp521r1) are
+considered as different parameters of a single "ECDSA" algorithm, so it
+is not presently possible to configure keys for more than one ECDSA
+curve. </p>
+
+<p>
+Example (separate files for each key and corresponding certificate chain):
+</p>
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_chain_files =
+ ${config_directory}/ed25519.pem,
+ ${config_directory}/ed448.pem,
+ ${config_directory}/rsa.pem
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/ed25519.pem:
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIEJfbbO4BgBQGBg9NAbIJaDBqZb4bC4cOkjtAH+Efbz3
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIBKzCB3qADAgECAhQaw+rflRreYuUZBp0HuNn/e5rMZDAFBgMrZXAwFDESMBAG
+ ...
+ nC0egv51YPDWxEHom4QA
+ -----END CERTIFICATE-----
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/ed448.pem:
+ -----BEGIN PRIVATE KEY-----
+ MEcCAQAwBQYDK2VxBDsEOQf+m0P+G0qi+NZ0RolyeiE5zdlPQR8h8y4jByBifpIe
+ LNler7nzHQJ1SLcOiXFHXlxp/84VZuh32A==
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIBdjCB96ADAgECAhQSv4oP972KypOZPNPF4fmsiQoRHzAFBgMrZXEwFDESMBAG
+ ...
+ pQcWsx+4J29e6YWH3Cy/CdUaexKP4RPCZDrPX7bk5C2BQ+eeYOxyThMA
+ -----END CERTIFICATE-----
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/rsa.pem:
+ -----BEGIN PRIVATE KEY-----
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc4QusgkahH9rL
+ ...
+ ahQkZ3+krcaJvDSMgvu0tDc=
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIC+DCCAeCgAwIBAgIUIUkrbk1GAemPCT8i9wKsTGDH7HswDQYJKoZIhvcNAQEL
+ ...
+ Rirz15HGVNTK8wzFd+nulPzwUo6dH2IU8KazmyRi7OGvpyrMlm15TRE2oyE=
+ -----END CERTIFICATE-----
+</pre>
+</blockquote>
+
+<p>
+Example (all keys and certificates in a single file):
+</p>
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ smtp_tls_chain_files = ${config_directory}/chains.pem
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/chains.pem:
+ -----BEGIN PRIVATE KEY-----
+ MC4CAQAwBQYDK2VwBCIEIEJfbbO4BgBQGBg9NAbIJaDBqZb4bC4cOkjtAH+Efbz3
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIBKzCB3qADAgECAhQaw+rflRreYuUZBp0HuNn/e5rMZDAFBgMrZXAwFDESMBAG
+ ...
+ nC0egv51YPDWxEHom4QA
+ -----END CERTIFICATE-----
+ -----BEGIN PRIVATE KEY-----
+ MEcCAQAwBQYDK2VxBDsEOQf+m0P+G0qi+NZ0RolyeiE5zdlPQR8h8y4jByBifpIe
+ LNler7nzHQJ1SLcOiXFHXlxp/84VZuh32A==
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIBdjCB96ADAgECAhQSv4oP972KypOZPNPF4fmsiQoRHzAFBgMrZXEwFDESMBAG
+ ...
+ pQcWsx+4J29e6YWH3Cy/CdUaexKP4RPCZDrPX7bk5C2BQ+eeYOxyThMA
+ -----END CERTIFICATE-----
+ -----BEGIN PRIVATE KEY-----
+ MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQDc4QusgkahH9rL
+ ...
+ ahQkZ3+krcaJvDSMgvu0tDc=
+ -----END PRIVATE KEY-----
+ -----BEGIN CERTIFICATE-----
+ MIIC+DCCAeCgAwIBAgIUIUkrbk1GAemPCT8i9wKsTGDH7HswDQYJKoZIhvcNAQEL
+ ...
+ Rirz15HGVNTK8wzFd+nulPzwUo6dH2IU8KazmyRi7OGvpyrMlm15TRE2oyE=
+ -----END CERTIFICATE-----
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM lmtp_tls_chain_files
+
+<p> The LMTP-specific version of the smtp_tls_chain_files configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_client_chain_files $smtp_tls_chain_files
+
+<p> Files with the Postfix tlsproxy(8) client keys and certificate
+chains in PEM format. See smtp_tls_chain_files for further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tlsproxy_tls_chain_files $smtpd_tls_chain_files
+
+<p> Files with the Postfix tlsproxy(8) server keys and certificate
+chains in PEM format. See smtpd_tls_chain_files for further details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM tls_server_sni_maps
+
+<p> Optional lookup tables that map names received from remote SMTP
+clients via the TLS Server Name Indication (SNI) extension to the
+appropriate keys and certificate chains. This parameter is implemented
+in the Postfix TLS library, and applies to both smtpd(8) and the SMTP
+server mode of tlsproxy(8). </p>
+
+<p> When this parameter is non-empty, the Postfix SMTP server enables
+SNI extension processing, and logs SNI values that are invalid or
+don't match an entry in the specified tables. When an entry
+does match, the SNI name is logged as part of the connection summary
+at log levels 1 and higher. </p>
+
+<p> The lookup key is either the verbatim SNI domain name or an
+ancestor domain prefixed with a leading dot. For internationalized
+domains, the lookup key must be in IDNA 2008 A-label form (as
+required in the TLS SNI extension). </p>
+
+<p> The syntax of the lookup value is the same as with the
+smtp_tls_chain_files parameter (see there for additional details),
+but here scoped to just TLS connections in which the client sends
+a matching SNI domain name. </p>
+
+<p> Example: </p>
+<blockquote>
+<pre>
+/etc/postfix/main.cf:
+ #
+ # The indexed SNI table must be created with "postmap -F"
+ #
+ indexed = ${default_database_type}:${config_directory}/
+ tls_server_sni_maps = ${indexed}sni
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/sni:
+ #
+ # The example.com domain has both an RSA and ECDSA certificate
+ # chain. The chain files MUST start with the private key,
+ # with the certificate chain next, starting with the leaf
+ # (server) certificate, and then the issuer certificates.
+ #
+ example.com /etc/postfix/sni-chains/rsa2048.example.com.pem,
+ /etc/postfix/sni-chains/ecdsa-p256.example.com.pem
+ #
+ # The example.net domain has a wildcard certificate, and two
+ # additional DNS names. So its certificate chain is also used
+ # with any subdomain, plus the additional names.
+ #
+ example.net /etc/postfix/sni-chains/example.net.pem
+ .example.net /etc/postfix/sni-chains/example.net.pem
+ example.info /etc/postfix/sni-chains/example.net.pem
+ example.org /etc/postfix/sni-chains/example.net.pem
+</pre>
+</blockquote>
+
+<p> Note that the SNI lookup tables should also have entries for
+the domains that correspond to the Postfix SMTP server's default
+certificate(s). This ensures that the remote SMTP client's TLS SNI
+extension gets a positive response when it specifies one of the
+Postfix SMTP server's default domains, and ensures that the Postfix
+SMTP server will not log an SNI name mismatch for such a domain.
+The Postfix SMTP server's default certificates are then only used
+when the client sends no SNI or when it sends SNI with a domain
+that the server knows no certificate(s) for. </p>
+
+<p> The mapping from an SNI domain name to a certificate chain is indirect. In
+the input source files for "cdb", "hash", "btree" or other tables that are
+converted to on-disk indexed files via postmap(1), the value specified for each
+key is a list of filenames. When postmap(1) is used with the <b>-F</b> option,
+the generated table stores for each lookup key the base64-encoded contents of
+the associated files. When querying tables via <b>postmap -Fq</b>, the table
+value is decoded from base64, yielding the original file content, plus a new
+line. </p>
+
+<p> With "regexp", "pcre", "inline", "texthash", "static" and similar
+tables that are interpreted at run-time, and don't have a separate
+source format, the table value is again a list files, that are loaded
+into memory when the table is opened. </p>
+
+<p> With tables whose content is managed outside of Postfix, such
+as LDAP, MySQL, PostgreSQL, socketmap and tcp, the value must be a
+concatenation of the desired PEM keys and certificate chains, that
+is then further encoded to yield a single-line base64 string.
+Creation of such tables and secure storage (the value includes
+private key material) are outside the responsibility of Postfix. </p>
+
+<p> With "socketmap" and "tcp" the data will be transmitted in the clear, and
+there is no query access control, so these are generally unsuitable for storing
+SNI chains. With LDAP and SQL, you should restrict read access and use TLS to
+protect the sensitive data in transit. </p>
+
+<p> Typically there is only one private key and its chain of certificates
+starting with the "leaf" certificate corresponding to that key, and
+continuing with the appropriate intermediate issuer CA certificates,
+with each certificate ideally followed by its issuer. Servers
+that have keys and certificates for more than one algorithm (e.g.
+both an RSA key and an ECDSA key, or even RSA, ECDSA and Ed25519)
+can use multiple chains concatenated together, with the key always
+listed before the corresponding certificates. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM smtp_tls_servername
+
+<p> Optional name to send to the remote SMTP server in the TLS Server
+Name Indication (SNI) extension. The SNI extension is always on when
+DANE is used to authenticate the server, and in that case the SNI name
+sent is the one required by RFC7672 and this parameter is ignored. </p>
+
+<p> Some SMTP servers use the received SNI name to select an appropriate
+certificate chain to present to the client. While this may improve
+interoperability with such servers, it may reduce interoperability with
+other servers that choose to abort the connection when they don't have a
+certificate chain configured for the requested name. Such servers
+should select a default certificate chain and continue the handshake,
+but some may not. Therefore, absent DANE, no SNI name is sent by
+default. </p>
+
+<p> The SNI name must be either a valid DNS hostname, or else one of the
+special values <b>hostname</b> or <b>nexthop</b>, which select either the
+remote hostname or the nexthop domain respectively. DNS names for SNI must be
+in A-label (punycode) form. Invalid DNS names log a configuration error
+warning and mail delivery is deferred. </p>
+
+<p> Except when using a relayhost to forward all email, the only
+sensible non-empty main.cf setting for this parameter is
+<b>hostname</b>. Other non-empty values are only practical on a
+per-destination basis via the <b>servername</b> attribute of the Postfix
+TLS <a href="TLS_README.html#client_tls_policy">policy table</a>. When
+in doubt, leave this parameter empty, and configure per-destination SNI
+as needed. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM lmtp_tls_servername
+
+<p> The LMTP-specific version of the smtp_tls_servername configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM maillog_file
+
+<p> The name of an optional logfile that is written by the Postfix
+postlogd(8) service. An empty value selects logging to syslogd(8).
+Specify "/dev/stdout" to select logging to standard output. Stdout
+logging requires that Postfix is started with "postfix start-fg".
+</p>
+
+<p> Note 1: The maillog_file parameter value must contain a prefix
+that is specified with the maillog_file_prefixes parameter. </p>
+
+<p> Note 2: Some Postfix non-daemon programs may still log information
+to syslogd(8), before they have processed their configuration
+parameters and command-line options. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM postlog_service_name postlog
+
+<p> The name of the postlogd(8) service entry in master.cf.
+This service appends logfile records to the file specified
+with the maillog_file parameter. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM postlogd_watchdog_timeout 10s
+
+<p> How much time a postlogd(8) process may take to process a request
+before it is terminated by a built-in watchdog timer. This is a
+safety mechanism that prevents postlogd(8) from becoming non-responsive
+due to a bug in Postfix itself or in system software. This limit
+cannot be set under 10s. </p>
+
+<p> Specify a non-zero time value (an integral value plus an optional
+one-letter suffix that specifies the time unit). Time units: s
+(seconds), m (minutes), h (hours), d (days), w (weeks).
+The default time unit is s (seconds). </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM maillog_file_prefixes /var, /dev/stdout
+
+<p> A list of allowed prefixes for a maillog_file value. This is a
+safety feature to contain the damage from a single configuration
+mistake. Specify one or more prefix strings, separated by comma or
+whitespace. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM maillog_file_compressor gzip
+
+<p> The program to run after rotating $maillog_file with "postfix
+logrotate". The command is run with the rotated logfile name as its
+first argument. </p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM maillog_file_rotate_suffix %Y%m%d-%H%M%S
+
+<p> The format of the suffix to append to $maillog_file while rotating
+the file with "postfix logrotate". See strftime(3) for syntax. The
+default suffix, YYYYMMDD-HHMMSS, allows logs to be rotated frequently.
+</p>
+
+<p> This feature is available in Postfix 3.4 and later. </p>
+
+%PARAM info_log_address_format external
+
+<p> The email address form that will be used in non-debug logging
+(info, warning, etc.). As of Postfix 3.5 when an address localpart
+contains spaces or other special characters, the localpart will be
+quoted, for example: </p>
+
+<blockquote>
+<pre>
+ from=&lt;"name with spaces"@example.com&gt;
+</pre>
+</blockquote>
+
+<p> Older Postfix versions would log the internal (unquoted) form: </p>
+
+<blockquote>
+<pre>
+ from=&lt;name with spaces@example.com&gt;
+</pre>
+</blockquote>
+
+<p> The external and internal forms are identical for the vast
+majority of email addresses that contain no spaces or other special
+characters in the localpart. </p>
+
+<p> The logging in external form is consistent with the address
+form that Postfix 3.2 and later prefer for most table lookups. This
+is therefore the more useful form for non-debug logging. </p>
+
+<p> Specify "<b>info_log_address_format = internal</b>" for backwards
+compatibility. </p>
+
+<p> Postfix uses the unquoted form internally, because an attacker
+can specify an email address in different forms by playing games
+with quotes and backslashes. An attacker should not be able to use
+such games to circumvent Postfix access policies. </p>
+
+<p> This feature is available in Postfix 3.5 and later. </p>
+
+%PARAM smtpd_sasl_mechanism_filter !external, static:rest
+
+<p> If non-empty, a filter for the SASL mechanism names that the
+Postfix SMTP server will announce in the EHLO response. By default,
+the Postfix SMTP server will not announce the EXTERNAL mechanism,
+because Postfix support for that is not implemented. </p>
+
+<p> Specify mechanism names, "/file/name" patterns, or "type:table"
+lookup tables, separated by comma or whitespace. The right-hand
+side result from "type:table" lookups is ignored. Specify "!pattern"
+to exclude a mechanism name from the list. </p>
+
+<p>
+Examples:
+</p>
+
+<pre>
+smtpd_sasl_mechanism_filter = !external, !gssapi, static:rest
+smtpd_sasl_mechanism_filter = login, plain
+smtpd_sasl_mechanism_filter = /etc/postfix/smtpd_mechs
+</pre>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+%PARAM dnssec_probe ns:.
+
+<p> The DNS query type (default: "ns") and DNS query name (default:
+".") that Postfix may use to determine whether DNSSEC validation
+is available.
+</p>
+
+<p> Background: DNSSEC validation is needed for Postfix DANE support;
+this ensures that Postfix receives TLSA records with secure TLS
+server certificate info. When DNSSEC validation is unavailable,
+mail deliveries using <i>opportunistic</i> DANE will not be protected
+by server certificate info in TLSA records, and mail deliveries
+using <i>mandatory</i> DANE will not be made at all. </p>
+
+<p> By default, a Postfix process will send a DNSSEC probe after
+1) the process made a DNS query that requested DNSSEC validation,
+2) the process did not receive a DNSSEC validated response to this
+query or to an earlier query, and 3) the process did not already
+send a DNSSEC probe. <p>
+
+<p> When the DNSSEC probe has no response, or when the response is
+not DNSSEC validated, Postfix logs a warning that DNSSEC validation
+may be unavailable. </p>
+
+<p> Example: </p>
+
+<pre>
+warning: DNSSEC validation may be unavailable
+warning: reason: dnssec_probe 'ns:.' received a response that is not DNSSEC validated
+warning: reason: dnssec_probe 'ns:.' received no response: Server failure
+</pre>
+
+<p> Possible reasons why DNSSEC validation may be unavailable: </p>
+
+<ul>
+
+<li> The local /etc/resolv.conf file specifies a DNS resolver that
+does not validate DNSSEC signatures (that's
+$queue_directory/etc/resolv.conf when a Postfix daemon runs in a
+chroot jail).
+
+<li> The local system library does not pass on the "DNSSEC validated"
+bit to Postfix, or Postfix does not know how to ask the library to
+do that.
+
+</ul>
+
+<p> By default, the DNSSEC probe asks for the DNS root zone NS
+records, because resolvers should always have that information
+cached. If Postfix runs on a network where the DNS root zone is not
+reachable, specify a different probe, or specify an empty dnssec_probe
+value to disable the feature. </p>
+
+<p> This feature is available in Postfix 3.6 and later. It was backported
+to Postfix versions 3.5.9, 3.4.19, 3.3.16. 3.2.21. </p>
+
+%PARAM local_login_sender_maps static:*
+
+<p> A list of lookup tables that are searched by the UNIX login name,
+and that return a list of allowed envelope sender patterns separated
+by space or comma. These sender patterns are enforced by the Postfix
+postdrop(1) command. The default is backwards-compatible:
+every user may specify any sender envelope address. </p>
+
+<p> When no UNIX login name is available, the postdrop(1) command will
+prepend "<b>uid:</b>" to the numerical UID and use that instead. </p>
+
+<p> This feature ignores address extensions in the user-specified
+envelope sender address. </p>
+
+<p> The following sender patterns are special; these cannot be used
+as part of a longer pattern. </p>
+
+<dl compact>
+
+<dt> <b> * </b> <dd> This pattern allows any envelope sender address.
+</dd>
+
+<dt> <b> &lt;&gt; </b> </dt> <dd> This pattern allows the empty
+envelope sender address. See the
+empty_address_local_login_sender_maps_lookup_key configuration
+parameter. </dd>
+
+<dt> <b> @</b><i>domain</i> </dt> <dd> This pattern allows an
+envelope sender address when the '<b>@</b>' and <i>domain</i> part
+match. </dd>
+
+</dl>
+
+<p> Examples: </p>
+
+<pre>
+/etc/postfix/main.cf:
+ # Allow root and postfix full control, anyone else can only
+ # send mail as themselves. Use "uid:" followed by the numerical
+ # UID when the UID has no entry in the UNIX password file.
+ local_login_sender_maps =
+ inline:{ { root = * }, { postfix = * } },
+ pcre:/etc/postfix/login_senders
+</pre>
+
+<pre>
+/etc/postfix/login_senders:
+ # Allow both the bare username and the user@domain forms.
+ /(.+)/ $1 $1@example.com
+</pre>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+%PARAM empty_address_local_login_sender_maps_lookup_key &lt;&gt;
+
+<p>
+The lookup key to be used in local_login_sender_maps tables, instead
+of the null sender address.
+</p>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+%PARAM enable_threaded_bounces no
+
+<p> Enable non-delivery, success, and delay notifications that link
+to the original message by including a References: and In-Reply-To:
+header with the original Message-ID value. There are advantages and
+disadvantages to consider. </p>
+
+<dl>
+
+<dt> <b> advantage </b> </dt> <dd> This allows mail readers to present
+a delivery status notification in the same email thread as the original
+message. </dd>
+
+<dt> <b> disadvantage </b> </dt> <dd> This makes it easy for users to
+mistakenly delete the whole email thread (all related messages),
+instead of deleting only the non-delivery notification. </dd>
+
+</dl>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+%PARAM smtpd_relay_before_recipient_restrictions see "postconf -d" output
+
+<p> Evaluate smtpd_relay_restrictions before smtpd_recipient_restrictions.
+Historically, smtpd_relay_restrictions was evaluated after
+smtpd_recipient_restrictions, contradicting documented behavior. </p>
+
+<p> Background: the smtpd_relay_restrictions feature is primarily
+designed to enforce a mail relaying policy, while
+smtpd_recipient_restrictions is primarily designed to enforce spam
+blocking policy. Both are evaluated while replying to the RCPT TO
+command, and both support the same features. </p>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+%PARAM respectful_logging see 'postconf -d' output
+
+<p> Avoid logging that implies white is better than black. Instead
+use 'allowlist', 'denylist', and variations of those words. </p>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+%PARAM known_tcp_ports lmtp=24, smtp=25, smtps=submissions=465, submission=587
+
+<p> Optional setting that avoids lookups in the services(5) database.
+This feature was implemented to address inconsistencies in the name
+of the port "465" service. The ABNF is:
+</p>
+
+<blockquote>
+<p>
+known_tcp_ports = empty | name-to-port *("," name-to-port) <br>
+name-to-port = 1*(service-name "=') port-number
+</p>
+</blockquote>
+
+<p> The comma is required. Whitespace is optional but it cannot appear
+inside a service name or port number. </p>
+
+<p> This feature is available in Postfix 3.6 and later. </p>
+
+%PARAM smtpd_min_data_rate 500
+
+<p> The minimum plaintext data transfer rate in bytes/second for
+DATA and BDAT requests, when deadlines are enabled with
+smtpd_per_request_deadline. After a read operation transfers N
+plaintext message bytes (possibly after TLS decryption), and after
+the DATA or BDAT request deadline is decremented by the elapsed
+time of that read operation, the DATA or BDAT request deadline is
+incremented by N/smtpd_min_data_rate seconds. However, the deadline
+will never be incremented beyond the time limit specified with
+smtpd_timeout. </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM smtpd_per_request_deadline normal: no, overload: yes
+
+<p> Change the behavior of the smtpd_timeout and smtpd_starttls_timeout
+time limits, from a time limit per plaintext or TLS read or write
+call, to a combined time limit for receiving a complete SMTP request
+and for sending a complete SMTP response. The deadline limits only
+the time spent waiting for plaintext or TLS read or write calls,
+not time spent elsewhere. The per-request deadline limits the impact
+from hostile peers that trickle data one byte at a time. </p>
+
+<p> See smtpd_min_data_rate for how the per-request deadline is
+managed during the DATA and BDAT phase. </p>
+
+<p> Note: when per-request deadlines are enabled, a short time limit
+may cause problems with TLS over very slow network connections. The
+reason is that a TLS protocol message can be up to 16 kbytes long
+(with TLSv1), and that an entire TLS protocol message must be
+transferred within the per-request deadline. </p>
+
+<p> This feature is available in Postfix 3.7 and later. A weaker
+feature, called smtpd_per_record_deadline, is available with Postfix
+2.9-3.6. With older Postfix releases, the behavior is as if this
+parameter is set to "no". </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM lmtp_min_data_rate 500
+
+<p> The LMTP-specific version of the smtp_min_data_rate configuration
+parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM lmtp_per_request_deadline no
+
+<p> The LMTP-specific version of the smtp_per_request_deadline
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM smtp_min_data_rate 500
+
+<p> The minimum plaintext data transfer rate in bytes/second for
+DATA requests, when deadlines are enabled with smtp_per_request_deadline.
+After a write operation transfers N plaintext message bytes (possibly
+after TLS encryption), and after the DATA request deadline is
+decremented by the elapsed time of that write operation, the DATA
+request deadline is incremented by N/smtp_min_data_rate seconds.
+However, the deadline will never be incremented beyond the time
+limit specified with smtp_data_xfer_timeout. </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM smtp_per_request_deadline no
+
+<p> Change the behavior of the smtp_*_timeout time limits, from a
+time limit per plaintext or TLS read or write call, to a combined
+time limit for sending a complete SMTP request and for receiving a
+complete SMTP response. The deadline limits only the time spent
+waiting for plaintext or TLS read or write calls, not time spent
+elsewhere. The per-request deadline limits the impact from hostile
+peers that trickle data one byte at a time. </p>
+
+<p> See smtp_min_data_rate for how the per-request deadline is
+managed during the DATA phase. </p>
+
+<p> Note: when per-request deadlines are enabled, a short time limit
+may cause problems with TLS over very slow network connections. The
+reason is that a TLS protocol message can be up to 16 kbytes long
+(with TLSv1), and that an entire TLS protocol message must be
+transferred within the per-request deadline. </p>
+
+<p> This feature is available in Postfix 3.7 and later. A weaker
+feature, called smtp_per_record_deadline, is available with Postfix
+2.9-3.6. </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM smtp_bind_address_enforce no
+
+<p> Defer delivery when the Postfix SMTP client cannot apply the
+smtp_bind_address or smtp_bind_address6 setting. By default, the
+Postfix SMTP client will continue delivery after logging a warning.
+</p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM lmtp_bind_address_enforce
+
+<p> The LMTP-specific version of the smtp_bind_address_enforce
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 3.7 and later. </p>
+
+%PARAM tls_config_name
+
+<p> The application name passed by Postfix to OpenSSL library
+initialization functions. This name is used to select the desired
+configuration "section" in the OpenSSL configuration file specified
+via the tls_config_file parameter. When empty, or when the
+selected name is not present in the configuration file, the default
+application name ("openssl_conf") is used as a fallback. </p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.1, 3.7.6,
+3.6.10, and 3.5.20. </p>
+
+%PARAM tls_config_file default
+
+<p> Optional configuration file with baseline OpenSSL settings.
+OpenSSL loads any SSL settings found in the configuration file for
+the selected application name (see tls_config_name) or else the
+built-in application name "openssl_conf" when no application name is
+specified, or no corresponding configuration section is present.
+</p>
+
+<p> With OpenSSL releases 1.1.1 and 1.1.1a, applications (including
+Postfix) can neither specify an alternative configuration file, nor
+avoid loading the default configuration file. </p>
+
+<p> With OpenSSL 1.1.1b or later, this parameter may be set to one of:
+</p>
+
+<dl>
+
+<dt> <b>default</b> (default) </dt> <dd> Load the system-wide
+"openssl.cnf" configuration file. </dd>
+
+<dt> <b>none</b> (recommended, OpenSSL 1.1.1b or later only) </dt>
+<dd> This setting disables loading of the system-wide "openssl.cnf"
+file. </dd>
+
+<dt> <b><i>/absolute-path</i></b> (OpenSSL 1.1.1b or later only) </dt>
+<dd> Load the configuration file specified by <i>/absolute-path</i>.
+With this setting it is an error for the file to not contain any
+settings for the selected tls_config_name. There is no fallback to
+the default "openssl_conf" name. </dd>
+
+</dl>
+
+<p> Failures in processing of the built-in default configuration file,
+are silently ignored. Any errors in loading a non-default configuration
+file are detected by Postfix, and cause TLS support to be disabled.
+</p>
+
+<p> The OpenSSL configuration file format is not documented here,
+beyond giving two examples. <p>
+
+<p> Example: Default settings for all applications. </p>
+
+<blockquote>
+<pre>
+# The name 'openssl_conf' is the default application name
+# The section name to the right of the '=' sign is arbitrary,
+# any name will do, so long as it refers to the desired section.
+#
+# The name 'system_default' selects the settings applied internally
+# by the SSL library as part of SSL object creation. Applications
+# can then apply any additional settings of their choice.
+#
+# In this example, TLS versions prior to 1.2 are disabled by default.
+#
+openssl_conf = system_wide_settings
+[system_wide_settings]
+ssl_conf = ssl_library_settings
+[ssl_library_settings]
+system_default = initial_ssl_settings
+[initial_ssl_settings]
+MinProtocol = TLSv1.2
+</pre>
+</blockquote>
+
+<p> Example: Custom settings for an application named "postfix". </p>
+
+<blockquote>
+<pre>
+# The mapping from an application name to the corresponding configuration
+# section must appear near the top of the file, (in what is sometimes called
+# the "default section") prior to the start of any explicitly named
+# "[sections]". The named sections can appear in any order and don't nest.
+#
+postfix = postfix_settings
+[postfix_settings]
+ssl_conf = postfix_ssl_settings
+[postfix_ssl_settings]
+system_default = baseline_postfix_settings
+[baseline_postfix_settings]
+MinProtocol = TLSv1
+</pre>
+</blockquote>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.1, 3.7.6,
+3.6.10, and 3.5.20. </p>
+
+%PARAM smtpd_forbid_bare_newline Postfix &lt; 3.9: no
+
+<p> Reject or restrict input lines from an SMTP client that end in
+&lt;LF&gt; instead of the standard &lt;CR&gt;&lt;LF&gt;. Such line
+endings are commonly allowed with UNIX-based SMTP servers, but they
+violate RFC 5321, and allowing such line endings can make a server
+vulnerable to <a href="https://www.postfix.org/smtp-smuggling.html">
+SMTP smuggling</a>. </p>
+
+<p> Specify one of the following values (case does not matter): </p>
+
+<dl compact>
+
+<dt> <b>normalize</b></dt> <dd> Require the standard
+End-of-DATA sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+Otherwise, allow command or message content lines ending in the
+non-standard &lt;LF&gt;, and process them as if the client sent the
+standard &lt;CR&gt;&lt;LF&gt;. <br> <br> This maintains compatibility
+with many legitimate SMTP client applications that send a mix of
+standard and non-standard line endings, but will fail to receive
+email from client implementations that do not terminate DATA content
+with the standard End-of-DATA sequence
+&lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. <br> <br> Such clients
+can be excluded with smtpd_forbid_bare_newline_exclusions. </dd>
+
+<dt> <b>yes</b> </dt> <dd> Compatibility alias for <b>normalize</b>. </dd>
+
+<dt> <b>reject</b> </dt> <dd> Require the standard End-of-DATA
+sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. Reject a command
+or message content when a line contains bare &lt;LF&gt;, log a "bare
+&lt;LF&gt; received" error, and reply with the SMTP status code in
+$smtpd_forbid_bare_newline_reject_code. <br> <br> This will reject
+email from SMTP clients that send any non-standard line endings
+such as web applications, netcat, or load balancer health checks.
+<br> <br> This will also reject email from services that use BDAT
+to send MIME text containing a bare newline (RFC 3030 Section 3
+requires canonical MIME format for text message types, defined in
+RFC 2045 Sections 2.7 and 2.8). <br> <br> Such clients can be
+excluded with smtpd_forbid_bare_newline_exclusions (or, in the case
+of BDAT violations, BDAT can be selectively disabled with
+smtpd_discard_ehlo_keyword_address_maps, or globally disabled with
+smtpd_discard_ehlo_keywords). </dd>
+
+<dt> <b>no</b> (default)</dt> <dd> Do not require the standard
+End-of-DATA
+sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;. Always process
+a bare &lt;LF&gt; as if the client sent &lt;CR&gt;&lt;LF&gt;. This
+option is fully backwards compatible, but is not recommended for
+an Internet-facing SMTP server, because it is vulnerable to <a
+href="https://www.postfix.org/smtp-smuggling.html"> SMTP smuggling</a>.
+</dd>
+
+</dl>
+
+<p> Recommended settings: </p>
+
+<blockquote>
+<pre>
+# Require the standard End-of-DATA sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+# Otherwise, allow bare &lt;LF&gt; and process it as if the client sent
+# &lt;CR&gt;&lt;LF&gt;.
+#
+# This maintains compatibility with many legitimate SMTP client
+# applications that send a mix of standard and non-standard line
+# endings, but will fail to receive email from client implementations
+# that do not terminate DATA content with the standard End-of-DATA
+# sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = normalize
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+</pre>
+</blockquote>
+
+<p> Alternative: </p>
+
+<blockquote>
+<pre>
+# Reject input lines that contain &lt;LF&gt; and log a "bare &lt;LF&gt; received"
+# error. Require that input lines end in &lt;CR&gt;&lt;LF&gt;, and require the
+# standard End-of-DATA sequence &lt;CR&gt;&lt;LF&gt;.&lt;CR&gt;&lt;LF&gt;.
+#
+# This will reject email from SMTP clients that send any non-standard
+# line endings such as web applications, netcat, or load balancer
+# health checks.
+#
+# This will also reject email from services that use BDAT to send
+# MIME text containing a bare newline (RFC 3030 Section 3 requires
+# canonical MIME format for text message types, defined in RFC 2045
+# Sections 2.7 and 2.8).
+#
+# Such clients can be allowlisted with smtpd_forbid_bare_newline_exclusions.
+# The example below allowlists SMTP clients in trusted networks.
+#
+smtpd_forbid_bare_newline = reject
+smtpd_forbid_bare_newline_exclusions = $mynetworks
+#
+# Alternatively, in the case of BDAT violations, BDAT can be selectively
+# disabled with smtpd_discard_ehlo_keyword_address_maps, or globally
+# disabled with smtpd_discard_ehlo_keywords.
+#
+# smtpd_discard_ehlo_keyword_address_maps = cidr:/path/to/file
+# /path/to/file:
+# 10.0.0.0/24 chunking, silent-discard
+# smtpd_discard_ehlo_keywords = chunking, silent-discard
+</pre>
+</blockquote>
+
+<p> This feature with settings <b>yes</b> and <b>no</b> is available
+in Postfix 3.8.4, 3.7.9, 3.6.13, and 3.5.23. Additionally, the
+settings <b>reject</b>, and <b>normalize</b> are available with
+Postfix &ge; 3.9, 3.8.5, 3.7.10, 3.6.14, and 3.5.24. </p>
+
+%PARAM smtpd_forbid_bare_newline_exclusions $mynetworks
+
+<p> Exclude the specified clients from smtpd_forbid_bare_newline
+enforcement. This setting uses the same syntax and parent-domain
+matching behavior as mynetworks. </p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.4, 3.7.9,
+3.6.13, and 3.5.23. </p>
+
+%PARAM smtpd_forbid_bare_newline_reject_code 550
+
+<p>
+The numerical Postfix SMTP server response code when rejecting a
+request with "smtpd_forbid_bare_newline = reject".
+Specify a 5XX status code (521 to disconnect).
+</p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24. </p>
+
+%PARAM cleanup_replace_stray_cr_lf yes
+
+<p> Replace each stray &lt;CR&gt; or &lt;LF&gt; character in message
+content with a space character, to prevent outbound SMTP smuggling,
+and to make the evaluation of Postfix-added DKIM or other signatures
+independent from how a remote mail server handles such characters.
+</p>
+
+<p> SMTP does not allow such characters unless they are part of a
+&lt;CR&gt;&lt;LF&gt; sequence, and different mail systems handle
+such stray characters in an implementation-dependent manner. Stray
+&lt;CR&gt; or &lt;LF&gt; characters could be used for outbound
+SMTP smuggling, where an attacker uses a Postfix server to send
+message content with a non-standard End-of-DATA sequence that
+triggers inbound SMTP smuggling at a remote SMTP server.</p>
+
+<p> The replacement happens before all other content management,
+and before Postfix may add a DKIM etc. signature; if the signature
+were created first, the replacement could invalidate the signature.
+</p>
+
+<p> In addition to preventing SMTP smuggling, replacing stray
+&lt;CR&gt; or &lt;LF&gt; characters ensures that the result of
+signature validation by later mail system will not depend on how
+that mail system handles those stray characters in an
+implementation-dependent manner. </p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.5, 3.7.10,
+3.6.14, and 3.5.24. </p>
+
+%PARAM smtpd_forbid_unauth_pipelining Postfix &ge; 3.9: yes
+
+<p> Disconnect remote SMTP clients that violate RFC 2920 (or 5321)
+command pipelining constraints. The server replies with "554 5.5.0
+Error: SMTP protocol synchronization" and logs the unexpected remote
+SMTP client input. Specify "smtpd_forbid_unauth_pipelining = yes"
+to enable. This feature is enabled by default with Postfix &ge;
+3.9. </p>
+
+<p> This feature is available in Postfix &ge; 3.9, 3.8.1, 3.7.6,
+3.6.10, and 3.5.20. </p>
diff --git a/proto/postfix-wrapper b/proto/postfix-wrapper
new file mode 100644
index 0000000..177282e
--- /dev/null
+++ b/proto/postfix-wrapper
@@ -0,0 +1,290 @@
+#++
+# NAME
+# postfix-wrapper 5
+# SUMMARY
+# Postfix multi-instance API
+# DESCRIPTION
+# Support for managing multiple Postfix instances is available
+# as of version 2.6. Instances share executable files and
+# documentation, but have their own directories for configuration,
+# queue and data files.
+#
+# This document describes how the familiar "postfix start"
+# etc. user interface can be used to manage one or multiple
+# Postfix instances, and gives details of an API to coordinate
+# activities between the postfix(1) command and a multi-instance
+# manager program.
+#
+# With multi-instance support, the default Postfix instance
+# is always required. This instance is identified by the
+# config_directory parameter's default value.
+# GENERAL OPERATION
+# .ad
+# .fi
+# Multi-instance support is backwards compatible: when you
+# run only one Postfix instance, commands such as "postfix
+# start" will not change behavior at all.
+#
+# Even with multiple Postfix instances, you can keep using
+# the same postfix commands in boot scripts, upgrade procedures,
+# and other places. The commands do more work, but humans are
+# not forced to learn new tricks.
+#
+# For example, to start all Postfix instances, use:
+# .IP
+# # postfix start
+# .PP
+# Other postfix(1) commands also work as expected. For example,
+# to find out what Postfix instances exist in a multi-instance
+# configuration, use:
+# .IP
+# # postfix status
+# .PP
+# This enumerates the status of all Postfix instances within
+# a multi-instance configuration.
+# MANAGING AN INDIVIDUAL POSTFIX INSTANCE
+# .ad
+# .fi
+# To manage a specific Postfix instance, specify its configuration
+# directory on the postfix(1) command line:
+# .IP
+# # postfix -c \fI/path/to/config_directory command\fR
+# .PP
+# Alternatively, the postfix(1) command accepts the instance's
+# configuration directory via the MAIL_CONFIG environment
+# variable (the -c command-line option has higher precedence).
+#
+# Otherwise, the postfix(1) command will operate on all Postfix
+# instances.
+# ENABLING POSTFIX(1) MULTI-INSTANCE MODE
+# .ad
+# .fi
+# By default, the postfix(1) command operates in single-instance
+# mode. In this mode the command invokes the postfix-script
+# file directly (currently installed in the daemon directory).
+# This file contains the commands that start or stop one
+# Postfix instance, that upgrade the configuration of one
+# Postfix instance, and so on.
+#
+# When the postfix(1) command operates in multi-instance mode
+# as discussed below, the command needs to execute start,
+# stop, etc. commands for each Postfix instance. This
+# multiplication of commands is handled by a multi-instance
+# manager program.
+#
+# Turning on postfix(1) multi-instance mode goes as follows:
+# in the default Postfix instance's main.cf file, 1) specify
+# the pathname of a multi-instance manager program with the
+# multi_instance_wrapper parameter; 2) populate the
+# multi_instance_directories parameter with the configuration
+# directory pathnames of additional Postfix instances. For
+# example:
+# .IP
+# .nf
+# /etc/postfix/main.cf:
+# multi_instance_wrapper = $daemon_directory/postfix-wrapper
+# multi_instance_directories = /etc/postfix-test
+# .fi
+# .PP
+# The $daemon_directory/postfix-wrapper file implements a
+# simple manager and contains instructions for creating Postfix
+# instances by hand. The postmulti(1) command provides a
+# more extensive implementation including support for life-cycle
+# management.
+#
+# The multi_instance_directories and other main.cf parameters
+# are listed below in the CONFIGURATION PARAMETERS section.
+#
+# In multi-instance mode, the postfix(1) command invokes the
+# $multi_instance_wrapper command instead of the postfix-script
+# file. This multi-instance manager in turn executes the
+# postfix(1) command in single-instance mode for each Postfix
+# instance.
+#
+# To illustrate the main ideas behind multi-instance operation,
+# below is an example of a simple but useful multi-instance
+# manager implementation:
+# .IP
+# .nf
+# #!/bin/sh
+#
+# : ${command_directory?"do not invoke this command directly"}
+#
+# POSTCONF=$command_directory/postconf
+# POSTFIX=$command_directory/postfix
+# instance_dirs=\`$POSTCONF -h multi_instance_directories |
+# sed 's/,/ /'\` || exit 1
+#
+# err=0
+# for dir in $config_directory $instance_dirs
+# do
+# case "$1" in
+# stop|abort|flush|reload|drain)
+# test "\`$POSTCONF -c $dir -h multi_instance_enable\`" \e
+# = yes || continue;;
+# start)
+# test "\`$POSTCONF -c $dir -h multi_instance_enable\`" \e
+# = yes || {
+# $POSTFIX -c $dir check || err=$?
+# continue
+# };;
+# esac
+# $POSTFIX -c $dir "$@" || err=$?
+# done
+#
+# exit $err
+# .fi
+# PER-INSTANCE MULTI-INSTANCE MANAGER CONTROLS
+# .ad
+# .fi
+# Each Postfix instance has its own main.cf file with parameters
+# that control how the multi-instance manager operates on
+# that instance. This section discusses the most important
+# settings.
+#
+# The setting "multi_instance_enable = yes" allows the
+# multi-instance manager to start (stop, etc.) the corresponding
+# Postfix instance. For safety reasons, this setting is not
+# the default.
+#
+# The default setting "multi_instance_enable = no" is useful
+# for manual testing with "postfix -c \fI/path/name\fR start"
+# etc. The multi-instance manager will not start such an
+# instance, and it will skip commands such as "stop" or "flush"
+# that require a running Postfix instance. The multi-instance
+# manager will execute commands such as "check", "set-permissions"
+# or "upgrade-configuration", and it will replace "start" by
+# "check" so that problems will be reported even when the
+# instance is disabled.
+# MAINTAINING SHARED AND NON-SHARED FILES
+# .ad
+# .fi
+# Some files are shared between Postfix instances, such as
+# executables and manpages, and some files are per-instance,
+# such as configuration files, mail queue files, and data
+# files. See the NON-SHARED FILES section below for a list
+# of per-instance files.
+#
+# Before Postfix multi-instance support was implemented, the
+# executables, manpages, etc., have always been maintained
+# as part of the default Postfix instance.
+#
+# With multi-instance support, we simply continue to do this.
+# Specifically, a Postfix instance will not check or update
+# shared files when that instance's config_directory value is
+# listed with the default main.cf file's multi_instance_directories
+# parameter.
+#
+# The consequence of this approach is that the default Postfix
+# instance should be checked and updated before any other
+# instances.
+# MULTI-INSTANCE API SUMMARY
+# .ad
+# .fi
+# Only the multi-instance manager implements support for the
+# multi_instance_enable configuration parameter. The
+# multi-instance manager will start only Postfix instances
+# whose main.cf file has "multi_instance_enable = yes". A
+# setting of "no" allows a Postfix instance to be tested by
+# hand.
+#
+# The postfix(1) command operates on only one Postfix instance
+# when the -c option is specified, or when MAIL_CONFIG is
+# present in the process environment. This is necessary to
+# terminate recursion.
+#
+# Otherwise, when the multi_instance_directories parameter
+# value is non-empty, the postfix(1) command executes the
+# command specified with the multi_instance_wrapper parameter,
+# instead of executing the commands in postfix-script.
+#
+# The multi-instance manager skips commands such as "stop"
+# or "reload" that require a running Postfix instance, when
+# an instance does not have "multi_instance_enable = yes".
+# This avoids false error messages.
+#
+# The multi-instance manager replaces a "start" command by
+# "check" when a Postfix instance's main.cf file does not
+# have "multi_instance_enable = yes". This substitution ensures
+# that problems will be reported even when the instance is
+# disabled.
+#
+# No Postfix command or script will update or check shared
+# files when its config_directory value is listed in the
+# default main.cf's multi_instance_directories parameter
+# value. Therefore, the default instance should be checked
+# and updated before any Postfix instances that depend on it.
+#
+# Set-gid commands such as postdrop(1) and postqueue(1)
+# effectively append the multi_instance_directories parameter
+# value to the legacy alternate_config_directories parameter
+# value. The commands use this information to determine whether
+# a -c option or MAIL_CONFIG environment setting specifies a
+# legitimate value.
+#
+# The legacy alternate_config_directories parameter remains
+# necessary for non-default Postfix instances that are running
+# different versions of Postfix, or that are not managed
+# together with the default Postfix instance.
+# ENVIRONMENT VARIABLES
+# .ad
+# .fi
+# .IP MAIL_CONFIG
+# When present, this forces the postfix(1) command to operate
+# only on the specified Postfix instance. This environment
+# variable is exported by the postfix(1) -c option, so that
+# postfix(1) commands in descendant processes will work
+# correctly.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# The text below provides only a parameter summary. See
+# postconf(5) for more details.
+# .IP "\fBmulti_instance_directories (empty)\fR"
+# An optional list of non-default Postfix configuration directories;
+# these directories belong to additional Postfix instances that share
+# the Postfix executable files and documentation with the default
+# Postfix instance, and that are started, stopped, etc., together
+# with the default Postfix instance.
+# .IP "\fBmulti_instance_wrapper (empty)\fR"
+# The pathname of a multi-instance manager command that the
+# \fBpostfix\fR(1) command invokes when the multi_instance_directories
+# parameter value is non-empty.
+# .IP "\fBmulti_instance_name (empty)\fR"
+# The optional instance name of this Postfix instance.
+# .IP "\fBmulti_instance_group (empty)\fR"
+# The optional instance group name of this Postfix instance.
+# .IP "\fBmulti_instance_enable (no)\fR"
+# Allow this Postfix instance to be started, stopped, etc., by a
+# multi-instance manager.
+# NON-SHARED FILES
+# .ad
+# .fi
+# .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 "\fBqueue_directory (see 'postconf -d' output)\fR"
+# The location of the Postfix top-level queue directory.
+# SEE ALSO
+# postfix(1) Postfix control program
+# postmulti(1) full-blown multi-instance manager
+# $daemon_directory/postfix-wrapper simple multi-instance manager
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/regexp_table b/proto/regexp_table
new file mode 100644
index 0000000..1c38472
--- /dev/null
+++ b/proto/regexp_table
@@ -0,0 +1,209 @@
+#++
+# NAME
+# regexp_table 5
+# SUMMARY
+# format of Postfix regular expression tables
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" regexp:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - regexp:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting, mail routing, or access control. These tables
+# are usually in \fBdbm\fR or \fBdb\fR format.
+#
+# Alternatively, lookup tables can be specified in POSIX regular
+# expression form. In this case, each input is compared against a
+# list of patterns. When a match is found, the corresponding
+# result is returned and the search is terminated.
+#
+# To find out what types of lookup tables your Postfix system
+# supports use the "\fBpostconf -m\fR" command.
+#
+# To test lookup tables, use the "\fBpostmap -q\fR" command
+# as described in the SYNOPSIS above. Use "\fBpostmap -hmq
+# -\fR <\fIfile\fR" for header_checks(5) patterns, and
+# "\fBpostmap -bmq -\fR <\fIfile\fR" for body_checks(5)
+# (Postfix 2.6 and later).
+# COMPATIBILITY
+# .ad
+# .fi
+# With Postfix version 2.2 and earlier specify "\fBpostmap
+# -fq\fR" to query a table that contains case sensitive
+# patterns. Patterns are case insensitive by default.
+# TABLE FORMAT
+# .ad
+# .fi
+# The general form of a Postfix regular expression table is:
+# .IP "\fB/\fIpattern\fB/\fIflags result\fR"
+# When \fIpattern\fR matches the input string,
+# use the corresponding \fIresult\fR value.
+# .IP "\fB!/\fIpattern\fB/\fIflags result\fR"
+# When \fIpattern\fR does \fBnot\fR match the input string,
+# use the corresponding \fIresult\fR value.
+# .IP "\fBif /\fIpattern\fB/\fIflags\fR"
+# .IP "\fBendif\fR"
+# If the input string matches /\fIpattern\fR/, then match that
+# input string against the patterns between \fBif\fR and
+# \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
+# .sp
+# Note: do not prepend whitespace to patterns inside
+# \fBif\fR..\fBendif\fR.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .IP "\fBif !/\fIpattern\fB/\fIflags\fR"
+# .IP "\fBendif\fR"
+# If the input string does not match /\fIpattern\fR/, then
+# match that input string against the patterns between \fBif\fR
+# and \fBendif\fR. The \fBif\fR..\fBendif\fR can nest.
+# .sp
+# Note: do not prepend whitespace to patterns inside
+# \fBif\fR..\fBendif\fR.
+# .sp
+# This feature is available in Postfix 2.1 and later.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# .PP
+# Each pattern is a POSIX regular expression enclosed by a pair of
+# delimiters. The regular expression syntax is documented in
+# \fBre_format\fR(7) with 4.4BSD, in \fBregex\fR(5) with Solaris, and in
+# \fBregex\fR(7) with Linux. Other systems may use other document names.
+#
+# The expression delimiter can be any non-alphanumerical
+# character, except whitespace
+# or characters that have special meaning (traditionally the forward
+# slash is used). The regular expression can contain whitespace.
+#
+# By default, matching is case-insensitive, and newlines are not
+# treated as special characters. The behavior is controlled by flags,
+# which are toggled by appending one or more of the following
+# characters after the pattern:
+# .IP "\fBi\fR (default: on)"
+# Toggles the case sensitivity flag. By default, matching is case
+# insensitive.
+# .IP "\fBm\fR (default: off)"
+# Toggle the multi-line mode flag. When this flag is on, the \fB^\fR
+# and \fB$\fR metacharacters match immediately after and immediately
+# before a newline character, respectively, in addition to
+# matching at the start and end of the input string.
+# .IP "\fBx\fR (default: on)"
+# Toggles the extended expression syntax flag. By default, support
+# for extended expression syntax is enabled.
+# TABLE SEARCH ORDER
+# .ad
+# .fi
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the input string.
+#
+# Each pattern is applied to the entire input string.
+# Depending on the application, that string is an entire client
+# hostname, an entire client IP address, or an entire mail address.
+# Thus, no parent domain or parent network search is done, and
+# \fIuser@domain\fR mail addresses are not broken up into their
+# \fIuser\fR and \fIdomain\fR constituent parts, nor is \fIuser+foo\fR
+# broken up into \fIuser\fR and \fIfoo\fR.
+# TEXT SUBSTITUTION
+# .ad
+# .fi
+# Substitution of substrings (text that matches patterns
+# inside "()") from the matched expression into the result
+# string is requested with $1, $2, etc.; specify $$ to produce
+# a $ character as output.
+# The macros in the result string may need to be written as
+# ${n} or $(n) if they aren't followed by whitespace.
+#
+# Note: since negated patterns (those preceded by \fB!\fR) return a
+# result when the expression does not match, substitutions are not
+# available for negated patterns.
+# INLINE SPECIFICATION
+# .ad
+# .fi
+# The contents of a table may be specified in the table name
+# (Postfix 3.7 and later).
+# The basic syntax is:
+#
+# .nf
+# main.cf:
+# \fIparameter\fR \fB= .. regexp:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } ..\fR
+#
+# master.cf:
+# \fB.. -o { \fIparameter\fR \fB= .. regexp:{ { \fIrule-1\fB }, { \fIrule-2\fB } .. } .. } ..\fR
+# .fi
+#
+# Postfix ignores whitespace after '{' and before '}', and
+# writes each \fIrule\fR as one text line to an in-memory
+# file:
+#
+# .nf
+# in-memory file:
+# rule-1
+# rule-2
+# ..
+# .fi
+#
+# Postfix parses the result as if it is a file in /etc/postfix.
+#
+# Note: if a rule contains \fB$\fR, specify \fB$$\fR to keep
+# Postfix from trying to do \fI$name\fR expansion as it
+# evaluates a parameter value.
+# EXAMPLE SMTPD ACCESS MAP
+# # Disallow sender-specified routing. This is a must if you relay mail
+# # for other domains.
+# /[%!@].*[%!@]/ 550 Sender-specified routing rejected
+#
+# # Postmaster is OK, that way they can talk to us about how to fix
+# # their problem.
+# /^postmaster@/ OK
+#
+# # Protect your outgoing majordomo exploders
+# if !/^owner-/
+# /^(.*)-outgoing@(.*)$/ 550 Use ${1}@${2} instead
+# endif
+# EXAMPLE HEADER FILTER MAP
+# # These were once common in junk mail.
+# /^Subject: make money fast/ REJECT
+# /^To: friend@public\\.com/ REJECT
+# EXAMPLE BODY FILTER MAP
+# # First skip over base 64 encoded text to save CPU cycles.
+# ~^[[:alnum:]+/]{60,}$~ OK
+#
+# # Put your own body patterns here.
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# pcre_table(5), format of PCRE tables
+# cidr_table(5), format of CIDR tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# AUTHOR(S)
+# The regexp table lookup code was originally written by:
+# LaMont Jones
+# lamont@hp.com
+#
+# That code was based on the PCRE dictionary contributed by:
+# Andrew McNamara
+# andrewm@connect.com.au
+# connect.com.au Pty. Ltd.
+# Level 3, 213 Miller St
+# North Sydney, NSW, Australia
+#
+# Adopted and adapted by:
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/relocated b/proto/relocated
new file mode 100644
index 0000000..a0a54ca
--- /dev/null
+++ b/proto/relocated
@@ -0,0 +1,166 @@
+#++
+# NAME
+# relocated 5
+# SUMMARY
+# Postfix relocated table format
+# SYNOPSIS
+# \fBpostmap /etc/postfix/relocated\fR
+# DESCRIPTION
+# The optional \fBrelocated\fR(5) table provides the information that is
+# used in "user has moved to \fInew_location\fR" bounce messages.
+#
+# Normally, the \fBrelocated\fR(5) table is specified as a text file
+# that serves as input to the \fBpostmap\fR(1) command.
+# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
+# is used for fast searching by the mail system. Execute the command
+# "\fBpostmap /etc/postfix/relocated\fR" to rebuild an indexed
+# file after changing the corresponding relocated table.
+#
+# When the table is provided via other means such as NIS, LDAP
+# or SQL, the same lookups are done as for ordinary indexed files.
+#
+# Alternatively, the table can be provided as a regular-expression
+# map where patterns are given as regular expressions, or lookups
+# can be directed to a TCP-based server. In those case, the lookups
+# are done in a slightly different way as described below under
+# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES".
+#
+# Table lookups are case insensitive.
+# CASE FOLDING
+# .ad
+# .fi
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+# TABLE FORMAT
+# .ad
+# .fi
+# The input format for the \fBpostmap\fR(1) command is as follows:
+# .IP \(bu
+# An entry has one of the following form:
+#
+# .nf
+# \fIpattern new_location\fR
+# .fi
+#
+# Where \fInew_location\fR specifies contact information such as
+# an email address, or perhaps a street address or telephone number.
+# .IP \(bu
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP \(bu
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# TABLE SEARCH ORDER
+# .ad
+# .fi
+# With lookups from indexed files such as DB or DBM, or from networked
+# tables such as NIS, LDAP or SQL, patterns are tried in the order as
+# listed below:
+# .IP \fIuser\fR@\fIdomain\fR
+# Matches \fIuser\fR@\fIdomain\fR. This form has precedence over all
+# other forms.
+# .IP \fIuser\fR
+# Matches \fIuser\fR@\fIsite\fR when \fIsite\fR is $\fBmyorigin\fR,
+# when \fIsite\fR is listed in $\fBmydestination\fR, or when \fIsite\fR
+# is listed in $\fBinet_interfaces\fR or $\fBproxy_interfaces\fR.
+# .IP @\fIdomain\fR
+# Matches other addresses in \fIdomain\fR. This form has the lowest
+# precedence.
+# ADDRESS EXTENSION
+# .fi
+# .ad
+# When a mail address localpart contains the optional recipient delimiter
+# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
+# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
+# \fIuser\fR, and @\fIdomain\fR.
+# REGULAR EXPRESSION TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when the table
+# is given in the form of regular expressions or when lookups are
+# directed to a TCP-based server. For a description of regular
+# expression lookup table syntax, see \fBregexp_table\fR(5) or
+# \fBpcre_table\fR(5). For a description of the TCP client/server
+# table lookup protocol, see \fBtcp_table\fR(5).
+# This feature is available in Postfix 2.5 and later.
+#
+# Each pattern is a regular expression that is applied to the entire
+# address being looked up. Thus, \fIuser@domain\fR mail addresses are not
+# broken up into their \fIuser\fR and \fI@domain\fR constituent parts,
+# nor is \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the search string.
+#
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from the
+# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on.
+# TCP-BASED TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when lookups
+# are directed to a TCP-based server. For a description of the TCP
+# client/server lookup protocol, see \fBtcp_table\fR(5).
+# This feature is available in Postfix 2.5 and later.
+#
+# Each lookup operation uses the entire address once. Thus,
+# \fIuser@domain\fR mail addresses are not broken up into their
+# \fIuser\fR and \fI@domain\fR constituent parts, nor is
+# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Results are the same as with indexed file lookups.
+# BUGS
+# The table format does not understand quoting conventions.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# The following \fBmain.cf\fR parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# \fBpostconf\fR(5) for more details including examples.
+# .IP "\fBrelocated_maps (empty)\fR"
+# Optional lookup tables with new contact information for users or
+# domains that no longer exist.
+# .PP
+# Other parameters of interest:
+# .IP "\fBinet_interfaces (all)\fR"
+# The network interface addresses that this mail system receives
+# mail on.
+# .IP "\fBmydestination ($myhostname, localhost.$mydomain, localhost)\fR"
+# The list of domains that are delivered via the $local_transport
+# mail delivery transport.
+# .IP "\fBmyorigin ($myhostname)\fR"
+# The domain name that locally-posted mail appears to come
+# from, and that locally posted mail is delivered to.
+# .IP "\fBproxy_interfaces (empty)\fR"
+# The network interface addresses that this mail system receives mail
+# on by way of a proxy or network address translation unit.
+# SEE ALSO
+# trivial-rewrite(8), address resolver
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# ADDRESS_REWRITING_README, address rewriting guide
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/socketmap_table b/proto/socketmap_table
new file mode 100644
index 0000000..be01054
--- /dev/null
+++ b/proto/socketmap_table
@@ -0,0 +1,96 @@
+#++
+# NAME
+# socketmap_table 5
+# SUMMARY
+# Postfix socketmap table lookup client
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" socketmap:inet:\fIhost\fB:\fIport\fB:\fIname\fR
+# .br
+# \fBpostmap -q "\fIstring\fB" socketmap:unix:\fIpathname\fB:\fIname\fR
+#
+# \fBpostmap -q - socketmap:inet:\fIhost\fB:\fIport\fB:\fIname\fB <\fIinputfile\fR
+# .br
+# \fBpostmap -q - socketmap:unix:\fIpathname\fB:\fIname\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting. mail routing or policy lookup.
+#
+# The Postfix socketmap client expects TCP endpoint names of
+# the form \fBinet:\fIhost\fB:\fIport\fB:\fIname\fR, or
+# UNIX-domain endpoints of the form \fBunix:\fIpathname\fB:\fIname\fR.
+# In both cases, \fIname\fR specifies the name field in a
+# socketmap client request (see "REQUEST FORMAT" below).
+# PROTOCOL
+# .ad
+# .fi
+# Socketmaps use a simple protocol: the client sends one
+# request, and the server sends one reply. Each request and
+# each reply are sent as one netstring object.
+# REQUEST FORMAT
+# .ad
+# .fi
+# The socketmap protocol supports only the lookup request.
+# The request has the following form:
+#
+# .IP "\fB\fIname\fB <space> \fIkey\fR"
+# Search the named socketmap for the specified key.
+# .PP
+# Postfix will not generate partial search keys such as domain
+# names without one or more subdomains, network addresses
+# without one or more least-significant octets, or email
+# addresses without the localpart, address extension or domain
+# portion. This behavior is also found with cidr:, pcre:, and
+# regexp: tables.
+# REPLY FORMAT
+# .ad
+# .fi
+# The Postfix socketmap client requires that replies are not
+# longer than 100000 characters (not including the netstring
+# encapsulation). Replies must have the following form:
+# .IP "\fBOK <space> \fIdata\fR"
+# The requested data was found.
+# .IP "\fBNOTFOUND <space>"
+# The requested data was not found.
+# .IP "\fBTEMP <space> \fIreason\fR"
+# .IP "\fBTIMEOUT <space> \fIreason\fR"
+# .IP "\fBPERM <space> \fIreason\fR"
+# The request failed. The reason, if non-empty, is descriptive
+# text.
+# SECURITY
+# This map cannot be used for security-sensitive information,
+# because neither the connection nor the server are authenticated.
+# SEE ALSO
+# http://cr.yp.to/proto/netstrings.txt, netstring definition
+# postconf(1), Postfix supported lookup tables
+# postmap(1), Postfix lookup table manager
+# regexp_table(5), format of regular expression tables
+# pcre_table(5), format of PCRE tables
+# cidr_table(5), format of CIDR tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# BUGS
+# The protocol limits are not yet configurable.
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# Socketmap support was introduced with Postfix version 2.10.
+# AUTHOR(S)
+# Wietse Venema
+# IBM T.J. Watson Research
+# P.O. Box 704
+# Yorktown Heights, NY 10598, USA
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
+
diff --git a/proto/sqlite_table b/proto/sqlite_table
new file mode 100644
index 0000000..a4edf72
--- /dev/null
+++ b/proto/sqlite_table
@@ -0,0 +1,261 @@
+#++
+# NAME
+# sqlite_table 5
+# SUMMARY
+# Postfix SQLite configuration
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" sqlite:/etc/postfix/\fIfilename\fR
+#
+# \fBpostmap -q - sqlite:/etc/postfix/\fIfilename\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting or mail routing. These tables are usually in
+# \fBdbm\fR or \fBdb\fR format.
+#
+# Alternatively, lookup tables can be specified as SQLite databases.
+# In order to use SQLite lookups, define an SQLite source as a lookup
+# table in main.cf, for example:
+# .nf
+# alias_maps = sqlite:/etc/postfix/sqlite-aliases.cf
+# .fi
+#
+# The file /etc/postfix/sqlite-aliases.cf has the same format as
+# the Postfix main.cf file, and can specify the parameters
+# described below.
+# LIST MEMBERSHIP
+# .ad
+# .fi
+# When using SQL to store lists such as $mynetworks,
+# $mydestination, $relay_domains, $local_recipient_maps,
+# etc., it is important to understand that the table must
+# store each list member as a separate key. The table lookup
+# verifies the *existence* of the key. See "Postfix lists
+# versus tables" in the DATABASE_README document for a
+# discussion.
+#
+# Do NOT create tables that return the full list of domains
+# in $mydestination or $relay_domains etc., or IP addresses
+# in $mynetworks.
+#
+# DO create tables with each matching item as a key and with
+# an arbitrary value. With SQL databases it is not uncommon to
+# return the key itself or a constant value.
+# SQLITE PARAMETERS
+# .ad
+# .fi
+# .IP "\fBdbpath\fR"
+# The SQLite database file location. Example:
+# .nf
+# dbpath = customer_database
+# .fi
+# .IP "\fBquery\fR"
+# The SQL query template used to search the database, where \fB%s\fR
+# is a substitute for the address Postfix is trying to resolve,
+# e.g.
+# .nf
+# query = SELECT replacement FROM aliases WHERE mailbox = '%s'
+# .fi
+#
+# This parameter supports the following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character.
+# .IP "\fB%s\fR"
+# This is replaced by the input key.
+# SQL quoting is used to make sure that the input key does not
+# add unexpected metacharacters.
+# .IP "\fB%u\fR"
+# When the input key is an address of the form user@domain, \fB%u\fR
+# is replaced by the SQL quoted local part of the address.
+# Otherwise, \fB%u\fR is replaced by the entire search string.
+# If the localpart is empty, the query is suppressed and returns
+# no results.
+# .IP "\fB%d\fR"
+# When the input key is an address of the form user@domain, \fB%d\fR
+# is replaced by the SQL quoted domain part of the address.
+# Otherwise, the query is suppressed and returns no results.
+# .IP "\fB%[SUD]\fR"
+# The upper-case equivalents of the above expansions behave in the
+# \fBquery\fR parameter identically to their lower-case counter-parts.
+# With the \fBresult_format\fR parameter (see below), they expand the
+# input key rather than the result value.
+# .IP "\fB%[1-9]\fR"
+# The patterns %1, %2, ... %9 are replaced by the corresponding
+# most significant component of the input key's domain. If the
+# input key is \fIuser@mail.example.com\fR, then %1 is \fBcom\fR,
+# %2 is \fBexample\fR and %3 is \fBmail\fR. If the input key is
+# unqualified or does not have enough domain components to satisfy
+# all the specified patterns, the query is suppressed and returns
+# no results.
+# .RE
+# .IP
+# The \fBdomain\fR parameter described below limits the input
+# keys to addresses in matching domains. When the \fBdomain\fR
+# parameter is non-empty, SQL queries for unqualified addresses
+# or addresses in non-matching domains are suppressed
+# and return no results.
+#
+# This parameter is available with Postfix 2.2. In prior releases
+# the SQL query was built from the separate parameters:
+# \fBselect_field\fR, \fBtable\fR, \fBwhere_field\fR and
+# \fBadditional_conditions\fR. The mapping from the old parameters
+# to the equivalent query is:
+#
+# .nf
+# SELECT [\fBselect_field\fR]
+# FROM [\fBtable\fR]
+# WHERE [\fBwhere_field\fR] = '%s'
+# [\fBadditional_conditions\fR]
+# .fi
+#
+# The '%s' in the \fBWHERE\fR clause expands to the escaped search string.
+# With Postfix 2.2 these legacy parameters are used if the \fBquery\fR
+# parameter is not specified.
+#
+# NOTE: DO NOT put quotes around the query parameter.
+# .IP "\fBresult_format (default: \fB%s\fR)\fR"
+# Format template applied to result attributes. Most commonly used
+# to append (or prepend) text to the result. This parameter supports
+# the following '%' expansions:
+# .RS
+# .IP "\fB%%\fR"
+# This is replaced by a literal '%' character.
+# .IP "\fB%s\fR"
+# This is replaced by the value of the result attribute. When
+# result is empty it is skipped.
+# .IP "\fB%u\fR
+# When the result attribute value is an address of the form
+# user@domain, \fB%u\fR is replaced by the local part of the
+# address. When the result has an empty localpart it is skipped.
+# .IP "\fB%d\fR"
+# When a result attribute value is an address of the form
+# user@domain, \fB%d\fR is replaced by the domain part of
+# the attribute value. When the result is unqualified it
+# is skipped.
+# .IP "\fB%[SUD1-9]\fR"
+# The upper-case and decimal digit expansions interpolate
+# the parts of the input key rather than the result. Their
+# behavior is identical to that described with \fBquery\fR,
+# and in fact because the input key is known in advance, queries
+# whose key does not contain all the information specified in
+# the result template are suppressed and return no results.
+# .RE
+# .IP
+# For example, using "result_format = smtp:[%s]" allows one
+# to use a mailHost attribute as the basis of a transport(5)
+# table. After applying the result format, multiple values
+# are concatenated as comma separated strings. The expansion_limit
+# and parameter explained below allows one to restrict the number
+# of values in the result, which is especially useful for maps that
+# must return at most one value.
+#
+# The default value \fB%s\fR specifies that each result value should
+# be used as is.
+#
+# This parameter is available with Postfix 2.2 and later.
+#
+# NOTE: DO NOT put quotes around the result format!
+# .IP "\fBdomain (default: no domain list)\fR"
+# This is a list of domain names, paths to files, or "type:table"
+# databases. When specified, only fully qualified search
+# keys with a *non-empty* localpart and a matching domain
+# are eligible for lookup: 'user' lookups, bare domain lookups
+# and "@domain" lookups are not performed. This can significantly
+# reduce the query load on the SQLite server.
+# .nf
+# domain = postfix.org, hash:/etc/postfix/searchdomains
+# .fi
+#
+# It is best not to use SQL to store the domains eligible
+# for SQL lookups.
+#
+# This parameter is available with Postfix 2.2 and later.
+#
+# NOTE: DO NOT define this parameter for local(8) aliases,
+# because the input keys are always unqualified.
+# .IP "\fBexpansion_limit (default: 0)\fR"
+# A limit on the total number of result elements returned
+# (as a comma separated list) by a lookup against the map.
+# A setting of zero disables the limit. Lookups fail with a
+# temporary error if the limit is exceeded. Setting the
+# limit to 1 ensures that lookups do not return multiple
+# values.
+# OBSOLETE MAIN.CF PARAMETERS
+# .ad
+# .fi
+# For compatibility with other Postfix lookup tables, SQLite
+# parameters can also be defined in main.cf. In order to do that,
+# specify as SQLite source a name that doesn't begin with a slash
+# or a dot. The SQLite parameters will then be accessible as the
+# name you've given the source in its definition, an underscore,
+# and the name of the parameter. For example, if the map is
+# specified as "sqlite:\fIsqlitename\fR", the parameter "query"
+# would be defined in main.cf as "\fIsqlitename\fR_query".
+# OBSOLETE QUERY INTERFACE
+# .ad
+# .fi
+# This section describes an interface that is deprecated as
+# of Postfix 2.2. It is replaced by the more general \fBquery\fR
+# interface described above. If the \fBquery\fR parameter
+# is defined, the legacy parameters described here ignored.
+# Please migrate to the new interface as the legacy interface
+# may be removed in a future release.
+#
+# The following parameters can be used to fill in a
+# SELECT template statement of the form:
+#
+# .nf
+# SELECT [\fBselect_field\fR]
+# FROM [\fBtable\fR]
+# WHERE [\fBwhere_field\fR] = '%s'
+# [\fBadditional_conditions\fR]
+# .fi
+#
+# The specifier %s is replaced by the search string, and is
+# escaped so if it contains single quotes or other odd characters,
+# it will not cause a parse error, or worse, a security problem.
+# .IP "\fBselect_field\fR"
+# The SQL "select" parameter. Example:
+# .nf
+# \fBselect_field\fR = forw_addr
+# .fi
+# .IP "\fBtable\fR"
+# The SQL "select .. from" table name. Example:
+# .nf
+# \fBtable\fR = mxaliases
+# .fi
+# .IP "\fBwhere_field\fR
+# The SQL "select .. where" parameter. Example:
+# .nf
+# \fBwhere_field\fR = alias
+# .fi
+# .IP "\fBadditional_conditions\fR
+# Additional conditions to the SQL query. Example:
+# .nf
+# \fBadditional_conditions\fR = AND status = 'paid'
+# .fi
+# SEE ALSO
+# postmap(1), Postfix lookup table maintenance
+# postconf(5), configuration parameters
+# ldap_table(5), LDAP lookup tables
+# mysql_table(5), MySQL lookup tables
+# pgsql_table(5), PostgreSQL lookup tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# SQLITE_README, Postfix SQLITE howto
+# LICENSE
+# .ad
+# .fi
+# The Secure Mailer license must be distributed with this software.
+# HISTORY
+# SQLite support was introduced with Postfix version 2.8.
+# AUTHOR(S)
+# Original implementation by:
+# Axel Steiner
+#--
diff --git a/proto/stop b/proto/stop
new file mode 100644
index 0000000..8682f8e
--- /dev/null
+++ b/proto/stop
@@ -0,0 +1,1564 @@
+DHCP
+DNS
+IMAP
+IP
+ISP
+MX
+PPP
+RC
+README
+RFC
+Sendmail's
+Wietse
+cdb
+cf
+com
+db
+dbm
+dialup
+dns
+domainname
+download
+firewalled
+generic
+grep
+hostname
+html
+http
+inet
+intranet
+ip
+isp
+janes
+joes
+localdomain
+localhost
+localpart
+mailhost
+mailq
+mydestination
+mydomain
+myhostname
+mynetworks
+myorigin
+newaliases
+nullclient
+org
+postconf
+postmap
+relayhost
+sbin
+sendmail
+smtp
+smtpd
+smtprelay
+someprovider
+subdomains
+tld
+unauth
+usr
+wietse
+www
+Bcc
+Firstname
+LDAP
+LINUX
+LMTP
+Lastname
+NIS
+SQL
+SYSV
+Venema
+bangpath
+firstname
+hosta
+hostb
+lastname
+ldap
+lmtp
+luser
+mysql
+nis
+otherdomain
+otheruser
+pcre
+pgsql
+privs
+qmgr
+qmqpd
+regexp
+std
+sysadmin
+userid
+username
+Autoreplies
+CDB
+DBM
+Howto
+MAILDROP
+MYSQL
+Maildir
+MySQL
+PGSQL
+PgSQL
+Postfix's
+Spammers
+UID
+argv
+autoreplies
+autoreply
+berkeley
+chroot
+com's
+hostnames
+internet
+jim
+listname
+mailBOX
+mailDIRs
+maildir
+maildrop
+majordomo
+maxproc
+spam
+uid
+unix
+unpriv
+var
+vhosts
+vmailbox
+vs
+wildcard
+AG
+AHRlc
+AUTH
+AUXLIBS
+BITMIME
+CCARGS
+DUSE
+Daia
+EHLO
+ESMTP
+ETRN
+Franke
+FreeBSD
+Hoos
+Linux
+Liviu
+MMIME
+OTP
+RedHat
+RwYXNz
+SASL
+SASL's
+Solaris
+Strace
+SuSE
+UCE
+ZXN
+andrew
+auth
+auxprop
+chrooted
+cmu
+conf
+cpan
+dGVzdAB
+docs
+edu
+elses
+exampleuser
+ftp
+ktrace
+ld
+lib
+lsasl
+maillog
+mech
+metamail
+mmencode
+passwd
+perl
+plaintext
+plugin
+plugins
+printf
+pwcheck
+sasl
+saslauthd
+sasldb
+sasldblistusers
+saslpasswd
+sql
+su
+symlink
+tarball
+testpass
+CC
+CONFIG
+DDEF
+DEF
+DFD
+DIR
+Debian
+FD
+FILIO
+FIONREAD
+FREEBSD
+GCC
+HTML
+IRIX
+MAILQ
+MANPAGE
+MANPATH
+MacOSX
+NEWALIAS
+NEXTSTEP
+NetBSD
+OPENSTEP
+OSF
+OSX
+PCRE
+Perl
+PostgreSQL
+SENDMAIL
+SETSIZE
+SUNOS
+SUNWspro
+SYSTEMTYPE
+Sendmail
+Slackware
+SunOS
+TLS
+UX
+ansic
+bd
+bi
+bp
+cc
+ccs
+cd
+chmod
+config
+defs
+egrep
+ifdef
+init
+libexec
+lndir
+logfile
+logfiles
+mailserver
+makedefs
+manpage
+mantools
+mv
+postdrop
+postprocessing
+postqueue
+pre
+pwd
+qwhatever
+readme
+setenv
+syslog
+syslogd
+util
+DoS
+Duchovni
+FF
+MTA
+QSHAPE
+Requeing
+SYN
+algonet
+aristotle
+backoff
+bbde
+bcc
+bitmask
+cn
+extremepricecuts
+fr
+gjr
+google
+gotdns
+gov
+gzd
+heyhihellothere
+highvolume
+hinet
+hotmail
+ids
+malware
+meri
+misconfiguring
+ms
+msg
+msn
+nexthop
+osn
+paknet
+pk
+pleazerzoneprod
+postsuper
+qshape
+reprocessing
+setgid
+sourceforge
+spammers
+timestamp
+toppoint
+transport's
+transportname
+undeliverables
+uwasa
+winnersdaily
+worldnet
+FAQ
+MB
+SMTPD
+args
+fd
+fs
+helo
+ipc
+maxfiles
+maxfilesperproc
+maxsockets
+nl
+nmbclusters
+proc
+rcpts
+resolv
+rlim
+solaris
+sysctl
+Ctrl
+ECC
+XAUTHORITY
+Xauthority
+anonymize
+cont
+csh
+gdb
+loopback
+ltrace
+oqmgr
+postfinger
+sotruss
+strace
+tcpdump
+BUILTIN
+SPAM
+website
+HELO
+Mozilla
+Netscape
+VirusWarning
+dk
+dkuug
+spammer
+txt
+wtf
+PERL
+Rq
+TEMPFAIL
+XFORWARD
+inetd
+rm
+smtpprox
+sysexits
+xforward
+xxx
+yyy
+DSN
+RBL
+RCPT
+ehlo
+proxying
+SPF
+Whitelisting
+XCLIENT
+etrn
+greylisting
+rfc
+unreplyable
+websites
+whitelisting
+DUNNO
+Greylisting
+VRFY
+aol
+attr
+bigfoot
+chown
+dunno
+greylist
+headername
+headertext
+lc
+mkdir
+mta
+neohapsis
+obj
+pl
+pobox
+securityfocus
+spf
+tmp
+ttl
+AOL
+VERP
+btree
+interruptus
+mis
+sender's
+whitelist
+rbl
+spoofing
+IDs
+Oct
+mx
+nrcpt
+qRdestination
+qRdomain
+sdestination
+sdomain
+LinxNet
+SSL
+Sanders's
+Seymour's
+au
+jdp
+jimsun
+recipien
+rmail
+stunnel
+taz
+tcp
+uux
+dir
+foobar
+pag
+postalias
+proxymap
+BerkeleyDB
+DHAS
+MBytes
+UNIXWARE
+UNIXes
+bsd
+condattr
+fcntl
+kBytes
+ldb
+linux
+lpthread
+mutex
+mutexattr
+pthread
+setpshared
+sleepycat
+trylock
+DN
+Guesdon
+Haahtinen
+Hensley
+Hery
+Hoeger
+KTH
+Kerberos
+LDAPv
+LaMont
+Linux's
+Maildrops
+Mattice
+OpenLDAP
+Prabhat
+Rakotoarisoa
+SDKs
+STARTTLS
+Sami
+Tardieu
+URL
+accountingstaff
+dc
+defaultrecipient
+dirsvcs
+dn
+hmmmm
+kerberos
+ldapuser
+libdns
+libldap
+libldapssl
+llber
+lldap
+mailacceptinggeneralid
+mailacceptinggeneralids
+maildrops
+maillist
+mylist
+normaluser
+objectclass
+openldap
+realuser
+slapd
+slurpd
+someserver
+theother
+tls
+umich
+virtualaccount
+wildcards
+IC
+addr
+dbname
+downloads
+forw
+libm
+libz
+lm
+lmysqlclient
+lz
+mxaliases
+mysqlclient
+POSIX
+ac
+csx
+lpcre
+uk
+Sethman
+libpq
+lpq
+QMQP
+XVERP
+cr
+ezmlm
+prefixuser
+qmail
+qmqp
+verp
+yourname
+yp
+Procmail
+Syslogd
+devel
+procmail
+MTAs
+Netapp
+dotlock
+DECstation
+NOFILE
+RLIMIT
+Roques
+getdtablesize
+getrlimit
+von
+zsh
+DRhu
+Earnshaw
+Maildrop
+Mosemann
+Tonni
+someother
+userdb
+vmail
+bv
+dest
+ination
+makemap
+postcat
+postkick
+postlock
+postlog
+postsomething
+showq
+BCC
+CR
+Cc
+Helo
+LF
+LHLO
+LOGNAME
+MicroSoft
+PID
+PTR
+RFCs
+RSET
+SCO
+Subdomain
+TZ
+YYYYMMDD
+admin
+ain
+aliasname
+bitmime
+cl
+dequoted
+faqs
+fetchmail
+fqdn
+gethostbyname
+gethostname
+hopcount
+hostaddress
+ient
+ifconfig
+ish
+lhlo
+localparts
+lockfile
+mailtool
+minfree
+multipart
+mydom
+mysmtp
+netmask
+noactive
+noanonymous
+nodictionary
+noplaintext
+ns
+nsswitch
+octets
+partialdomainname
+patchlevel
+pid
+provider's
+rcpt
+relayhostname
+ress
+rfcs
+rhsbl
+rset
+sendmail's
+servername
+smrsh
+spams
+ss
+subdomain
+uucphost
+vrfy
+xclient
+xfer
+ipaddress
+gz
+gzip
+outputfile
+umask
+xargs
+xvpf
+Patrik
+Rak
+Rak's
+emails
+nqmgr
+AAE
+ADDR
+CF
+IPV
+IPv
+MTA's
+SP
+TEMPUNAVAIL
+xtext
+CIDR
+FQDN
+Hildebrandt
+OpenBSD
+Pflogsumm
+Pflogsumm's
+Zeikat
+cidr
+faq
+howto
+linxnet
+mailhub
+mpack
+nt
+pflogg
+pflogsumm
+recipie
+spoofed
+ACK
+Ac
+BDFORhqu
+BSMTP
+DNs
+DOTALL
+Dtv
+Dv
+ENDONLY
+EOF
+Fpath
+Fsome
+Gouaux
+IFRAME
+INET
+INT
+IPC
+Idem
+Jozsef
+KFKI
+Kadlecsik
+MAILDIR
+MC
+MULTILINE
+McNamara
+Mirapoint
+Modra
+NN
+NSW
+NY
+Nfinoprvw
+ONELEVEL
+OQMGR
+OpenSSL
+PEM
+POSTALIAS
+POSTCAT
+POSTCONF
+POSTDROP
+POSTKICK
+POSTLOCK
+POSTLOG
+POSTMAP
+POSTQUEUE
+POSTSUPER
+PROXYMAP
+Prindeville
+Pty
+QMAIL
+QMGR
+QMQPD
+REGEXP
+REQ
+ROMANIA
+RS
+Requeue
+SHOWQ
+SIGHUP
+SIGTERM
+TARPIT
+TX
+URLs
+Vxy
+alnum
+andrewm
+awk
+bH
+bh
+blackhole
+bm
+bs
+cert
+checkpointed
+cid
+cv
+debuglevel
+dhmlnv
+dsn
+eb
+eef
+ef
+endif
+eoctal
+eol
+ev
+exe
+exploders
+fq
+groupname
+headervalue
+hp
+hqu
+hu
+ident
+idx
+iframe
+inode
+inputfile
+kadlec
+kfki
+lamont
+ldapi
+ldaps
+ldapsearch
+ldapsource
+localname
+mailHost
+mapname
+maptype
+metacharacter
+metacharacters
+mysqlname
+netstring
+oA
+oAalias
+oi
+pgsqlname
+postfixpw
+psv
+pw
+qR
+qRsite
+qSsite
+qinterval
+queueid
+regcomp
+regex
+requeue
+requeued
+requeues
+rv
+searchdomains
+sitename
+src
+sytem
+textfile
+tr
+unzip
+usernames
+vbs
+vq
+CERT
+NOQUEUE
+NS
+Qmail
+Tarpit
+Verisign
+Verisign's
+dd
+itd
+AU
+CAcert
+CAfile
+CApath
+CAs
+CNAME
+CommonName
+Cottbus
+DH
+DSA
+EE
+EGD
+GMT
+IA
+Lutz
+Lutz's
+NOPEERMATCH
+Nov
+OPENSSL
+PRNG
+PosgreSQL
+RSA
+SubjectAlternativeName
+Uing
+Widgits
+Wietse's
+aet
+cacert
+ccert
+certs
+cipherlist
+clientcerts
+cnf
+commonName
+compat
+cottbus
+countryName
+cp
+dNSNames
+dcert
+demoCA
+dh
+dkey
+dsa
+eg
+egd
+emailAddress
+exch
+fifos
+gendh
+infiles
+kbytes
+keyout
+lcrypto
+libcrypto
+libssl
+localityName
+loglevel
+lssl
+lutzpc
+misc
+newca
+nicke
+ok
+openssl
+organizationName
+peername
+pem
+prng
+req
+scache
+scert
+sdbm
+smtps
+ssl
+sslclient
+sslserver
+starttls
+stateOrProvinceName
+tlsmgr
+unencrypted
+unpassworded
+urandom
+verifydepth
+wrappermode
+AAAA
+DNSBL
+GETIFADDRS
+Hagino
+Huizer
+Jaenicke's
+Lutz
+PLD
+SIOCGIF
+SIOCGLIF
+Strik
+Strik's
+Tru
+USAGI
+compat
+ff
+ffff
+getifaddrs
+ichiro
+ifndef
+ipnet
+ipv
+itojun
+netmasks
+kluges
+APPENDDEF
+EOH
+EOM
+MSGIDUNKNOWN
+Milters
+SMFIS
+SenderID
+authen
+confINCDIRS
+confLIBDIRS
+ctx
+dnl
+eoh
+eom
+getpriv
+getsymval
+gzcat
+jobid
+libmilter
+ments
+milters
+mlfi
+msgid
+optionneg
+portnumber
+ptr
+sid
+smfi
+smfilter
+strcmp
+tempfail
+vx
+wich
+xf
+xxxxx
+yy
+zz
+AAAREADME
+API
+DAEMONs
+DHE
+DSL
+DataBase
+EMSTP
+EST
+HTTPS
+JOBIDUNKNOWN
+Jänicke
+Koetter
+Leandro
+MSA
+MUAs
+Netinfo
+ODRhu
+Outlook's
+PQexec
+Procontrol
+REJECTs
+Requeuing
+SDBM
+SSLv
+Santi
+Sirainen
+TCL
+TEMPFAILs
+TLSv
+Tallon
+Tinycdb
+Tokarev
+Wrobel
+aNULL
+agroup
+alloc
+antiantivirus
+apps
+arandom
+arounds
+auser
+beb
+bgroup
+buser
+callouts
+cctx
+cli
+cname
+corpit
+cuser
+ddd
+dfc
+dkim
+dmS
+domainkeys
+duser
+epoll
+esmtp
+exim
+gssapi
+heraccount
+herisp
+hisaccount
+hisisp
+ietf
+imc
+interoperate
+keysize
+koetter
+kqueue
+ldapgroup
+libcdb
+libdb
+lpr
+mailwrapper
+mctx
+memberaddr
+memberdn
+mjt
+mlm
+msa
+myisp
+myname
+netinfo
+nisplus
+noatime
+nopeer
+obs
+openspf
+orig
+passdb
+patrick
+preloading
+rpm
+saslfinger
+securetls
+spamware
+systemtype
+tinycdb
+unencoded
+uniquename
+william
+xxxxxxx
+yulszqocfzsficvzzju
+yyyyyy
+zzzzzz
+BC
+DKIM
+DomainKeys
+Hmm
+Jnicke
+QAdGVzdHBhc
+RBL's
+RBLs
+RST
+SMTPS
+Spamhaus
+Ss
+Ubuntu
+blocklists
+botnet
+botnets
+bx
+cb
+co
+dest
+foreach
+int
+jp
+le
+mind's
+nqmgr's
+overinflating
+portscan
+preemptions
+ps
+qf
+refcount
+ru
+spamhaus
+stddev
+sysadmins
+timeline
+todo
+tt
+unsubscribe
+wl
+zen
+Blocklist
+DNSBLs
+MailChannels
+Postscreen
+Spambots
+WHITELISTED
+blocklist
+dnsbl
+dnsblog
+postscreen
+postscreen's
+spambots
+spamd
+texthash
+ul
+whitelisted
+whitelists
+Amavisd
+MUA
+Mailserver
+SpamAssassin
+barracudacentral
+bl
+spamcop
+tlsproxy
+AEIOUaeiou
+AF
+ASN
+BB
+CB
+CBC
+CRYPTOPRO
+CTX
+CVE
+DER
+DES
+DNSSEC
+Diffie
+EC
+ECDH
+ECDSA
+EDNS
+EECDH
+FB
+GOST
+Hellman
+LMDB
+MSIE
+Mmm
+NODATA
+NXDOMAIN
+Nexthop
+OP
+OTIFY
+OpenSSL's
+Postix
+Pt
+SECG
+SSLEAY
+SSLREF
+SSLV
+TLSEXT
+VXxznjll
+Whitelist
+XYZ
+YYYYMMDDHHMMSS
+aRSA
+authcid
+authcid's
+authentiCation
+authoriZation
+authzid
+bc
+blockquote
+certfile
+cfm
+cipherlists
+ciphertext
+crypto
+dane
+defnames
+dgst
+dl
+dnsrch
+dnssec
+dnswl
+dotcrlf
+dt
+eNULL
+eccert
+ecdsa
+eckey
+ecparam
+eecdh
+fc
+fixup
+getaddrinfo
+haproxy
+headerbody
+hh
+hyperlinked
+ia
+kEDH
+lmdb
+localtime
+mN
+matchlists
+md
+mechs
+memcache
+mylmtp
+nginx
+noout
+nsa
+pkey
+postlink
+postmulti
+proxywrite
+pubin
+pubkey
+queueID
+rsa
+secp
+stdin
+tarpit
+uncached
+unzipping
+windowsize
+xpostconf
+TLSA
+tafile
+VPN
+Dukhovni
+Exim
+NIST
+PFS
+Snowden
+Viktor
+XP
+cron
+dhparam
+inadvisably
+ADH
+AECDH
+CN
+DSS
+ECDHE
+GCM
+Jnicke's
+Kx
+PKI
+XXX
+YYY
+ZZZ
+kEECDH
+EXIM
+DLV
+IANA
+RRs
+RRset
+RRsets
+SNI
+tlsa
+TSIG
+ciphersuite
+ciphersuites
+nlnetlabs
+resolver's
+tempfails
+Chu
+LMDB's
+NDBM
+dict
+kbyte
+llmdb
+lockfiles
+slmdb
+DEVPOLL
+DNO
+EPOLL
+GETPW
+KQUEUE
+MacOS
+NISPLUS
+SHLIB
+SIGSETJMP
+SQLITE
+SQLite
+deinstalling
+dynamicmaps
+gcc
+getpwnam
+getpwuid
+ldconfig
+libpostfix
+longjmp
+nonprod
+setjmp
+shlib
+siglongjmp
+sigsetjmp
+sqlite
+unversioned
+versioned
+DNSWL
+cbc
+ADDRCPT
+Ae
+AES
+Arnt
+ASLR
+authz
+authzTo
+autodetect
+autodetection
+backend
+backends
+backscatter
+BACKSCATTER
+balancer
+byname
+cakey
+casefold
+casefolding
+caseless
+Centos
+CFLAGS
+changetype
+characterset
+CHGFROM
+cmusaslsecretMECHNAME
+CNNIC
+concurrencies
+cryptanalytic
+cryptographic
+cryptographically
+customizations
+cyrus
+DB's
+de
+decrypts
+deinstall
+dev
+DMARC
+EAI
+EDH
+encodings
+ENHANCEDSTATUSCODES
+environ
+esac
+etcetera
+exchanger
+executables
+Executables
+filename
+filenames
+fPIC
+fred
+genrsa
+GSSAPI
+Gulbrandsen
+Gulbrandsen's
+helpdesk
+icu
+icuuc
+imap
+infeasible
+interoperability
+interoperable
+invasiveness
+jetmore
+Jetmore
+KERBEROS
+kern
+launchd
+ldapadd
+ldapdb
+ldapmodify
+libc
+libicu
+liblogin
+libplain
+libsasl
+libsasl's
+login
+Login
+LOGIN
+logins
+lookup
+Lookup
+lookups
+Makefile
+makefiles
+Makefiles
+mary
+matcher
+maxprocperuid
+mdash
+MECHNAME
+Memcache
+Mf
+milter
+Milter
+misconfigured
+multi
+mux
+namen
+nameserver
+nameserver's
+ndash
+ne
+newkey
+nicke's
+NOOP
+nroff
+ntlm
+NTLM
+Ok
+opendkim
+OpenDKIM
+OpenDMARC
+optimizations
+ou
+outform
+pam
+param
+pathname
+pathnames
+performant
+pipelined
+pipelining
+PIPELINING
+pipemap
+Plaintext
+postfix
+Postfix
+POSTSCREEN
+Pre
+prepend
+PREPEND
+PROTO
+proxyuser
+randmap
+rc
+REJ
+REPLBODY
+resultn
+Rhein
+RHEL
+rimap
+rpath
+RPATH
+runpath
+runtime
+SASLv
+scalable
+scanf
+sha
+SHA
+SMFIC
+SMFIP
+SMFIR
+SMTP
+smtputf
+SMTPUTF
+socketdir
+socketmap
+startup
+subdirectory
+subnet
+subnetworks
+substring
+sys
+SYS
+sysconfig
+TCP
+testsaslauthd
+Timo
+tradeoff
+typechecks
+typen
+ulimit
+undeliverable
+Unencrypted
+unionmap
+uniqueIdentifier
+unpatched
+untrusted
+Untrusted
+unvailable
+uri
+userPassword
+UTF
+uucp
+UUCP
+wakeup
+Westchester
+whitespace
+Wl
+xFFFFFFFF
+xn
+xyy
+xzz
+ymd
+INLINE
+SNPRINTF
+inline
+mtime
+snprintf
+sprintf
+allowlist
+allowlisted
+denylist
+denylisted
+ALLOWLIST
+ALLOWLISTED
+DENYLIST
+DENYLISTED
+epilog
+prolog
+proto
+ICMP
+NORANDOMIZE
+wallclock
+BDAT
+IPL
+yyyy
+yyyymmdd
+Incompat
+Junod
+gid
+json
+postlogd
+proxied
+raf
diff --git a/proto/stop.double-cc b/proto/stop.double-cc
new file mode 100644
index 0000000..1e9b3de
--- /dev/null
+++ b/proto/stop.double-cc
@@ -0,0 +1,330 @@
+void void rewrite_proto stream
+ Strip trailing dot at end of domain but not dot dot or dot This
+ strip source routed addresses site site user domain
+transport_lookup transport_lookup finds the channel and nexthop for the given
+ Typically the nexthop specifies a hostname hostname TCP Port or the
+resolve_addr resolve_addr resolve address according to rule set
+ technically incorrect this is needed to stop user domain domain relay
+ needs white space but stuff stuff does not This is not a
+ where stuff stuff does not happen
+ Strip trailing dot at end of domain but not dot dot or at dot
+XXX XXX Short cut invalid address forms
+ Connect via TCP to domain domain port port The default
+ Connect via TCP to domain domain port port The default
+files files that are owned by the wrong user or files that have world write
+ name is is not defined
+ conditionally to value when name is is not
+MUMBLE_TODO MUMBLE_TODO flags must not be cleared once raised The _TODO_TO_PASS and
+psc_todo_tests psc_todo_tests overwrites all per session flag bits and
+ Either hand off the socket to a real SMTP engine or say bye bye
+char char context
+inet_pton inet_pton
+void void psc_early_tests state
+void void psc_smtpd_init void
+void void psc_smtpd_tests state
+ IP postscreen_dnsbl_max_ttl postscreen_dnsbl_ttl postscreen_dnsbl_ttl 1 h
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ The event driven TLS I O implementation is founded on on line OpenSSL
+unused unused
+ IP f command command
+ IP q command command
+ IP Q command command
+ IP r command command
+ IP s command command
+ TCP port port Both host and port may be
+void void
+ reset_cmd_flags reset per command command flags
+ set_cmd_flags set per command command flags
+ Connect via TCP to host host port port The default
+ Connect via TCP to host host port port The default
+argv argv command
+time time of entry into active queue
+peer peer entries
+FD_SETSIZE FD_SETSIZE
+FD_SETSIZE FD_SETSIZE
+FD_SETSIZE FD_SETSIZE
+ var spool postfix incoming incoming queue
+ var spool postfix active active queue
+ var spool postfix deferred deferred queue
+time time of entry into active queue
+FD_SETSIZE FD_SETSIZE
+FD_SETSIZE FD_SETSIZE
+FD_SETSIZE FD_SETSIZE
+ var spool postfix incoming incoming queue
+ var spool postfix active active queue
+ var spool postfix deferred deferred queue
+XXX XXX
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+NOTREACHED NOTREACHED
+ If not connected to stdin stdin must not be a terminal
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ If not connected to stdin stdin must not be a terminal
+select select
+ If not connected to stdin stdin must not be a terminal
+ main main program
+this this first
+linkage linkage
+ Postfix master master cf file processing
+select select
+ If not connected to stdin stdin must not be a terminal
+ response to stress level changes Doing so would would contaminate
+ IP CA_MAIL_SERVER_EXIT void void
+ If not connected to stdin stdin must not be a terminal
+smtp_site_fail smtp_site_fail handles the case where the program fails to
+ We can t avoid copying copying lots of strings into VSTRING buffers
+binding binding properties passivated
+endpoint endpoint properties passivated
+safety safety
+XXX XXX
+ See src tls tls_level c and src tls tls h Levels above encrypt require
+smtp_rcpt_done smtp_rcpt_done
+smtp_rcpt_done smtp_rcpt_done
+smtp_rcpt_done smtp_rcpt_done
+ Ignore out of protocol enhanced status codes codes that accompany 3XX
+ IP name name
+void void
+FALLTHROUGH FALLTHROUGH
+HAS_PCRE HAS_PCRE
+HAS_PCRE HAS_PCRE
+ any any
+ typedef DICT DICT_OPEN_FN const char int int
+EDIT_FILE EDIT_FILE edit_file_open original_path output_flags output_mode
+void void
+nvtable_locate nvtable_locate returns a pointer to the entry that was stored
+legacy legacy
+ for symlinks owned by root NEVER NEVER make exceptions for symlinks
+ sanitize sanitize db_get put del result
+ simple attr attr name colon attr value newline
+void void htable_free table free_fn
+void void htable_walk table action ptr
+htable_locate htable_locate returns a pointer to the entry that was stored
+ IP CA_VSTREAM_POPEN_WAITPID_FN pid_t pid_t WAIT_STATUS_T int
+optimization optimization
+msg_fatal msg_fatal reports an unrecoverable error and terminates the program
+ compare compare the address family and network address or
+ numbers or number number ranges
+ v4pattern v4field v4field v4field v4field
+ v4pattern v4field v4field v4field v4field
+ v4pattern v4field v4field v4field v4field
+ v4seq_member v4octet v4octet v4octet
+ v4seq_member v4octet v4octet v4octet
+Corruption Corruption
+ main main program
+privileges privileges
+DICT_THASH_OPEN_RETURN DICT_THASH_OPEN_RETURN
+ Fatal errors cannot open file file write error out of memory
+found found
+found found
+XXX XXX maybe earlier
+XXX XXX
+ verified RedHat 3 03
+ Bits per byte byte in vector bit offset in byte bytes per set
+ echo echo text received on stdin
+ request request a bunch of timer events
+ Fatal errors cannot open file file write error out of memory
+found found
+found found
+ concatenate concatenate null terminated list of strings
+void void context
+void void binhash_free table free_fn
+void void binhash_walk table action ptr
+binhash_locate binhash_locate returns a pointer to the entry that was stored
+width width precision separator
+ and whitespace characters must be replaced by XX XX being the
+ and whitespace characters and the by XX XX being the two digit
+ Fatal errors cannot open file file write error out of
+privileges privileges
+ Example 00000000000000000000000000000001 01 80 10 80 lo
+ text text
+void void
+matched matched text
+SUNOS5 SUNOS5
+ casefold casefold text for caseless comparison
+ simple name string string simple name
+ attribute list attribute attribute attribute list
+ attribute list attribute attribute attribute list
+ attribute string string
+string string ISO Latin 1 character set except the character
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+ Example checking infrastructure for int int const int
+ Example variables with type int int const int
+int int int_val
+ host port host host
+host host port host host
+ host port host host
+ port port
+ host port host host
+ host port host host port port
+ host port host host port port
+ simple attr attr name null attr value null
+ IP CA_SLMDB_CTL_LONGJMP_FN void void int
+ IP CA_SLMDB_CTL_NOTIFY_FN void void int
+ IP CA_SLMDB_CTL_ASSERT_FN void void const char
+ DICT dict_static_open name name dict_flags
+buffer buffer length
+privileges privileges
+key key length
+ simple attr attr name attr value newline
+ attr name any string without null or or newline
+ var spool postfix maildrop maildrop queue
+ WARNING WARNING WARNING
+ WARNING WARNING WARNING
+lmdb lmdb supports concurrent writes and reads from different
+private private
+private private
+ var spool postfix private private class endpoints
+ var spool postfix public public class endpoints
+messages messages put on hold
+option option disables UTF 8 syntax checks on query keys and
+option option disables UTF 8 syntax checks on query keys and
+lmdb lmdb supports concurrent writes and reads from different
+peer peer
+void void
+XXX XXX
+ relay loopholes with user domain domain when relaying mail to a
+ Strip one trailing dot but not dot dot
+void void
+headers headers after multipart boundary
+ by XX XX being the two digit uppercase hexadecimal equivalent
+must must
+request request completed unsuccessfully
+DSN_BUF DSN_BUF dsb_create void
+DSN_SPLIT DSN_SPLIT dsn_split dp def_dsn text
+ that registers operators such as level level that compare
+ var_maillog_file var_maillog_file import_service_path 0
+ IP address address family information and the numerical TCP port
+privileges privileges
+void void rcpb_reset rcpb
+ The entire lookup key key
+DSN DSN dsn_create status action reason dtype dtext mtype mname
+ When specified with a flush request request that
+storage storage
+message message size
+ starts with or or the prefix which will be used
+ with or or the prefix which will be used to obtain
+strings strings with digits uppercase letters and lowercase
+safe_strtoul safe_strtoul implements similar functionality as strtoul
+ typedef LOGIN_SENDER_MATCH LOGIN_SENDER_MATCH
+LOGIN_SENDER_MATCH LOGIN_SENDER_MATCH login_sender_create
+void void anvil_clnt_free anvil_clnt
+privileges privileges
+ characters specified with special with x XX XX being
+0000 0000 0000 007 F 0x xxxxxx
+0000 0000 0000 007 F 0x xxxxxx
+ https github com aox aox blob master encodings utf cpp with
+FALLTHROUGH FALLTHROUGH
+ Detail format is digit digit 1 3 digit 1 3
+encoding encoding domain
+domain domain
+domain domain
+encoding encoding
+XXX XXX EAI inspect encoded message global
+domain domain
+MBOX MBOX mbox_open path flags mode st user group lock_style
+ incomplete address address rewriting alias expansion automatic BCC
+unquoted unquoted form then quoted
+ records data offset offset of the first REC_TYPE_NORM or REC_TYPE_CONT
+DELIVER_REQUEST DELIVER_REQUEST deliver_request_read stream
+MAIL_VERSION MAIL_VERSION mail_version_parse version_string why
+dict_xx_open dict_xx_open result
+ When specified with a flush request request that
+MAIL_STREAM MAIL_STREAM mail_stream_file queue class service mode
+ starts with or or the prefix which will be used to
+hosts hosts on which databases reside
+ or maptype mapname search name name The search
+ with or or the prefix which will be used to obtain
+the the message delivery record
+MKMAP MKMAP mkmap_open type path open_flags dict_flags
+BOUNCE_LOG BOUNCE_LOG bounce_log_open queue id flags mode
+ internal external external first
+context context for queue file changes
+sender sender transport
+SMFIM_EOH SMFIM_EOH SMFIM_EOM
+value value to string
+RE RE
+PCF_MASTER_ENT PCF_MASTER_ENT local_scope
+to to instantiate legacy per dbms parameters and to examine
+ tls_digest_encode encode message digest binary blob as xx xx
+logged logged
+logged logged
+ DNS at the dane dane only and half dane security levels or be
+void void tls_pre_jail_init TLS_ROLE
+TLS_ROLE TLS_ROLE role
+and and the protocol version floor ceiling given a list plist of
+ of the form name name hexvalue hexvalue If plist
+ of the form name name hexvalue hexvalue If plist
+XXX XXX We re ignoring the function name do we want to log it
+ If the match is required unambiguous insist that that no other values
+ etc postfix canonical canonical mapping table
+ etc postfix virtual virtual mapping table
+void void
+regions regions with body content
+SASLv2 SASLv2 s sasl_server_new takes two new parameters to specify local and
+SASLv2 SASLv2 s sasl_client_new takes two new parameters to specify local and
+ All 5xx replies must have a 5 xx xx detail code
+ Truncate hostnames ending in dot but not dot dot
+ Truncate hostnames ending in dot but not dot dot
+ Truncate hostnames ending in dot but not dot dot
+ Truncate names ending in dot but not dot dot
+200412 200412
+ Reject mail to unknown addresses in local domains domains that
+client client name
+stuff stuff
+counter counter
+Milter Milter initialization status
+USE_TLSPROXY USE_TLSPROXY
+address address family
+void void
+probed probed if non zero the time the currently outstanding address probe was
+ recipient lists and some MUAs even specify word word address
+VERP VERP
+NOTREACHED NOTREACHED
+NOTREACHED NOTREACHED
+NOTREACHED NOTREACHED
+NOTREACHED NOTREACHED
+NOTREACHED NOTREACHED
+NOTREACHED NOTREACHED
+NOTREACHED NOTREACHED
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+key key
+ Fatal error error opening existing file
+void void bounce_cleanup_unregister void
+ Fatal error error opening existing file
+BOUNCE_TEMPLATES BOUNCE_TEMPLATES bounce_templates_create void
+void void bounce_templates_free templates
+ Fatal error error opening existing file
+ also showq showq c
+name name length
+BOUNCE_INFO BOUNCE_INFO bounce_mail_init service queue_name queue_id encoding
+ Fatal error error opening existing file
+more more useful and more consistent
+ Fatal error error opening existing file
+ Fatal error error opening existing file
+XXX XXX
+ int compar DNS_RR DNS_RR
+USE_FNV_32BIT USE_FNV_32BIT
diff --git a/proto/stop.double-install-proto-text b/proto/stop.double-install-proto-text
new file mode 100644
index 0000000..338286e
--- /dev/null
+++ b/proto/stop.double-install-proto-text
@@ -0,0 +1,41 @@
+bind bind no
+bind bind sasl
+bind bind yes
+ command_directory command_directory
+ Content Disposition Type name es es e 2E
+ daemon_directory daemon_directory
+ data_directory data_directory
+done done
+ echo 0 Error unknown type type for path in meta postfix files 1 2
+ echo echo 0 Error name should be an absolute path name 1 2
+esac esac
+ eval echo n name name c
+ eval group group
+ eval owner owner
+example example com uucp example
+file contains only a small subset of all parameters parameters
+group group
+ html_directory html_directory
+ IP domain address address
+ IP pattern address address
+ IP user address address
+ IP user domain address address
+ mail_owner mail_owner
+ mailq_path mailq_path
+ manpage_directory manpage_directory
+ meta_directory meta_directory
+ newaliases_path newaliases_path
+ nisplus name s name name name column
+ postmap q nisplus name s name name inputfile
+ postmap q string nisplus name s name name
+postmaster postmaster root
+ queue_directory queue_directory
+ readme_directory readme_directory
+root root you
+ sample_directory sample_directory
+ sendmail_path sendmail_path
+ server_host ldap ldap example com 1444
+ setgid_group setgid_group
+ shlib_directory shlib_directory
+ user foo domain user domain domain
+virtual virtual alias domain anything right hand content does not matter
diff --git a/proto/stop.double-proto-html b/proto/stop.double-proto-html
new file mode 100644
index 0000000..a7e7824
--- /dev/null
+++ b/proto/stop.double-proto-html
@@ -0,0 +1,247 @@
+ 1 000 000 messages with good performance unlikely above that limit
+ 10 10 Mandatory configuration file edits
+ 11 11 To chroot or not to chroot
+ 12 12 Care and feeding of the Postfix system
+14 rbl_domain rbl_reason rbl_reason
+168 100 189 2 255 255 255 224
+18 rbl_domain rbl_reason rbl_reason
+ 1 ffff ffff ffff ffff ffff ffff ffff ffff
+2001 240 587 0 2d0 b7ff fe88 2ca7 ffff ffff ffff ffff
+ 31 sasldb Accounts are stored stored in a Cyrus SASL Berkeley DB
+ 33 ldapdb Accounts are stored stored in an LDAP database
+ 4 yes yes yes never 100
+5 postmaster postmaster example com
+5 root root localhost
+6 abuse abuse example com
+80821 S 0 00 24 smtpd n smtp t inet u c o stress yes
+83326 S 0 00 28 smtpd n smtp t inet u c o stress
+84345 Ss 0 00 11 usr bin perl usr libexec postfix smtpd policy pl
+ 8 SENDMAIL usr sbin sendmail G i NEVER NEVER NEVER use t here
+address localpart as per RFC 822 so that additional or or
+all all Maximum per destination delivery concurrency
+and cost cost 1 times more than if the preemptive scheduler was
+ and sneak in the ten recipient mail Wait wait wait Could we Aren t
+ aNULL aNULL kEECDH kEDH RC4 eNULL EXPORT LOW STRENGTH
+Arrival Date Sun 26 Nov 2006 17 01 01 0500 EST
+attacks with user domain domain addresses when Postfix provides
+authzTo authzTo dn regex uniqueIdentifier ou people dc example dc com
+ AUXLIBS AUXLIBS options for LDAP or TLS etc
+blockquote blockquote
+ broken smtp smtp o smtp_quote_rfc821_envelope no
+ccert_fingerprint C2 9D F4 87 71 73 73 D9 18 E7 C2 F3 C1 DA 6E 04
+command_directory command_directory
+ concurrency concurrency limit
+config_directory config_directory
+daemon_directory daemon_directory
+data_directory data_directory
+Date Sun 26 Nov 2006 17 01 01 0500 EST
+dd dd Alternatively check_ccert_access accepts an explicit search
+dd dd check_ccert_access type table search_order cert_fingerprint
+dd dd The commas are optional dd
+dd dd The default algorithm is b sha256 b with Postfix ge 3 6
+ dd No TLS TLS will not be used unless enabled for specific
+Dec 4 04 30 09 hostname postfix smtpd 58549 NOQUEUE reject
+ default_transport uucp uucp gateway
+ different client IP addresses Lookup results override the the global
+Documentation Documentation is available as README files start with the file
+done done
+done done
+ dt b a name check_address_map check_address_map a i a href DATABASE_RE
+ dt b a name check_ccert_access check_ccert_access a i a href DATABASE_
+ dt b a name check_client_a_access check_client_a_access a i a href DAT
+ dt b a name check_client_access check_client_access a i a href DATABAS
+ dt b a name check_client_mx_access check_client_mx_access a i a href D
+ dt b a name check_client_ns_access check_client_ns_access a i a href D
+ dt b a name check_etrn_access check_etrn_access a i a href DATABASE_RE
+ dt b a name check_helo_a_access check_helo_a_access a i a href DATABAS
+ dt b a name check_helo_access check_helo_access a i a href DATABASE_RE
+ dt b a name check_helo_mx_access check_helo_mx_access a i a href DATAB
+ dt b a name check_helo_ns_access check_helo_ns_access a i a href DATAB
+ dt b a name check_policy_service check_policy_service i servername i a
+ dt b a name check_recipient_a_access check_recipient_a_access a i a hre
+ dt b a name check_recipient_access check_recipient_access a i a href D
+ dt b a name check_recipient_mx_access check_recipient_mx_access a i a h
+ dt b a name check_recipient_ns_access check_recipient_ns_access a i a h
+ dt b a name check_sasl_access check_sasl_access a i a href DATABASE_RE
+ dt b a name check_sender_a_access check_sender_a_access a i a href DAT
+ dt b a name check_sender_access check_sender_access a i a href DATABAS
+ dt b a name check_sender_mx_access check_sender_mx_access a i a href D
+ dt b a name check_sender_ns_access check_sender_ns_access a i a href D
+ dt b a name defer defer a b dt
+ dt b a name defer_if_permit defer_if_permit a b dt
+ dt b a name defer_if_reject defer_if_reject a b dt
+ dt b a name defer_unauth_destination defer_unauth_destination a b dt
+ dt b a name no_address_mappings no_address_mappings a b dt
+ dt b a name no_header_body_checks no_header_body_checks a b dt
+ dt b a name no_milters no_milters a b dt
+ dt b a name no_unknown_recipient_checks no_unknown_recipient_checks a b
+ dt b a name permit_auth_destination permit_auth_destination a b dt
+ dt b a name permit_dnswl_client permit_dnswl_client i dnswl_domain d d d d
+ dt b a name permit_inet_interfaces permit_inet_interfaces a b dt
+ dt b a name permit_mx_backup permit_mx_backup a b dt
+ dt b a name permit_mynetworks permit_mynetworks a b dt
+ dt b a name permit permit a b dt
+ dt b a name permit_rhswl_client permit_rhswl_client i rhswl_domain d d d d
+ dt b a name permit_sasl_authenticated permit_sasl_authenticated a b dt
+ dt b a name permit_tls_all_clientcerts permit_tls_all_clientcerts a b
+ dt b a name permit_tls_clientcerts permit_tls_clientcerts a b dt
+ dt b a name reject_invalid_helo_hostname reject_invalid_helo_hostname a
+ dt b a name reject_multi_recipient_bounce reject_multi_recipient_bounce a
+ dt b a name reject_non_fqdn_helo_hostname reject_non_fqdn_helo_hostname a
+ dt b a name reject_non_fqdn_recipient reject_non_fqdn_recipient a b dt
+ dt b a name reject_non_fqdn_sender reject_non_fqdn_sender a b dt
+ dt b a name reject_plaintext_session reject_plaintext_session a b dt
+ dt b a name reject_rbl_client reject_rbl_client i rbl_domain d d d d i
+ dt b a name reject reject a b dt
+ dt b a name reject_rhsbl_client reject_rhsbl_client i rbl_domain d d d d
+ dt b a name reject_rhsbl_helo reject_rhsbl_helo i rbl_domain d d d d i
+ dt b a name reject_rhsbl_recipient reject_rhsbl_recipient i rbl_domain d d
+ dt b a name reject_rhsbl_reverse_client reject_rhsbl_reverse_client i rbl_
+ dt b a name reject_rhsbl_sender reject_rhsbl_sender i rbl_domain d d d d
+ dt b a name reject_sender_login_mismatch reject_sender_login_mismatch a
+ dt b a name reject_unauth_destination reject_unauth_destination a b dt
+ dt b a name reject_unauth_pipelining reject_unauth_pipelining a b dt
+ dt b a name reject_unknown_client_hostname reject_unknown_client_hostname
+ dt b a name reject_unknown_helo_hostname reject_unknown_helo_hostname a
+ dt b a name reject_unknown_recipient_domain reject_unknown_recipient_domain
+ dt b a name reject_unknown_sender_domain reject_unknown_sender_domain a
+ dt b a name reject_unlisted_recipient reject_unlisted_recipient a b wi
+ dt b a name reject_unlisted_sender reject_unlisted_sender a b dt
+ dt b a name reject_unverified_recipient reject_unverified_recipient a b
+ dt b a name reject_unverified_sender reject_unverified_sender a b dt
+ dt b a name sleep sleep i seconds i a b dt
+ dt b a name warn_if_reject warn_if_reject a b dt
+dt dt b i a href DATABASE_README html type table a i b dt
+dt dt b i number i i number i b dt
+ dt dt dd 0 Disable logging of TLS activity dd
+ dt dt dd 1 Log only a summary message on TLS handshake completion
+ dt dt dd 2 Also log levels during TLS negotiation dd
+ dt dt dd 3 Also log hexadecimal and ASCII dump of TLS negotiation
+ dt dt dd 4 Also log hexadecimal and ASCII dump of complete
+ dude dude example com
+ eliminates the latency of the TCP handshake SYN SYN ACK ACK
+ example com uucp uucp host
+ example MAIL RCPT BDAT BDAT MAIL RCPT BDAT without ever having to
+ export MANPATH MANPATH pwd man MANPATH
+fe80 1 2d0 b7ff fe88 2ca7 ffff ffff ffff ffff
+fe80 5 1 ffff ffff ffff ffff
+file allows for robust handling of temporary delivery errors errors
+Filtered Filtered
+for the file name when a pattern is a type table table specification
+from host example com 192 168 0 2 TLSv1 with cipher cipher name
+generic generic a restrictions These restrictions are applicable in
+ groups msn com 63 2 1 2 4 4 14 14 14 8 0
+ highvolume com 4000 160 160 320 640 1280 1440 0 0 0 0
+host host port host port address or address port the form
+ http www umich edu dirsvcs ldap ldap html or OpenLDAP
+ id 84863BC0E5 Sun 26 Nov 2006 17 01 01 0500 EST
+ if concurrency concurrency limit
+ ifconfig en0 alias address netmask 255 255 255 255
+ inet_addr_local inet_addr_local configured 2 IPv4 addresses
+ inet_addr_local inet_addr_local configured 4 IPv6 addresses
+insiders_only insiders_only check_sender_access hash etc postfix insiders reject
+in the form of a domain name hostname hostname port hostname port
+into memory such as pcre regexp or texthash texthash is similar
+ jane jane janes preferred machine
+ joe joe joes preferred machine
+ Line 8 NEVER NEVER NEVER use the t command line option here It
+listname listname request
+ lists sourceforge net 2313 2313 0 0 0 0 0 0 0 0
+local local 8
+local_only local_only
+maildrop maildrop
+maildrop maildrop owner cn root dc your dc com
+make make makefiles CC opt ansic bin cc Ae HP UX
+make make makefiles CC purify cc
+ man man man5 postconf 5 less
+master_service_disable foo inet inet
+multi_instance_enable multi_instance_enable
+multi_instance_group multi_instance_group
+multi_instance_name multi_instance_name
+mydestination myhostname localhost mydomain mydomain
+ mydomain to an incomplete address address rewriting alias
+mynetworks mynetworks 127 0 0 0 8 168 100 189 0 28 1 128 fe80 10 2001 240 587
+mynetworks mynetworks hash etc postfix network_table
+Name lt user example com gt gt i Postfix will ignore the i User
+ name name port name or name port
+ NOTE Postfix 3 6 also introduces support for the level level
+number number ranges Postfix version 2 8 and later If no
+numbers or number number ranges Postfix version 2 8 and later
+one or more separated numbers or number number ranges
+ openssl req new key key
+or more separated numbers or number number ranges p
+or number number ranges Postfix version 2 8 and later If no
+ ownership of system directories such as etc usr usr bin var
+ PARAM postscreen_dnsbl_max_ttl postscreen_dnsbl_ttl postscreen_dnsbl_ttl
+ patterns list multiple domain names as domain domain
+ p Note 2 address information may be enclosed inside tt tt
+ postfix 12345 12345 postfix no where no shell
+ Postfix 2 3 2 5 to hang up on clients that that match
+ Postfix has TWO sets of mail filters filters that are used for
+Postfix Postfix can use an LDAP directory as a source for any of its lookups
+ Postfix Postfix passes the status back to the remote SMTP
+ Postfix Postfix will send the mail back to the sender address
+pre pre
+query_filter mailacceptinggeneralid s maildrop maildrop
+queue_directory queue_directory
+Received from localhost localhost 127 0 0 1
+Received Received from porcupine org
+rejected rejected recipients are available on request by the Milter
+ rewrite 8 none none
+ Say we have ten recipient mail followed by two two recipient mails If
+ separated numbers or number number ranges If no
+smtpd_recipient_restrictions smtpd_recipient_restrictions
+smtpd_relay_restrictions smtpd_relay_restrictions
+smtpd_relay_restrictions smtpd_relay_restrictions
+ smtpd_tls_mandatory_protocols SSLv2 SSLv3 TLSv1 TLSv1 1
+smtpd_tls_mandatory_protocols SSLv2 SSLv3 TLSv1 TLSv1 1
+ smtp smtp o smtp_bind_address 11 22 33 44
+ smtp smtp o smtp_bind_address6 1 2 3 4 5 6 7 8
+ smtp_tls_mandatory_protocols SSLv2 SSLv3 TLSv1 TLSv1 1
+smtp_tls_mandatory_protocols SSLv2 SSLv3 TLSv1 TLSv1 1
+ SSLv3 TLSv1 TLSv1 1 TLSv1 2 and TLSv1 3 Starting with
+ T 5 10 20 40 80 160 320 640 1280 1280
+ T A 5 10 20 40 80 160 320 320
+ The and match and literally Without the the
+ The matches literally Without the the would
+Therefore 301 0301 0x301 and 0x0301 are all equivalent to
+ The syntax of name value value name value and name value
+the the backed up domain tld domain This prevents your mail queue
+ tls_random_source dev dev urandom
+ tls_random_source dev dev urandom
+tls_random_source dev dev urandom
+TLS TLS support in the LMTP delivery agent
+ TLSv1 3 with cipher TLS_AES_256_GCM_SHA384 256 256 bits
+ to flush flush 8 Deferred
+to host example com 192 168 0 2 25 TLSv1 with cipher cipher name
+ to server example TLSv1 3 with cipher TLS_AES_256_GCM_SHA384 256 256 bits
+ TOTAL 5000 200 200 400 800 1600 1000 200 200 200 200
+transport transport
+ tt tt in the authorized_verp_clients value and in files
+ tt tt in the mynetworks value and in files specified with
+ tt tt in the smtpd_authorized_verp_clients value and in
+ tt tt in the smtpd_authorized_xclient_hosts value and in
+ tt tt in the smtpd_authorized_xforward_hosts value and in
+ tt tt in the smtpd_client_event_limit_exceptions value and
+ tt tt in the smtpd_sasl_exceptions_networks value and in
+ tt tt p
+two two recipient mails
+ uid cn cn auth
+Unfiltered Unfiltered
+ unknown recipients in local domains domains that match mydestination
+ Use blockquote pre pre blockquote for examples
+ Use pre pre for the Examples section at the end
+username username
+ user sourceforge net 7678 7678 0 0 0 0 0 0 0 0
+ using TLSv1 3 with cipher TLS_AES_256_GCM_SHA384 256 256 bits
+ using TLSv1 with cipher cipher name
+var var spool and so on This is especially an issue if you executed
+With the standard operators lt lt etc compatibility
+ yes yes yes never 100
+zombie zombie tlsproxy 8 smtpd 8
+ and 1 000 000 messages with good performance unlikely above that
+dt dt b name value b Postfix ge 3 0 dt
+ dt dt dd 3 Also log the hexadecimal and ASCII dump of the
+ dt dt dd 4 Also log the hexadecimal and ASCII dump of complete
+ parametername stress something something Other
+ p Note on OpenBSD systems specify dev dev arandom when dev dev urandom
diff --git a/proto/stop.spell-cc b/proto/stop.spell-cc
new file mode 100644
index 0000000..9166298
--- /dev/null
+++ b/proto/stop.spell-cc
@@ -0,0 +1,1784 @@
+Aarnio
+abcd
+ABI
+ABNF
+abounce
+accessor
+ack
+acked
+acknowledgement
+acl
+ACL
+adaptor
+ADDCH
+adddr
+addenv
+addn
+Addr
+addrbuf
+ADDRFAMILY
+addrinfo
+ADDRINFO
+addrs
+adefer
+adelay
+adhoc
+adomain
+aes
+af
+AFS
+Aho
+ai
+aierr
+AIX
+al
+alg
+algbits
+algcode
+allalnum
+allascii
+allbits
+alldig
+Allgemeine
+ALLOC
+allocator
+Allowlist
+allowlisting
+ALLPERMS
+ALLPKTS
+allprint
+Allright
+allspace
+alphanum
+alphanumerics
+androsyn
+aox
+ap
+api
+APIs
+appl
+APPL
+ar
+arg
+argc
+Argh
+argi
+argl
+argp
+Args
+ARGS
+ARGV
+argvp
+arpa
+ARPA
+aRv
+ascii
+aslo
+ast
+async
+atol
+atrace
+ATTR
+attrp
+attrs
+atype
+Auch
+auths
+autoclass
+Autodetect
+Autodetection
+automagically
+AUTOUTF
+AUXULIARY
+AWK
+Axel
+Backoff
+BADFLAGS
+BADHINTS
+balpar
+basename
+Basename
+bdat
+BDAT
+bdehnoqv
+BDFORXhqu
+beh
+bfFhimnNoprsuUvw
+BH
+BINARYMIME
+binhash
+BINHASH
+BIOs
+bitclean
+BITCLEAN
+bitmasks
+bitrot
+Bitrot
+bitset
+bitwise
+Bitwise
+blackholes
+blocklisted
+bona
+bool
+BOOL
+booleans
+br
+bsmtp
+BST
+buf
+BUF
+BUFIZ
+buflen
+bufp
+BUFSIZ
+bufsize
+BUFSIZE
+bufstat
+bugtraq
+byuid
+bzero
+cachable
+cacheable
+canonicalization
+canonicalize
+Canonicalize
+canonicalized
+CANONNAME
+CAPTURECOUNT
+carriagecontrol
+carriagereturn
+Carsten
+CASEF
+Casefold
+casefolded
+casefoldx
+casemapped
+cC
+ccerts
+cdbm
+CDBM
+cdbq
+CDE
+certkey
+certmatch
+cfg
+CFG
+chainfiles
+ChangeCipherSpec
+charactersets
+charset
+checkdir
+Chroot
+CHROOT
+chrooting
+Ciphersuite
+cleanenv
+clearerr
+clist
+clnt
+CLNT
+clobbber
+closefrom
+closelog
+CLR
+clumsify
+cmalloc
+cmd
+CMD
+cmdp
+cmds
+cmp
+cmsg
+CMSG
+CNAMEs
+codepoint
+Codepoint
+codepoints
+colocated
+comingle
+compar
+COMPAT
+comsat
+COND
+CONF
+conn
+const
+Const
+conv
+cooldown
+Coverity
+cpio
+cpp
+cptr
+CPTR
+CPUs
+CREAT
+CRLF
+ctable
+CTABLE
+ctext
+ctime
+ctl
+CTL
+ctype
+CUID
+curr
+cvt
+CWD
+cz
+da
+datagram
+datagrams
+datalink
+dbms
+dbopen
+dbpath
+DCL
+dcs
+Dditvw
+dealloc
+deallocate
+deallocates
+deallocating
+deallocation
+debian
+decapsulate
+DECnet
+decrypt
+decryptable
+decrypted
+decrypting
+DEFL
+DEFLT
+deflts
+DEFNAME
+DEFNAMES
+DEFPATH
+defport
+DEFS
+defval
+del
+delim
+delims
+deliverability
+delrcpt
+DELRCPT
+denylisting
+dequote
+dereference
+dereferencing
+deserialization
+Dest
+DEST
+DESTADDR
+DESTPORT
+destructor
+df
+DFFF
+dfhHnopvx
+DFL
+DFXP
+dgram
+DGRAM
+DHparams
+dhs
+Dik
+dirent
+dirname
+dirs
+DISCONN
+DJB
+DJBDNS
+DJB's
+dlen
+dlfunc
+DLL
+DNSBLOG
+DNSBNL
+dNSName
+DNSRCH
+dnsxl
+DNSXL
+dom
+dont
+DONT
+doproto
+DORX
+dotforward
+dp
+Driehuis
+dsb
+DSB
+dsbuf
+DSNs
+dst
+dtext
+DTEXT
+DTXT
+dtype
+DTYPE
+dumpfile
+dup
+DUP
+DUPFD
+dups
+dymap
+EACCES
+EADDRINUSE
+EAGAIN
+EBADF
+ec
+ECONNABORTED
+ECONNREFUSED
+ECONNRESET
+eddd
+EDQUOT
+ee
+EEXIST
+EFBC
+EFBDA
+EFBIG
+egid
+Eindhoven
+EINTR
+EINVAL
+Elektrotechnik
+elif
+else's
+elsize
+empt
+emptive
+Emtpy
+emul
+ENDIF
+ENDIFs
+endp
+endpt
+ENOBUFS
+ENOENT
+ENOMEM
+ENOSPC
+ENOTCONN
+ent
+ENT
+entrancy
+enum
+ENUM
+env
+ENV
+ENVFROM
+envid
+ENVID
+ENVRCPT
+eob
+EOB
+eod
+eof
+EOL
+eother
+EOVERFLOW
+EPERM
+epilog
+EPIPE
+EPROTO
+epv
+eq
+EQ
+ERANGE
+errno
+errstr
+Eschborn
+especials
+ESTALE
+et
+ETIMEDOUT
+eugid
+EUGID
+euid
+EV
+eval
+EVAL
+EVP
+EXCHANGER
+exchangers
+execvp
+expar
+EXPN
+expr
+EXPR
+extern
+extpar
+EXTPAR
+FALLTHROUGH
+FALLTRHOUGH
+fam
+Fawcett
+fbck
+fchmod
+fclose
+FCNTL
+fdclose
+FDD
+FDEF
+fdopen
+fds
+fdtable
+feof
+ferror
+FFDHE
+FFF
+FFFE
+FFFF
+fflush
+fg
+fgetc
+fgets
+fh
+fhHovx
+fi
+fide
+fifo
+FIFOs
+filedes
+fileno
+filesystem
+filesystems
+filt
+FILT
+findenv
+fixme
+Fixme
+FLD
+fmt
+fn
+FN
+FoldCase
+fopen
+forcetlsa
+FOREACH
+formatter
+formfeed
+Forststrasse
+fovx
+fp
+fprint
+fprintf
+fpt
+fpurge
+fputc
+fputs
+fread
+freeaddrinfo
+fron
+fscanf
+fsck
+fseek
+fset
+fsops
+fsspace
+fsstone
+fstat
+fsync
+ftell
+ftime
+ftimeout
+ftimeval
+ftruncate
+fu
+fullname
+fullwidth
+func
+FUNC
+futimes
+fwi
+fwrite
+gai
+GECOS
+Geoff
+GETC
+GETCHAR
+getegid
+getenv
+geteuid
+getgrnam
+gethostbyaddr
+GETHOSTBYNAME
+getnameinfo
+GETNAMEINFO
+getopt
+GETOPT
+getpid
+getpw
+getsockopt
+gettimeofday
+getuid
+ghostgun
+giasbm
+gid
+GID
+ging
+github
+GLIBC
+glibc's
+globals
+gmtoff
+gn
+Goedel's
+goto
+GOTO
+gotsigchld
+gotsighup
+grey
+groupid
+grr
+Grr
+halfdane
+halfwidth
+handoff
+HaProxy
+hardlink
+hardlinks
+hbc
+HBC
+hc
+hdr
+HDR
+hdrs
+HDRS
+hdrval
+HelloRetryRequest
+helohost
+herror
+hexdump
+hexvalue
+hfrom
+HFROM
+HGMP
+Hinxton
+HMAC
+honoured
+hostaddr
+HOSTADDR
+hostmumble
+Hostname
+HOSTNAME
+hostport
+hostrr
+hport
+HPUX
+HRR
+htable
+HTABLE
+htonl
+htons
+https
+HUP
+ial
+icgroup
+ICT
+IDENT
+ideographic
+idna
+IDNA
+ifdefs
+IFF
+ifinet
+IFINET
+IFMT
+ifself
+IGN
+illumos
+IMPL
+INADDR
+incr
+INCR
+indexable
+Indexable
+indirections
+ing
+INIT
+initializations
+initializer
+inj
+Inlined
+inlining
+instantiation
+interruptible
+intra
+INTV
+intval
+inum
+INVAL
+ioctls
+iostuff
+iov
+iovlen
+ipaddr
+IPD
+ipmatch
+IPPROTO
+isalnum
+ISALNUM
+isascii
+ISASCII
+iscntrl
+isjmp
+ISMARKED
+isprint
+ISSET
+issetuid
+ISSOCK
+ISXXX
+iter
+ITER
+iterator's
+iterators's
+itty
+Jaenicke
+jbuf
+JCL
+jeffm
+JIT
+jmp
+johhny
+jq
+json
+JSON
+KAME
+Karlsruhe
+kB
+Keean
+keepalive
+keepalives
+Kellerspeicherpegelanzeiger
+Kernighan
+keyfile
+keyname
+Kilani
+killme
+Kirch
+koobera
+Kouhei
+Krahmer
+lastl
+latencies
+lateron
+ldapone
+LDH
+len
+LEV
+leven
+lex
+lexicals
+lf
+lflags
+libbind
+LIBC
+libdata
+libfuncs
+libmaster
+libmemcache
+Libmilter
+libname
+libresolv
+libtls
+libunbound
+libutil
+lims
+lineno
+liveness
+lnsl
+LOCALDOMAIN
+LOCALPART
+Logfile
+Logfiles
+logmask
+logopts
+logrotate
+logtag
+logwriter
+LOGWRITER
+LONGJMP
+longjump
+Lookups
+lowfd
+lowfrom
+lposix
+lseek
+lsm
+LSM
+lsocket
+lstat
+Lstat
+ltype
+lvalue
+lvalues
+lx
+LY
+macrps
+MAILLOG
+makedef
+malloc
+mallocs
+mapnames
+MAPNAMES
+mapsize
+maptypes
+masq
+masterp
+matchlist
+Matti
+maxdepth
+maxlen
+MAXLEN
+MaxProtocol
+MAXSEG
+maxsize
+mbox
+MBOX
+mdalg
+mdb
+MDB
+MECH
+Meer
+memcaches
+memcat
+memchr
+memcmp
+memcpy
+memmove
+memopen
+memreopen
+memset
+MERCHANTABILITY
+mesg
+MESG
+midna
+MILTER
+milter's
+MILTERS
+MinProtocol
+minrate
+minssf
+Mis
+misconfiguration
+mkdirs
+mkfifo
+mkmap
+MKMAP
+mmap
+MMNNFFPPS
+mname
+MNAME
+Montegancedo
+MQID
+MRU
+msgs
+msk
+mss
+MSS
+mtp
+MTU
+mtype
+MTYPE
+MUL
+multf
+multibyte
+multiline
+multiserver
+multivalued
+mutexes
+Muuss
+MVCC
+mvect
+MVECT
+mxrr
+MXs
+myaddrinfo
+mydest
+mydomainname
+myflock
+MYFLOCK
+myfree
+mygroup
+mymalloc
+mymemdup
+mypasswd
+mypwcache
+mypwd
+mypwenter
+mypwfree
+mypwnam
+mypwuid
+myrand
+myrealloc
+mysqlsource
+mysrand
+mystrdup
+mystrndup
+mystrtok
+mystrtokdq
+mystrtokq
+na
+Nagle
+Nagle's
+nam
+namaddr
+namadr
+NAMADR
+namechecks
+NAMELEN
+namelength
+nameser
+namespace
+namespaces
+nameval
+NAMEVAL
+namme
+nasties
+natively
+NATs
+nbbio
+NBBIO
+nbool
+NBOOL
+nbytes
+nc
+ncache
+Ncache
+NCACHE
+nd
+ndbm
+ndr
+nelm
+netblock
+netdb
+NetInfo
+Netstring
+NETSTRING
+netstrings
+newcontext
+newd
+newpath
+newqeueid
+newqueueid
+newtls
+nexhop
+NeXT
+NEXTHOP
+nexthops
+nf
+Nfinoprsuvw
+NFS
+ni
+nid
+NID
+nids
+nint
+NINT
+nlink
+nlinks
+nnn
+NOCLOSE
+NODELAY
+nodename
+noexcept
+NOEXT
+noforward
+NOKEY
+NOLOCK
+NOMEMINIT
+NONAME
+NONDEF
+nonl
+noop
+Noop
+nop
+NOP
+NORETURN
+normalizer
+NOSUB
+notfound
+NOTFOUND
+NOTHROTTLE
+NOTREACHED
+nowait
+NOWAIT
+np
+nparts
+nr
+Nr
+nscd
+ntls
+ntohs
+ntop
+NUL
+nulll
+nullmx
+nullMX
+NULLMX
+num
+NUMERICHOST
+nvtable
+NVTABLE
+nxxx
+oact
+Oaktree
+oconv
+offsetof
+OID
+oldd
+oldlog
+oldstyle
+oname
+OpenLDAP's
+openlog
+operability
+OPs
+OPTNEG
+orcpt
+ORCPT
+ord
+ot
+ourself
+overallocate
+ownreq
+ozz
+padchar
+padlen
+pagein
+pageout
+PARAM
+parametername
+params
+PARAMS
+paren
+parens
+parm
+parsable
+parseline
+parsers
+Pashkov
+passivate
+Passivate
+passivated
+passivation
+pathame
+Pathname
+pathp
+patrik
+pcf
+PCF
+pclose
+pcs
+PDDMDS
+pdelay
+PDMS
+pedantism
+peekfd
+peercert
+permited
+pfxs
+PGRES
+PGresult
+pgsqlsource
+Pieter
+Pipelining
+PKCS
+PKEY
+PKIX
+PLAINTEXT
+Plauger
+plist
+plmysql
+PLMYSQL
+plpgsql
+PLPGSQL
+PMilter
+Pn
+pname
+POB
+popen
+POPEN
+portnum
+PORTP
+pos
+posix
+Posix
+postcondition
+Postcondition
+postexpire
+POSTFIX
+postgresql
+Postgresql
+Postlog
+postlogd
+Postprocessing
+postremove
+postrename
+postrmdir
+posttls
+PPTR
+PQescapeString
+PQescapeStringConn
+prabhat
+PRE
+precedences
+pred
+predefines
+prefetch
+prefi
+pregreet
+PREGREET
+pregreeting
+preimage
+Preload
+prepended
+prepending
+Prepending
+prepends
+preprocessed
+Preprocessing
+PREREQ
+prescan
+printfck
+PRINTFLIKE
+PRINTFPTRLIKE
+PRNGD
+PROC
+procname
+procnet
+PROCNET
+progname
+programmatically
+prolog
+proto
+Proto
+protomask
+prototyped
+PROX
+proxied
+Proxied
+PROXYING
+Proxymappers
+psc
+PSC
+pseudofield
+pseudothread
+pseudothreads
+PSS
+psSv
+PTHREAD
+pton
+PTRs
+pushback
+PUTC
+PUTCHAR
+putenv
+pv
+qfile
+qflags
+qI
+qIqueueid
+qname
+qnameval
+qsort
+QSTRING
+ratbox
+raxoft
+rcode
+RCODE
+rcpb
+RCPTs
+rdb
+rdev
+rdonly
+RDONLY
+rdwr
+RDWR
+readdir
+readline
+readlline
+readllines
+readwrite
+realloc
+recdump
+recip
+RECIP
+reclen
+reconnection
+recurse
+Recurse
+RECURSE
+Recurses
+recursing
+recv
+RECV
+Redhat
+Redistributions
+reentrancy
+REENTRANCY
+reentrant
+refcounts
+refesh
+regerror
+reget
+REGSUB
+relop
+RELOP
+relops
+rendez
+repl
+replayer
+replycode
+representable
+requestor
+requestors
+requeuing
+resflags
+responder
+restartable
+resync
+resynchronize
+ret
+RET
+retransmission
+retransmit
+retryable
+retval
+revalidate
+revalidated
+rewriter
+rfind
+rflag
+rflags
+rh
+RHS
+RHSBL
+rhswl
+RHSWL
+Ribbens
+rl
+RLIM
+RMTA
+rname
+RO
+Roel
+roques
+roundtrips
+rp
+RPCs
+RQST
+rr
+RRDATA
+rrlist
+RRSIG
+rtnetlink
+ruleset
+RWR
+sa
+salen
+SAML
+sanitization
+Santize
+sb
+SCACHE
+SCANFLIKE
+SCCS
+Schoenmakers
+Schupke
+scott
+screener
+sdelay
+SDK's
+seach
+seekable
+selectable
+sendfd
+sendmsg
+sep
+serv
+SERV
+serverid
+serverout
+servers's
+servicename
+servname
+SERVNAME
+SERVPORT
+sess
+SESS
+setegid
+Setenv
+seteuid
+setgroups
+Sethi
+setrlimit
+setsid
+setsockopt
+setuid
+sgid
+sig
+SIG
+sigaction
+sigaddset
+SIGALRM
+sigchld
+SIGCHLD
+sigdeath
+sigdelay
+sigemptyset
+sighup
+SIGILL
+siginit
+SIGINT
+SIGKILL
+signum
+SIGPIPE
+sigprocmask
+SIGQUIT
+sigresume
+SIGSEGV
+sigset
+sigsetup
+sigval
+silenty
+siocgif
+SIOCGIFCONF
+SIOCGIFNETMASK
+siocglif
+SIOCGLIFCONF
+SIOCGLIFNETMASK
+SIOCLIF
+sizeof
+skipblanks
+sl
+SLMDB
+SLMs
+smap
+SMFIF
+SMFIM
+sni
+SOA
+sockaddr
+SOCKADDR
+Socketmap
+socketmapname
+socketmaps
+socketpair
+socklen
+sockmap
+socktype
+SOCKTYPE
+sofar
+softerror
+softlinks
+SOML
+soname
+sp
+SPARC
+spawner
+Spead
+SPID
+splitq
+splitter
+sqlitecon
+sqrt
+SRC
+srv
+srvr
+sscanf
+SSF
+ssize
+ssscanf
+stackable
+starttime
+STATCUR
+STATFAIL
+statp
+STATUNTRIED
+StatusOr
+statusp
+stdarg
+stderr
+STDERR
+STDIN
+stdout
+STDOUT
+steenkeeng
+stmt
+str
+STR
+strcasecmp
+strcat
+strcpy
+streamlf
+STREAMLF
+STREQ
+strerror
+STRERROR
+strflags
+strftime
+stringops
+strlen
+STRLEN
+strncasecmp
+strncat
+strncpy
+strrecord
+STRREF
+strspn
+strtol
+strtoul
+strtype
+struct
+structs
+strval
+STS
+stuffozz
+stye
+subclasses
+subcommand
+subdirectories
+Subdirectory
+subjectAltName
+subjectAltNames
+sublist
+sublists
+Subnet
+subnets
+subopen
+subpatterns
+Substring
+substrings
+subtype
+subtypes
+succ
+sudo
+sunislelodge
+superblocks
+superset
+supprt
+Sutou
+SVID
+swb
+Symas
+symlinked
+symlink's
+symlinks
+syscall
+SYSCALL
+sysconf
+Syslog
+syslogged
+syslogging
+sysv
+TAAAA
+tailp
+tas
+teardown
+Tempfail
+tempfailed
+testcase
+testname
+th
+tha
+thash
+THASH
+theadsafe
+threadsafe
+thusly
+timecmp
+timeval
+timval
+tindx
+tItp
+tkt
+TLScontext
+tlsext
+tlsfinger
+tlsmgrmem
+tlsmgr's
+tlsp
+TLSP
+TLSPKTS
+TLSPROXY
+TLVs
+tm
+tmpbuf
+ToASCII
+TOCTOU
+Todo
+TODO
+TOFILE
+tok
+TOK
+tokenize
+Tokenize
+tokenizer
+tokenizes
+tokenizing
+tokval
+toUTF
+tp
+translit
+transp
+TRANSP
+treibsand
+tresspassers
+trimblanks
+trivally
+TRNC
+TRUNC
+TRUSTAD
+trustfile
+TTL
+TTLs
+tty
+tunable
+Tunable
+Tunables
+tv
+txn
+TXT
+Typechecking
+TYPECONNSTRING
+typedef
+typedefs
+TYPEINET
+TYPEUNIX
+ucasemap
+uchar
+UDP
+ug
+ugid
+uic
+uidna
+UIDNA
+UIDs
+uint
+ULIMIT
+Ullman
+ulong
+ULONG
+ultostr
+Ultrix
+ulval
+un
+unalias
+uname
+UNAUTH
+unbuffered
+uncache
+Uncomment
+undef
+UNDEF
+Undefine
+Undeliverable
+unescape
+UNFAIL
+unformatted
+unget
+ungetc
+Unhandled
+unicode
+unimpl
+uniq
+unistd
+unitialized
+Universitaetsplatz
+UnixWare
+unk
+unlink
+Unlink
+unlinked
+unlinking
+unlockfile
+unmark
+Unmark
+unmarks
+Unoptimized
+Unparsable
+unparse
+unparsed
+unparser
+unparsing
+UNPROTO
+unprototyped
+unregister
+unregistering
+unregisters
+unselect
+unselected
+unsetenv
+unsets
+UNSPEC
+unterminated
+unthrottle
+Unthrottle
+UNTHROTTLE
+UNTRUSTED
+upass
+upd
+updatable
+UPDATABLE
+Upref
+uprefs
+URI
+URIs
+url
+useauto
+usebits
+usec
+usleep
+USR
+utf
+utime
+UTS
+uva
+uxtext
+va
+valgrind
+validator
+VALIDATOR
+variadic
+vbuf
+VBUF
+VBUFs
+vdsb
+ve
+ver
+verifier
+verpified
+VERPify
+vfprintf
+vfy
+vmailer
+Vmailer
+vmilter
+VMS
+vmsg
+Vn
+vopened
+vous
+vp
+vprint
+vprintf
+vscan
+vsmtp
+vsmtpd
+vsnl
+VSNL
+vsprintf
+vstream
+VSTREAM
+Vstreams
+VSTREAM's
+VSTREAMs
+VSTREAMS
+vstring
+VSTRING
+VSTRINGs
+vtrace
+waitpid
+WAITPID
+Wakeup
+WAKEUP
+wat
+webservers
+WeiYu
+Wformat
+whatsup
+Whitespace
+WIFSTOPPED
+wil
+wildcarded
+Wimplicit
+wireshark
+Wmissing
+Woops
+Wparentheses
+wr
+Wrappermode
+WRITEMAP
+WRONLY
+wsp
+Wstrict
+Wswitch
+WTF
+Wuninitialized
+Wunused
+XCPT
+xdelay
+xe
+xfers
+xmask
+xport
+xsasl
+XSASL
+XSH
+xt
+XTRA
+XVxy
+xxdbx
+xxgdb
+xxxx
+XXXXX
+xxxxxx
+XXXXXXX
+YASLM
+yeardays
+yyyy
+yyyymmdd
+zA
+zer
+Zmailer
+AMD
+All's
+BIO
+BTU
+CALLBACK
+CHUNKING
+CO
+CONT
+CV
+Callback
+Cert
+Compaq
+DBL
+DBMS
+DICT
+DP
+Deferrals
+ENC
+EXCL
+EXP
+EXT
+Ff
+Goode
+Grandfathered
+INST
+Inline
+Kluge
+LANG
+LIB
+LP
+MAI
+MGR
+MIPS
+MISC
+MSG
+MULTIPART
+Majordomo
+Misc
+Mn
+NB
+NR
+OBS
+ORIG
+OTOH
+PF
+PP
+PX
+Pf
+Plugins
+REC
+RR
+Rcpt
+Regexp
+SB
+SC
+SEQ
+SN
+STAT
+STATS
+STD
+Siemens
+Simplistically
+Stat
+UK
+UNICODE
+USERNAME
+UTC
+Unicode
+Username
+VA
+ab
+alphanumerical
+app
+av
+barf
+beholder's
+bidirectionally
+binding's
+bio
+builtin
+callback
+callbacks
+ch
+chg
+comm
+comp
+crappy
+def
+deferrals
+diff
+enc
+excl
+exp
+ext
+externalized
+gazillions
+ht
+incl
+instance's
+key's
+kluge
+masqueraded
+maxed
+metadata
+mgr
+mp
+neg
+op
+ops
+perms
+pf
+piggybacked
+pref
+proactive
+proactively
+proxy's
+pt
+reanimates
+rec
+refactor
+regexps
+request's
+rollover
+schlepping
+scratchpad
+seq
+singlets
+stat
+stats
+trespassing
+ts
+val
+vars
+verboten
+versioning
+wiki
+DSTRICT
+FNV
+NONBLOCK
+Vo
+chongo
+fnv
+isthe
+ldseed
+softwareengineering
+stackexchange
+stdint
+Noll
diff --git a/proto/stop.spell-proto-html b/proto/stop.spell-proto-html
new file mode 100644
index 0000000..a4ad7c5
--- /dev/null
+++ b/proto/stop.spell-proto-html
@@ -0,0 +1,350 @@
+ABNF
+ADAgECAhQSv
+adhoc
+ADME
+aes
+af
+ahQkZ
+AIX
+Allowlist
+allowlisting
+allowlists
+alphanumerics
+amavisd
+ame
+apache
+ASE
+ATABASE
+ated
+attractor
+authc
+Axel
+backported
+Backscatter
+BAQEFAASCBKcwggSjAgEAAoIBAQDc
+barelf
+bC
+BDAT
+BgBQGBg
+BINARYMIME
+bona
+BQ
+br
+CAQAwBQYDK
+Carsten
+CdUaexKP
+ce
+certN
+cflags
+cgi
+CHACHA
+chainN
+ching
+ciphe
+cldr
+cOkjtAH
+COMPAT
+concurrenc
+conn
+Crespo
+cronjob
+csie
+cve
+cvename
+Cy
+cyrusimap
+DATAB
+DATABAS
+dbpath
+DCCAeCgAwIBAgIUIUkrbk
+deduplication
+Denylist
+denylisting
+denylists
+der
+dereferencing
+DESTADDR
+destinatio
+DESTPORT
+dfn
+dgram
+dH
+DISPLA
+dll
+dom
+doma
+dont
+DONT
+dq
+ecdsacerts
+ecdsakey
+EEXIST
+eeYOxyThMA
+Efbz
+egv
+else's
+ENOENT
+exchangers
+exploder
+fb
+fe
+fg
+fi
+fide
+fifo
+filesystem
+fmsiQoRHzAFBgMrZXEwFDESMBAG
+fprint
+Fq
+GAemPCT
+ge
+gid
+GID
+github
+Gunnar
+hardlink
+hea
+hecks
+HGVNTK
+HHMMSS
+hostn
+HOSTNAME
+hre
+href
+HswDQYJKoZIhvcNAQEL
+https
+HuNn
+HUP
+iana
+IDENT
+idna
+IDNA
+ijs
+imit
+IU
+jane
+Jänicke
+Jänicke's
+jByBifpIe
+jnorell
+joe
+js
+jsp
+kali
+KAME
+KazmyRi
+keld
+keyN
+Kilani
+krcaJvDSMgvu
+KypOZPNPF
+lan
+latencies
+li
+libmemcache
+libs
+lient
+limi
+LNler
+Logfile
+logrotate
+LOGTAG
+lookahead
+Lookups
+lsqlite
+lt
+MAILLOG
+mbox
+MEcCAQAwBQYDK
+MessageLabs
+MIDDLEBOX
+MIIBdjCB
+MIIBKzCB
+MIIC
+MIIEvQIBADANBgkqhkiG
+MILTER
+mit
+mitre
+mtaadmin
+MTAADMIN
+mtadmin
+mua
+mygroup
+myinst
+NAbIJaDBqZb
+nameservers
+namespace
+nat
+nC
+ncache
+NCALLS
+NCTU
+newgroup
+NFS
+nH
+ninit
+NNTP
+noop
+nroffescape
+nullmx
+nulPzwUo
+nzHQJ
+OGvpyrMlm
+oP
+opendmarc
+orion
+oth
+overinflate
+oyE
+PARAM
+parametername
+params
+parsers
+Pathname
+pfs
+pkgsrc
+POSTFIX
+postlogd
+pQcWsx
+precedences
+pregreet
+Pregreet
+PREGREET
+prepended
+prepending
+prepends
+proble
+proxied
+Pseudocode
+PSS
+punycode
+qADAgECAhQaw
+qi
+qmznjbD
+Quanah
+QusgkahH
+Ralf
+relayhos
+RESOLV
+resolvers
+retransmission
+retransmits
+retransmitted
+rf
+rflRreYuUZBp
+rhswl
+Rirz
+rL
+rMZDAFBgMrZXAwFDESMBAG
+RolyeiE
+roundtrips
+RPCZDrPX
+rsacerts
+rsachain
+rsakey
+rsyslog
+runnable
+SASLAUTHD
+scheduler's
+schemas
+se
+selectable
+ser
+SESS
+si
+SLcOiXFHXlxp
+smarthost
+smatch
+sni
+Softw
+sp
+spamassassin
+spambot
+sqrt
+stderr
+stdout
+Stdout
+stname
+strftime
+subdirectories
+suboptimal
+suid
+suiteb
+systemd
+sz
+tDc
+tempfailing
+th
+threadm
+threadsafe
+tname
+TRE
+trusteddomain
+TTL
+tu
+tw
+TXT
+uname
+Uncomment
+Undeliverable
+unexpanded
+unextended
+unicode
+unrefreshed
+unrepliable
+Unselective
+unvalidated
+uva
+vali
+VwBCIEIEJfbbO
+VxBDsEOQf
+VZuh
+Whitespace
+wi
+wip
+wKsTGDH
+wzFd
+xhtml
+YPDWxEHom
+YWH
+yYhh
+zdlPQR
+Aren
+rejec
+debian
+prox
+vir
+AAA
+Admin
+CHUNKING
+DAT
+Downsides
+Firefox
+Inline
+Jänicke's
+LANG
+NZ
+Plugin
+Plugins
+Unicode
+WHITELIST
+bk
+ch
+chg
+chunking
+comm
+dbl
+downsides
+fer
+gt
+hos
+injectors
+kinks
+pkg
+rollover
+rs
+subj
+wiki
+JÃ
+ng
+rsyslogd
diff --git a/proto/tcp_table b/proto/tcp_table
new file mode 100644
index 0000000..d1ddb81
--- /dev/null
+++ b/proto/tcp_table
@@ -0,0 +1,108 @@
+#++
+# NAME
+# tcp_table 5
+# SUMMARY
+# Postfix client/server table lookup protocol
+# SYNOPSIS
+# \fBpostmap -q "\fIstring\fB" tcp:\fIhost:port\fR
+#
+# \fBpostmap -q - tcp:\fIhost:port\fB <\fIinputfile\fR
+# DESCRIPTION
+# The Postfix mail system uses optional tables for address
+# rewriting or mail routing. These tables are usually in
+# \fBdbm\fR or \fBdb\fR format. Alternatively, table lookups
+# can be directed to a TCP server.
+#
+# To find out what types of lookup tables your Postfix system
+# supports use the "\fBpostconf -m\fR" command.
+#
+# To test lookup tables, use the "\fBpostmap -q\fR" command as
+# described in the SYNOPSIS above.
+# PROTOCOL DESCRIPTION
+# .ad
+# .fi
+# The TCP map class implements a very simple protocol: the client
+# sends a request, and the server sends one reply. Requests and
+# replies are sent as one line of ASCII text, terminated by the
+# ASCII newline character. Request and reply parameters (see below)
+# are separated by whitespace.
+#
+# Send and receive operations must complete in 100 seconds.
+# REQUEST FORMAT
+# .ad
+# .fi
+# The tcp_table protocol supports only the lookup request.
+# The request has the following form:
+# .IP "\fBget\fR SPACE \fIkey\fR NEWLINE"
+# Look up data under the specified key.
+# .PP
+# Postfix will not generate partial search keys such as domain
+# names without one or more subdomains, network addresses
+# without one or more least-significant octets, or email
+# addresses without the localpart, address extension or domain
+# portion. This behavior is also found with cidr:, pcre:, and
+# regexp: tables.
+# REPLY FORMAT
+# .ad
+# .fi
+# Each reply specifies a status code and text. Replies must be no
+# longer than 4096 characters including the newline terminator.
+# .IP "\fB500\fR SPACE \fItext\fR NEWLINE"
+# In case of a lookup request, the requested data does not exist.
+# The text describes the nature of the problem.
+# .IP "\fB400\fR SPACE \fItext\fR NEWLINE"
+# This indicates an error condition. The text describes the nature of
+# the problem. The client should retry the request later.
+# .IP "\fB200\fR SPACE \fItext\fR NEWLINE"
+# The request was successful. In the case of a lookup request,
+# the text contains an encoded version of the requested data.
+# ENCODING
+# .ad
+# .fi
+# In request and reply parameters, the character %, each non-printing
+# character, and each whitespace character must be replaced by %XX,
+# where XX is the corresponding ASCII hexadecimal character value. The
+# hexadecimal codes can be specified in any case (upper, lower, mixed).
+#
+# The Postfix client always encodes a request.
+# The server may omit the encoding as long as the reply
+# is guaranteed to not contain the % or NEWLINE character.
+# SECURITY
+# .ad
+# .fi
+# Do not use TCP lookup tables for security critical purposes.
+# The client-server connection is not protected and the server
+# is not authenticated.
+# BUGS
+# Only the lookup method is currently implemented.
+#
+# The client does not hang up when the connection is idle for
+# a long time.
+# SEE ALSO
+# postmap(1), Postfix lookup table manager
+# regexp_table(5), format of regular expression tables
+# pcre_table(5), format of PCRE tables
+# cidr_table(5), format of CIDR tables
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# DATABASE_README, Postfix lookup table overview
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--*/
diff --git a/proto/transport b/proto/transport
new file mode 100644
index 0000000..c5ffff2
--- /dev/null
+++ b/proto/transport
@@ -0,0 +1,306 @@
+#++
+# NAME
+# transport 5
+# SUMMARY
+# Postfix transport table format
+# SYNOPSIS
+# \fBpostmap /etc/postfix/transport\fR
+#
+# \fBpostmap -q "\fIstring\fB" /etc/postfix/transport\fR
+#
+# \fBpostmap -q - /etc/postfix/transport <\fIinputfile\fR
+# DESCRIPTION
+# The optional \fBtransport\fR(5) table specifies a mapping from email
+# addresses to message delivery transports and next-hop destinations.
+# Message delivery transports such as \fBlocal\fR or \fBsmtp\fR
+# are defined in the \fBmaster.cf\fR file, and next-hop
+# destinations are typically hosts or domain names. The
+# table is searched by the \fBtrivial-rewrite\fR(8) daemon.
+#
+# This mapping overrides the default \fItransport\fR:\fInexthop\fR
+# selection that is built into Postfix:
+# .IP "\fBlocal_transport (default: local:$myhostname)\fR"
+# This is the default for final delivery to domains listed
+# with \fBmydestination\fR, and for [\fIipaddress\fR]
+# destinations that match \fB$inet_interfaces\fR or
+# \fB$proxy_interfaces\fR. The default \fInexthop\fR destination
+# is the MTA hostname.
+# .IP "\fBvirtual_transport (default: virtual:)\fR"
+# This is the default for final delivery to domains listed
+# with \fBvirtual_mailbox_domains\fR. The default \fInexthop\fR
+# destination is the recipient domain.
+# .IP "\fBrelay_transport (default: relay:)\fR"
+# This is the default for remote delivery to domains listed
+# with \fBrelay_domains\fR. In order of decreasing precedence,
+# the \fInexthop\fR destination is taken from \fBrelay_transport\fR,
+# \fBsender_dependent_relayhost_maps\fR, \fBrelayhost\fR, or from the
+# recipient domain.
+# .IP "\fBdefault_transport (default: smtp:)\fR"
+# This is the default for remote delivery to other destinations.
+# In order of decreasing precedence, the \fInexthop\fR
+# destination is taken from \fBsender_dependent_default_transport_maps,
+# \fBdefault_transport\fR, \fBsender_dependent_relayhost_maps\fR,
+# \fBrelayhost\fR, or from the recipient domain.
+# .PP
+# Normally, the \fBtransport\fR(5) table is specified as a text file
+# that serves as input to the \fBpostmap\fR(1) command.
+# The result, an indexed file in \fBdbm\fR or \fBdb\fR format, is used
+# for fast searching by the mail system. Execute the command
+# "\fBpostmap /etc/postfix/transport\fR" to rebuild an indexed
+# file after changing the corresponding transport table.
+#
+# When the table is provided via other means such as NIS, LDAP
+# or SQL, the same lookups are done as for ordinary indexed files.
+#
+# Alternatively, the table can be provided as a regular-expression
+# map where patterns are given as regular expressions, or lookups
+# can be directed to a TCP-based server. In those case, the lookups
+# are done in a slightly different way as described below under
+# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES".
+# CASE FOLDING
+# .ad
+# .fi
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+# TABLE FORMAT
+# .ad
+# .fi
+# The input format for the \fBpostmap\fR(1) command is as follows:
+# .IP "\fIpattern result\fR"
+# When \fIpattern\fR matches the recipient address or domain, use the
+# corresponding \fIresult\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# .PP
+# The \fIpattern\fR specifies an email address, a domain name, or
+# a domain name hierarchy, as described in section "TABLE
+# SEARCH ORDER".
+#
+# The \fIresult\fR is of the form \fItransport:nexthop\fR and
+# specifies how or where to deliver mail. This is described in
+# section "RESULT FORMAT".
+# TABLE SEARCH ORDER
+# .ad
+# .fi
+# With lookups from indexed files such as DB or DBM, or from networked
+# tables such as NIS, LDAP or SQL, patterns are tried in the order as
+# listed below:
+# .IP "\fIuser+extension@domain transport\fR:\fInexthop\fR"
+# Deliver mail for \fIuser+extension@domain\fR through
+# \fItransport\fR to
+# \fInexthop\fR.
+# .IP "\fIuser@domain transport\fR:\fInexthop\fR"
+# Deliver mail for \fIuser@domain\fR through \fItransport\fR to
+# \fInexthop\fR.
+# .IP "\fIdomain transport\fR:\fInexthop\fR"
+# Deliver mail for \fIdomain\fR through \fItransport\fR to
+# \fInexthop\fR.
+# .IP "\fI.domain transport\fR:\fInexthop\fR"
+# Deliver mail for any subdomain of \fIdomain\fR through
+# \fItransport\fR to \fInexthop\fR. This applies only when the
+# string \fBtransport_maps\fR is not listed in the
+# \fBparent_domain_matches_subdomains\fR configuration setting.
+# Otherwise, a domain name matches itself and its subdomains.
+# .IP "\fB*\fI transport\fR:\fInexthop\fR"
+# The special pattern \fB*\fR represents any address (i.e. it
+# functions as the wild-card pattern, and is unique to Postfix
+# transport tables).
+# .PP
+# Note 1: the null recipient address is looked up as
+# \fB$empty_address_recipient\fR@\fB$myhostname\fR (default:
+# mailer-daemon@hostname).
+#
+# Note 2: \fIuser@domain\fR or \fIuser+extension@domain\fR
+# lookup is available in Postfix 2.0 and later.
+# RESULT FORMAT
+# .ad
+# .fi
+# The lookup result is of the form \fItransport\fB:\fInexthop\fR.
+# The \fItransport\fR field specifies a mail delivery transport
+# such as \fBsmtp\fR or \fBlocal\fR. The \fInexthop\fR field
+# specifies where and how to deliver mail.
+#
+# The transport field specifies the name of a mail delivery transport
+# (the first name of a mail delivery service entry in the Postfix
+# \fBmaster.cf\fR file).
+#
+# The nexthop field usually specifies one recipient domain
+# or hostname. In the case of the Postfix SMTP/LMTP client,
+# the nexthop field may contain a list of nexthop destinations
+# separated by comma or whitespace (Postfix 3.5 and later).
+#
+# The syntax of a nexthop destination is transport dependent.
+# With SMTP, specify a service on a non-default
+# port as \fIhost\fR:\fIservice\fR, and disable MX (mail exchanger)
+# DNS lookups with [\fIhost\fR] or [\fIhost\fR]:\fIport\fR. The [] form
+# is required when you specify an IP address instead of a hostname.
+#
+# A null \fItransport\fR and null \fInexthop\fR field means "do
+# not change": use the delivery transport and nexthop information
+# that would be used when the entire transport table did not exist.
+#
+# A non-null \fItransport\fR field with a null \fInexthop\fR field
+# resets the nexthop information to the recipient domain.
+#
+# A null \fItransport\fR field with non-null \fInexthop\fR field
+# does not modify the transport information.
+# EXAMPLES
+# .ad
+# .fi
+# In order to deliver internal mail directly, while using a
+# mail relay for all other mail, specify a null entry for
+# internal destinations (do not change the delivery transport or
+# the nexthop information) and specify a wildcard for all other
+# destinations.
+#
+# .nf
+# \fB\&my.domain :\fR
+# \fB\&.my.domain :\fR
+# \fB* smtp:outbound-relay.my.domain\fR
+# .fi
+#
+# In order to send mail for \fBexample.com\fR and its subdomains
+# via the \fBuucp\fR transport to the UUCP host named \fBexample\fR:
+#
+# .nf
+# \fBexample.com uucp:example\fR
+# \fB\&.example.com uucp:example\fR
+# .fi
+#
+# When no nexthop host name is specified, the destination domain
+# name is used instead. For example, the following directs mail for
+# \fIuser\fR@\fBexample.com\fR via the \fBslow\fR transport to a mail
+# exchanger for \fBexample.com\fR. The \fBslow\fR transport could be
+# configured to run at most one delivery process at a time:
+#
+# .nf
+# \fBexample.com slow:\fR
+# .fi
+#
+# When no transport is specified, Postfix uses the transport that
+# matches the address domain class (see DESCRIPTION
+# above). The following sends all mail for \fBexample.com\fR and its
+# subdomains to host \fBgateway.example.com\fR:
+#
+# .nf
+# \fBexample.com :[gateway.example.com]\fR
+# \fB\&.example.com :[gateway.example.com]\fR
+# .fi
+#
+# In the above example, the [] suppress MX lookups.
+# This prevents mail routing loops when your machine is primary MX
+# host for \fBexample.com\fR.
+#
+# In the case of delivery via SMTP or LMTP, one may specify
+# \fIhost\fR:\fIservice\fR instead of just a host:
+#
+# .nf
+# \fBexample.com smtp:bar.example:2025\fR
+# .fi
+#
+# This directs mail for \fIuser\fR@\fBexample.com\fR to host \fBbar.example\fR
+# port \fB2025\fR. Instead of a numerical port a symbolic name may be
+# used. Specify [] around the hostname if MX lookups must be disabled.
+#
+# Deliveries via SMTP or LMTP support multiple destinations
+# (Postfix >= 3.5):
+#
+# .nf
+# \fBexample.com smtp:bar.example, foo.example\fR
+# .fi
+#
+# This tries to deliver to \fBbar.example\fR before trying
+# to deliver to \fBfoo.example\fR.
+#
+# The error mailer can be used to bounce mail:
+#
+# .nf
+# \fB\&.example.com error:mail for *.example.com is not deliverable\fR
+# .fi
+#
+# This causes all mail for \fIuser\fR@\fIanything\fB.example.com\fR
+# to be bounced.
+# REGULAR EXPRESSION TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when the table
+# is given in the form of regular expressions. For a description of
+# regular expression lookup table syntax, see \fBregexp_table\fR(5)
+# or \fBpcre_table\fR(5).
+#
+# Each pattern is a regular expression that is applied to the entire
+# address being looked up. Thus, \fIsome.domain.hierarchy\fR is not
+# looked up via its parent domains,
+# nor is \fIuser+foo@domain\fR looked up as \fIuser@domain\fR.
+#
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the search string.
+#
+# The \fBtrivial-rewrite\fR(8) server disallows regular
+# expression substitution of $1 etc. in regular expression
+# lookup tables, because that could open a security hole
+# (Postfix version 2.3 and later).
+# TCP-BASED TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when lookups
+# are directed to a TCP-based server. For a description of the TCP
+# client/server lookup protocol, see \fBtcp_table\fR(5).
+# This feature is not available up to and including Postfix version 2.4.
+#
+# Each lookup operation uses the entire recipient address once. Thus,
+# \fIsome.domain.hierarchy\fR is not looked up via its parent domains,
+# nor is \fIuser+foo@domain\fR looked up as \fIuser@domain\fR.
+#
+# Results are the same as with indexed file lookups.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# The following \fBmain.cf\fR parameters are especially relevant.
+# The text below provides only a parameter summary. See
+# \fBpostconf\fR(5) for more details including examples.
+# .IP "\fBempty_address_recipient (MAILER-DAEMON)\fR"
+# The recipient of mail addressed to the null address.
+# .IP "\fBparent_domain_matches_subdomains (see 'postconf -d' output)\fR"
+# A list of Postfix features where the pattern "example.com" also
+# matches subdomains of example.com,
+# instead of requiring an explicit ".example.com" pattern.
+# .IP "\fBtransport_maps (empty)\fR"
+# Optional lookup tables with mappings from recipient address to
+# (message delivery transport, next-hop destination).
+# SEE ALSO
+# trivial-rewrite(8), rewrite and resolve addresses
+# master(5), master.cf file format
+# postconf(5), configuration parameters
+# postmap(1), Postfix lookup table manager
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# ADDRESS_REWRITING_README, address rewriting guide
+# DATABASE_README, Postfix lookup table overview
+# FILTER_README, external content filter
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--
diff --git a/proto/virtual b/proto/virtual
new file mode 100644
index 0000000..84edde4
--- /dev/null
+++ b/proto/virtual
@@ -0,0 +1,302 @@
+#++
+# NAME
+# virtual 5
+# SUMMARY
+# Postfix virtual alias table format
+# SYNOPSIS
+# \fBpostmap /etc/postfix/virtual\fR
+#
+# \fBpostmap -q "\fIstring\fB" /etc/postfix/virtual\fR
+#
+# \fBpostmap -q - /etc/postfix/virtual <\fIinputfile\fR
+# DESCRIPTION
+# The optional \fBvirtual\fR(5) alias table rewrites recipient
+# addresses for all local, all virtual, and all remote mail
+# destinations.
+# This is unlike the \fBaliases\fR(5) table which is used
+# only for \fBlocal\fR(8) delivery. Virtual aliasing is
+# recursive, and is implemented by the Postfix \fBcleanup\fR(8)
+# daemon before mail is queued.
+#
+# The main applications of virtual aliasing are:
+# .IP \(bu
+# To redirect mail for one address to one or more addresses.
+# .IP \(bu
+# To implement virtual alias domains where all addresses are aliased
+# to addresses in other domains.
+# .sp
+# Virtual alias domains are not to be confused with the virtual mailbox
+# domains that are implemented with the Postfix \fBvirtual\fR(8) mail
+# delivery agent. With virtual mailbox domains, each recipient address
+# can have its own mailbox.
+# .PP
+# Virtual aliasing is applied only to recipient
+# envelope addresses, and does not affect message headers.
+# Use \fBcanonical\fR(5)
+# mapping to rewrite header and envelope addresses in general.
+#
+# Normally, the \fBvirtual\fR(5) alias table is specified as a text file
+# that serves as input to the \fBpostmap\fR(1) command.
+# The result, an indexed file in \fBdbm\fR or \fBdb\fR format,
+# is used for fast searching by the mail system. Execute the command
+# "\fBpostmap /etc/postfix/virtual\fR" to rebuild an indexed
+# file after changing the corresponding text file.
+#
+# When the table is provided via other means such as NIS, LDAP
+# or SQL, the same lookups are done as for ordinary indexed files.
+#
+# Alternatively, the table can be provided as a regular-expression
+# map where patterns are given as regular expressions, or lookups
+# can be directed to a TCP-based server. In those case, the lookups
+# are done in a slightly different way as described below under
+# "REGULAR EXPRESSION TABLES" or "TCP-BASED TABLES".
+# CASE FOLDING
+# .ad
+# .fi
+# The search string is folded to lowercase before database
+# lookup. As of Postfix 2.3, the search string is not case
+# folded with database types such as regexp: or pcre: whose
+# lookup fields can match both upper and lower case.
+# TABLE FORMAT
+# .ad
+# .fi
+# The input format for the \fBpostmap\fR(1) command is as follows:
+# .IP "\fIpattern address, address, ...\fR"
+# When \fIpattern\fR matches a mail address, replace it by the
+# corresponding \fIaddress\fR.
+# .IP "blank lines and comments"
+# Empty lines and whitespace-only lines are ignored, as
+# are lines whose first non-whitespace character is a `#'.
+# .IP "multi-line text"
+# A logical line starts with non-whitespace text. A line that
+# starts with whitespace continues a logical line.
+# TABLE SEARCH ORDER
+# .ad
+# .fi
+# With lookups from indexed files such as DB or DBM, or from networked
+# tables such as NIS, LDAP or SQL, each \fIuser\fR@\fIdomain\fR
+# query produces a sequence of query patterns as described below.
+#
+# Each query pattern is sent to each specified lookup table
+# before trying the next query pattern, until a match is
+# found.
+# .IP "\fIuser\fR@\fIdomain address, address, ...\fR"
+# Redirect mail for \fIuser\fR@\fIdomain\fR to \fIaddress\fR.
+# This form has the highest precedence.
+# .IP "\fIuser address, address, ...\fR"
+# Redirect mail for \fIuser\fR@\fIsite\fR to \fIaddress\fR when
+# \fIsite\fR is equal to $\fBmyorigin\fR, when \fIsite\fR is listed in
+# $\fBmydestination\fR, or when it is listed in $\fBinet_interfaces\fR
+# or $\fBproxy_interfaces\fR.
+# .sp
+# This functionality overlaps with the functionality of the local
+# \fIaliases\fR(5) database. The difference is that \fBvirtual\fR(5)
+# mapping can be applied to non-local addresses.
+# .IP "@\fIdomain address, address, ...\fR"
+# Redirect mail for other users in \fIdomain\fR to \fIaddress\fR.
+# This form has the lowest precedence.
+# .sp
+# Note: @\fIdomain\fR is a wild-card. With this form, the
+# Postfix SMTP server accepts
+# mail for any recipient in \fIdomain\fR, regardless of whether
+# that recipient exists. This may turn your mail system into
+# a backscatter source: Postfix first accepts mail for
+# non-existent recipients and then tries to return that mail
+# as "undeliverable" to the often forged sender address.
+# .sp
+# To avoid backscatter with mail for a wild-card domain,
+# replace the wild-card mapping with explicit 1:1 mappings,
+# or add a reject_unverified_recipient restriction for that
+# domain:
+#
+# .nf
+# smtpd_recipient_restrictions =
+# ...
+# reject_unauth_destination
+# check_recipient_access
+# inline:{example.com=reject_unverified_recipient}
+# unverified_recipient_reject_code = 550
+#.fi
+#
+# In the above example, Postfix may contact a remote server
+# if the recipient is aliased to a remote address.
+# RESULT ADDRESS REWRITING
+# .ad
+# .fi
+# The lookup result is subject to address rewriting:
+# .IP \(bu
+# When the result has the form @\fIotherdomain\fR, the
+# result becomes the same \fIuser\fR in \fIotherdomain\fR.
+# This works only for the first address in a multi-address
+# lookup result.
+# .IP \(bu
+# When "\fBappend_at_myorigin=yes\fR", append "\fB@$myorigin\fR"
+# to addresses without "@domain".
+# .IP \(bu
+# When "\fBappend_dot_mydomain=yes\fR", append
+# "\fB.$mydomain\fR" to addresses without ".domain".
+# ADDRESS EXTENSION
+# .fi
+# .ad
+# When a mail address localpart contains the optional recipient delimiter
+# (e.g., \fIuser+foo\fR@\fIdomain\fR), the lookup order becomes:
+# \fIuser+foo\fR@\fIdomain\fR, \fIuser\fR@\fIdomain\fR, \fIuser+foo\fR,
+# \fIuser\fR, and @\fIdomain\fR.
+#
+# The \fBpropagate_unmatched_extensions\fR parameter controls whether
+# an unmatched address extension (\fI+foo\fR) is propagated to the
+# result of a table lookup.
+# VIRTUAL ALIAS DOMAINS
+# .ad
+# .fi
+# Besides virtual aliases, the virtual alias table can also be used
+# to implement virtual alias domains. With a virtual alias domain, all
+# recipient addresses are aliased to addresses in other domains.
+#
+# Virtual alias domains are not to be confused with the virtual mailbox
+# domains that are implemented with the Postfix \fBvirtual\fR(8) mail
+# delivery agent. With virtual mailbox domains, each recipient address
+# can have its own mailbox.
+#
+# With a virtual alias domain, the virtual domain has its
+# own user name space. Local (i.e. non-virtual) usernames are not
+# visible in a virtual alias domain. In particular, local
+# \fBaliases\fR(5) and local mailing lists are not visible as
+# \fIlocalname@virtual-alias.domain\fR.
+#
+# Support for a virtual alias domain looks like:
+#
+# .nf
+# /etc/postfix/main.cf:
+# virtual_alias_maps = hash:/etc/postfix/virtual
+# .fi
+#
+# Note: some systems use \fBdbm\fR databases instead of \fBhash\fR.
+# See the output from "\fBpostconf -m\fR" for available database types.
+#
+# .nf
+# /etc/postfix/virtual:
+# \fIvirtual-alias.domain anything\fR (right-hand content does not matter)
+# \fIpostmaster@virtual-alias.domain postmaster\fR
+# \fIuser1@virtual-alias.domain address1\fR
+# \fIuser2@virtual-alias.domain address2, address3\fR
+# .fi
+# .sp
+# The \fIvirtual-alias.domain anything\fR entry is required for a
+# virtual alias domain. \fBWithout this entry, mail is rejected
+# with "relay access denied", or bounces with
+# "mail loops back to myself".\fR
+#
+# Do not specify virtual alias domain names in the \fBmain.cf
+# mydestination\fR or \fBrelay_domains\fR configuration parameters.
+#
+# With a virtual alias domain, the Postfix SMTP server
+# accepts mail for \fIknown-user@virtual-alias.domain\fR, and rejects
+# mail for \fIunknown-user\fR@\fIvirtual-alias.domain\fR as undeliverable.
+#
+# Instead of specifying the virtual alias domain name via
+# the \fBvirtual_alias_maps\fR table, you may also specify it via
+# the \fBmain.cf virtual_alias_domains\fR configuration parameter.
+# This latter parameter uses the same syntax as the \fBmain.cf
+# mydestination\fR configuration parameter.
+# REGULAR EXPRESSION TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when the table
+# is given in the form of regular expressions. For a description of
+# regular expression lookup table syntax, see \fBregexp_table\fR(5)
+# or \fBpcre_table\fR(5).
+#
+# Each pattern is a regular expression that is applied to the entire
+# address being looked up. Thus, \fIuser@domain\fR mail addresses are not
+# broken up into their \fIuser\fR and \fI@domain\fR constituent parts,
+# nor is \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Patterns are applied in the order as specified in the table, until a
+# pattern is found that matches the search string.
+#
+# Results are the same as with indexed file lookups, with
+# the additional feature that parenthesized substrings from the
+# pattern can be interpolated as \fB$1\fR, \fB$2\fR and so on.
+# TCP-BASED TABLES
+# .ad
+# .fi
+# This section describes how the table lookups change when lookups
+# are directed to a TCP-based server. For a description of the TCP
+# client/server lookup protocol, see \fBtcp_table\fR(5).
+# This feature is available in Postfix 2.5 and later.
+#
+# Each lookup operation uses the entire address once. Thus,
+# \fIuser@domain\fR mail addresses are not broken up into their
+# \fIuser\fR and \fI@domain\fR constituent parts, nor is
+# \fIuser+foo\fR broken up into \fIuser\fR and \fIfoo\fR.
+#
+# Results are the same as with indexed file lookups.
+# BUGS
+# The table format does not understand quoting conventions.
+# CONFIGURATION PARAMETERS
+# .ad
+# .fi
+# The following \fBmain.cf\fR parameters are especially relevant to
+# this topic. See the Postfix \fBmain.cf\fR file for syntax details
+# and for default values. Use the "\fBpostfix reload\fR" command after
+# a configuration change.
+# .IP "\fBvirtual_alias_maps ($virtual_maps)\fR"
+# Optional lookup tables that alias specific mail addresses or domains
+# to other local or remote addresses.
+# .IP "\fBvirtual_alias_domains ($virtual_alias_maps)\fR"
+# Postfix is the final destination for the specified list of virtual
+# alias domains, that is, domains for which all addresses are aliased
+# to addresses in other local or remote domains.
+# .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR"
+# What address lookup tables copy an address extension from the lookup
+# key to the lookup result.
+# .PP
+# Other parameters of interest:
+# .IP "\fBinet_interfaces (all)\fR"
+# The network interface addresses that this mail system receives
+# mail on.
+# .IP "\fBmydestination ($myhostname, localhost.$mydomain, localhost)\fR"
+# The list of domains that are delivered via the $local_transport
+# mail delivery transport.
+# .IP "\fBmyorigin ($myhostname)\fR"
+# The domain name that locally-posted mail appears to come
+# from, and that locally posted mail is delivered to.
+# .IP "\fBowner_request_special (yes)\fR"
+# Enable special treatment for owner-\fIlistname\fR entries in the
+# \fBaliases\fR(5) file, and don't split owner-\fIlistname\fR and
+# \fIlistname\fR-request address localparts when the recipient_delimiter
+# is set to "-".
+# .IP "\fBproxy_interfaces (empty)\fR"
+# The network interface addresses that this mail system receives mail
+# on by way of a proxy or network address translation unit.
+# SEE ALSO
+# cleanup(8), canonicalize and enqueue mail
+# postmap(1), Postfix lookup table manager
+# postconf(5), configuration parameters
+# canonical(5), canonical address mapping
+# README FILES
+# .ad
+# .fi
+# Use "\fBpostconf readme_directory\fR" or
+# "\fBpostconf html_directory\fR" to locate this information.
+# .na
+# .nf
+# ADDRESS_REWRITING_README, address rewriting guide
+# DATABASE_README, Postfix lookup table overview
+# VIRTUAL_README, domain hosting guide
+# 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
+#
+# Wietse Venema
+# Google, Inc.
+# 111 8th Avenue
+# New York, NY 10011, USA
+#--