]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.12-20140316
authorWietse Venema <wietse@porcupine.org>
Sun, 16 Mar 2014 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Mon, 17 Mar 2014 12:07:08 +0000 (08:07 -0400)
47 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/TLS_README
postfix/RELEASE_NOTES
postfix/html/TLS_README.html
postfix/html/lmdb_table.5.html
postfix/html/lmtp.8.html
postfix/html/pipe.8.html
postfix/html/postconf.5.html
postfix/html/smtp.8.html
postfix/html/virtual.8.html
postfix/man/man5/lmdb_table.5
postfix/man/man5/postconf.5
postfix/man/man8/pipe.8
postfix/man/man8/smtp.8
postfix/man/man8/virtual.8
postfix/mantools/postlink
postfix/proto/TLS_README.html
postfix/proto/lmdb_table
postfix/proto/postconf.proto
postfix/src/global/Makefile.in
postfix/src/global/bounce.c
postfix/src/global/bounce.h
postfix/src/global/defer.c
postfix/src/global/defer.h
postfix/src/global/dsn.c
postfix/src/global/mail_params.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/ndr_filter.c [new file with mode: 0644]
postfix/src/global/ndr_filter.h [new file with mode: 0644]
postfix/src/master/Makefile.in
postfix/src/master/event_server.c
postfix/src/master/mail_server.h
postfix/src/master/multi_server.c
postfix/src/master/single_server.c
postfix/src/master/trigger_server.c
postfix/src/pipe/pipe.c
postfix/src/smtp/lmtp_params.c
postfix/src/smtp/smtp.c
postfix/src/smtp/smtp_connect.c
postfix/src/smtp/smtp_params.c
postfix/src/smtp/smtp_tls_policy.c
postfix/src/smtp/smtp_trouble.c
postfix/src/smtpd/smtpd_check.c
postfix/src/trivial-rewrite/transport.c
postfix/src/virtual/virtual.c

index 78e0a16ef68808250f094b1cdb737c420bfff84e..82bf6e4fb7ea4005a657fddb02663a8341ac4dc4 100644 (file)
 -TNAME_CODE
 -TNAME_MASK
 -TNBBIO
+-TNDR_FILTER
 -TOPTIONS
 -TPCF_DBMS_INFO
 -TPCF_EVAL_CTX
index e0592bc05d6c6982054190550264290c0a2ba15a..7d986d0daa20661d23d2e9d096c2c904e867bacb 100644 (file)
@@ -19588,3 +19588,38 @@ Apologies for any names omitted.
 
        Documentation: new self-signed certificate example and
        updated private CA example. File: proto/TLS_README.html.
+
+20140224
+
+       Bugfix (introduced: 20061106): when the "retry" transport
+       was added to Postfix, it was not given special status like
+       the "error" transport. The Postfix SMTP server did not defer
+       mail that resolves to the "retry" transport, and the
+       trivial-rewrite daemon would override the null nexthop
+       destination in "retry:" with the current nexthop destination.
+       Files: smtpd/smtpd_check.c, trivial-rewrite/transport.c.
+
+20140227
+
+       Bugfix: Enforce TLS when TLSA records exist, but all are
+       unusable; Don't leak dane handle when all TLSA records are
+       unusable.  Viktor Dukhovni. File: smtp/smtp_tls_policy.c.
+
+       Cleanup: log TLS policy lookups as warnings. Viktor Dukhovni.
+       File: smtp/smtp_connect.c.
+
+20140316
+
+       Feature: preliminary support to change arbitrary hard
+       delivery errors into soft errors and vice versa, originally
+       introduced for sites that want to hard-bounce mail when a
+       remote SMTP server does not announce TLS support. New main.cf
+       parameters: {default,smtp,pipe,virtual}_bounce_defer_filter.
+       Support for the local(8) delivery agent is awaiting additional
+       code to emulate defer_one() support, and support for qmgr(8)
+       is awaiting further analysis.  Files: proto/postconf.proto,
+       mantools/postlink, global/bounce.[hc], bounce/defer.[hc],
+       global/ndr_filter.[hc], global/mail_params.[hc],
+       master/event_server.c, master/multi_server.c,
+       master/single_server.c, master/trigger_server.c, smtp/smtp.c,
+       pipe/pipe.c, virtual/virtual.c.
index 148f721cec625c2556bc9ec70343cf6f4680ae53..985e01d83b3fd0f90ceadc74c5bc7d4b21072c9b 100644 (file)
@@ -2023,6 +2023,7 @@ This requires super-user privileges.
 
     # 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}"
@@ -2057,9 +2058,10 @@ P\bPr\bri\biv\bva\bat\bte\be C\bCe\ber\brt\bti\bif\bfi\bic\bca\bat\bte\be A\bAu\but\bth\bho\bor\bri\bit\bt
   * Create an unpassworded private key for host foo.porcupine.org and create an
     unsigned public key certificate.
 
-        % o\bop\bpe\ben\bns\bss\bsl\bl r\bre\beq\bq -\b-n\bne\bew\bw -\b-n\bno\bod\bde\bes\bs -\b-k\bke\bey\byo\bou\but\bt f\bfo\boo\bo-\b-k\bke\bey\by.\b.p\bpe\bem\bm -\b-o\bou\but\bt f\bfo\boo\bo-\b-r\bre\beq\bq.\b.p\bpe\bem\bm
+        % (\b(u\bum\bma\bas\bsk\bk 0\b07\b77\b7;\b; o\bop\bpe\ben\bns\bss\bsl\bl r\bre\beq\bq -\b-n\bne\bew\bw -\b-n\bne\bew\bwk\bke\bey\by r\brs\bsa\ba:\b:2\b20\b04\b48\b8 -\b-n\bno\bod\bde\bes\bs -\b-k\bke\bey\byo\bou\but\bt f\bfo\boo\bo-\b-
+        k\bke\bey\by.\b.p\bpe\bem\bm -\b-o\bou\but\bt f\bfo\boo\bo-\b-r\bre\beq\bq.\b.p\bpe\bem\bm)\b)
         Using configuration from /etc/ssl/openssl.cnf
-        Generating a 1024 bit RSA private key
+        Generating a 2048 bit RSA private key
         ........................................++++++
         ....++++++
         writing new private key to 'foo-key.pem'
index 14b8ea23f54623960f72207b4848969848953904..6a3305bd18bb58e5a3ed7e4ab6dfd6ef7eb0011a 100644 (file)
@@ -15,3 +15,38 @@ specifies the release date of a stable release or snapshot release.
 
 If you upgrade from Postfix 2.10 or earlier, read RELEASE_NOTES-2.11
 before proceeding.
+
+Major changes with snapshot 20140316
+====================================
+
+Preliminary support to change arbitrary hard delivery errors into
+soft errors and vice versa, originally implemented for sites that
+want to bounce mail when a remote SMTP server does not support
+STARTTLS.
+
+This feature is implemented as a filter that replaces the three-number
+enhanced status code and descriptive text in Postfix delivery agent
+bounce/defer messages.
+
+The following example turns specific soft TLS errors into hard
+errors, by overriding the first number in the enhanced status code.
+
+/etc/postfix/main.cf:
+    smtp_bounce_defer_filter = pcre:/etc/postfix/smtp_ndr_filter
+
+/etc/postfix/smtp_ndr_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
+
+Support is currently limited to the lmtp(8), pipe(8), smtp(8) and
+virtual(8) delivery agents. The new main.cf parameters and default
+values are:
+
+    default_bounce_defer_filter =
+    lmtp_bounce_defer_filter = $default_bounce_defer_filter
+    pipe_bounce_defer_filter = $default_bounce_defer_filter
+    smtp_bounce_defer_filter = $default_bounce_defer_filter
+    virtual_bounce_defer_filter = $default_bounce_defer_filter
+
+See the postconf(5) manpage for more details.  Support for local(8)
+and qmgr(8) will be added as time is available.
index 8c653c7760edfa5e7ac060b9bc2725a8bf80dfe8..f18b619b1783712623d0197c84d96c5f0b69862e 100644 (file)
@@ -2651,6 +2651,7 @@ the local Postfix system. This requires super-user privileges. </p>
 <pre>
 # dir="$(postconf -h <a href="postconf.5.html#config_directory">config_directory</a>)"
 # fqdn=$(postconf -h <a href="postconf.5.html#myhostname">myhostname</a>)
+# 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}"
@@ -2697,9 +2698,9 @@ an unsigned public key certificate. </p>
 
 <blockquote>
 <pre>
-% <b>openssl req -new -nodes -keyout foo-key.pem -out foo-req.pem</b>
+% <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 1024 bit RSA private key
+Generating a 2048 bit RSA private key
 ........................................++++++
 ....++++++
 writing new private key to 'foo-key.pem'
index c2ac242d4ea32fc02c1dac4cc2aa427cd4f24428..9a4cf620bb4953f01514be77189be28bb992850f 100644 (file)
@@ -64,17 +64,16 @@ LMDB_TABLE(5)                                                    LMDB_TABLE(5)
        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 acquire an exclusive lock between updating the database and start-
-       ing another write transaction.
+       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  simulta-
+       Note that fcntl(2) locks do not protect transactions  within  the  same
+       process  against each other.  If a program cannot avoid making simulta-
        neous database requests, then it must protect its transactions with in-
        process locks, in addition to the per-process fcntl(2) locks.
 
 <b>CONFIGURATION PARAMETERS</b>
-       Short-lived programs automatically pick up changes  to  <a href="postconf.5.html">main.cf</a>.   With
-       long-running  daemon programs, Use the command "<b>postfix reload</b>" after a
+       Short-lived  programs  automatically  pick up changes to <a href="postconf.5.html">main.cf</a>.  With
+       long-running daemon programs, Use the command "<b>postfix reload</b>" after  a
        configuration change.
 
        <b><a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> (default: 16777216)</b>
index 7ab1a945daccde66ebc0192beeee6ce848339b40..a56176bb1602a371c6a0c8dec8072c96fb469a2e 100644 (file)
@@ -152,6 +152,10 @@ SMTP(8)                                                                SMTP(8)
        <b><a href="postconf.5.html#smtp_never_send_ehlo">smtp_never_send_ehlo</a> (no)</b>
               Never send EHLO at the start of an SMTP session.
 
+       <b><a href="postconf.5.html#smtp_bounce_defer_filter">smtp_bounce_defer_filter</a> ($<a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a>)</b>
+              Optional  filter  to  change arbitrary hard delivery errors into
+              soft errors and vice versa.
+
        <b><a href="postconf.5.html#smtp_defer_if_no_mx_address_found">smtp_defer_if_no_mx_address_found</a> (no)</b>
               Defer mail delivery when no MX record resolves to an IP address.
 
@@ -160,8 +164,8 @@ SMTP(8)                                                                SMTP(8)
               will send via SMTP.
 
        <b><a href="postconf.5.html#smtp_pix_workaround_delay_time">smtp_pix_workaround_delay_time</a> (10s)</b>
-              How   long   the  Postfix  SMTP  client  pauses  before  sending
-              ".&lt;CR&gt;&lt;LF&gt;"  in  order  to  work   around   the   PIX   firewall
+              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.
 
        <b><a href="postconf.5.html#smtp_pix_workaround_threshold_time">smtp_pix_workaround_threshold_time</a> (500s)</b>
@@ -170,19 +174,19 @@ SMTP(8)                                                                SMTP(8)
               delivery through firewalls with "smtp fixup" mode turned on.
 
        <b><a href="postconf.5.html#smtp_pix_workarounds">smtp_pix_workarounds</a> (disable_esmtp, delay_dotcrlf)</b>
-              A  list  that  specifies  zero or more workarounds for CISCO PIX
+              A list that specifies zero or more  workarounds  for  CISCO  PIX
               firewall bugs.
 
        <b><a href="postconf.5.html#smtp_pix_workaround_maps">smtp_pix_workaround_maps</a> (empty)</b>
-              Lookup tables, indexed by the remote SMTP server  address,  with
+              Lookup  tables,  indexed by the remote SMTP server address, with
               per-destination workarounds for CISCO PIX firewall bugs.
 
        <b><a href="postconf.5.html#smtp_quote_rfc821_envelope">smtp_quote_rfc821_envelope</a> (yes)</b>
-              Quote  addresses  in  Postfix  SMTP client MAIL FROM and RCPT TO
+              Quote addresses in Postfix SMTP client MAIL  FROM  and  RCPT  TO
               commands as required by <a href="http://tools.ietf.org/html/rfc5321">RFC 5321</a>.
 
        <b><a href="postconf.5.html#smtp_reply_filter">smtp_reply_filter</a> (empty)</b>
-              A mechanism to transform replies from remote  SMTP  servers  one
+              A  mechanism  to  transform replies from remote SMTP servers one
               line at a time.
 
        <b><a href="postconf.5.html#smtp_skip_5xx_greeting">smtp_skip_5xx_greeting</a> (yes)</b>
@@ -194,68 +198,68 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.0 and earlier:
 
        <b><a href="postconf.5.html#smtp_skip_4xx_greeting">smtp_skip_4xx_greeting</a> (yes)</b>
-              Skip  SMTP  servers  that greet with a 4XX status code (go away,
+              Skip SMTP servers that greet with a 4XX status  code  (go  away,
               try again later).
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_discard_ehlo_keyword_address_maps">smtp_discard_ehlo_keyword_address_maps</a> (empty)</b>
-              Lookup tables, indexed by the remote SMTP server  address,  with
-              case  insensitive  lists of EHLO keywords (pipelining, starttls,
+              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.
 
        <b><a href="postconf.5.html#smtp_discard_ehlo_keywords">smtp_discard_ehlo_keywords</a> (empty)</b>
-              A  case insensitive list of EHLO keywords (pipelining, starttls,
+              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.
 
        <b><a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a> (empty)</b>
-              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
+              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.
 
        Available in Postfix version 2.2.9 and later:
 
        <b><a href="postconf.5.html#smtp_cname_overrides_servername">smtp_cname_overrides_servername</a> (version dependent)</b>
-              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
+              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.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#lmtp_discard_lhlo_keyword_address_maps">lmtp_discard_lhlo_keyword_address_maps</a> (empty)</b>
-              Lookup  tables,  indexed by the remote LMTP server address, with
-              case insensitive lists of LHLO keywords  (pipelining,  starttls,
+              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.
 
        <b><a href="postconf.5.html#lmtp_discard_lhlo_keywords">lmtp_discard_lhlo_keywords</a> (empty)</b>
-              A case insensitive list of LHLO keywords (pipelining,  starttls,
+              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.
 
        Available in Postfix version 2.4.4 and later:
 
        <b><a href="postconf.5.html#send_cyrus_sasl_authzid">send_cyrus_sasl_authzid</a> (no)</b>
-              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  auth-
+              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 auth-
               cid's password.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#smtp_header_checks">smtp_header_checks</a> (empty)</b>
-              Restricted  <a href="header_checks.5.html"><b>header_checks</b>(5)</a> tables for the Postfix SMTP client.
+              Restricted <a href="header_checks.5.html"><b>header_checks</b>(5)</a> tables for the Postfix SMTP  client.
 
        <b><a href="postconf.5.html#smtp_mime_header_checks">smtp_mime_header_checks</a> (empty)</b>
-              Restricted <b><a href="postconf.5.html#mime_header_checks">mime_header_checks</a></b>(5) tables  for  the  Postfix  SMTP
+              Restricted  <b><a href="postconf.5.html#mime_header_checks">mime_header_checks</a></b>(5)  tables  for  the Postfix SMTP
               client.
 
        <b><a href="postconf.5.html#smtp_nested_header_checks">smtp_nested_header_checks</a> (empty)</b>
-              Restricted  <b><a href="postconf.5.html#nested_header_checks">nested_header_checks</a></b>(5)  tables for the Postfix SMTP
+              Restricted <b><a href="postconf.5.html#nested_header_checks">nested_header_checks</a></b>(5) tables for the  Postfix  SMTP
               client.
 
        <b><a href="postconf.5.html#smtp_body_checks">smtp_body_checks</a> (empty)</b>
@@ -264,7 +268,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.6 and later:
 
        <b><a href="postconf.5.html#tcp_windowsize">tcp_windowsize</a> (0)</b>
-              An optional workaround for routers that break TCP  window  scal-
+              An  optional  workaround for routers that break TCP window scal-
               ing.
 
        Available in Postfix version 2.8 and later:
@@ -275,14 +279,14 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.9 and later:
 
        <b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
-              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  mes-
+              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 mes-
               sage).
 
        <b><a href="postconf.5.html#smtp_send_dummy_mail_auth">smtp_send_dummy_mail_auth</a> (no)</b>
-              Whether  or  not to append the "AUTH=&lt;&gt;" option to the MAIL FROM
+              Whether or not to append the "AUTH=&lt;&gt;" option to the  MAIL  FROM
               command in SASL-authenticated SMTP sessions.
 
        Available in Postfix version 2.11 and later:
@@ -306,7 +310,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_send_xforward_command">smtp_send_xforward_command</a> (no)</b>
-              Send  the  non-standard  XFORWARD  command when the Postfix SMTP
+              Send the non-standard XFORWARD command  when  the  Postfix  SMTP
               server EHLO response announces XFORWARD support.
 
 <b>SASL AUTHENTICATION CONTROLS</b>
@@ -314,62 +318,62 @@ SMTP(8)                                                                SMTP(8)
               Enable SASL authentication in the Postfix SMTP client.
 
        <b><a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> (empty)</b>
-              Optional Postfix  SMTP  client  lookup  tables  with  one  user-
-              name:password  entry  per  remote  hostname or domain, or sender
+              Optional  Postfix  SMTP  client  lookup  tables  with  one user-
+              name:password entry per remote hostname  or  domain,  or  sender
               address when sender-dependent authentication is enabled.
 
        <b><a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> (noplaintext, noanonymous)</b>
               Postfix SMTP client SASL security options; as of Postfix 2.3 the
-              list  of available features depends on the SASL client implemen-
+              list of available features depends on the SASL client  implemen-
               tation that is selected with <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> (empty)</b>
-              If non-empty, a Postfix SMTP client filter for the  remote  SMTP
+              If  non-empty,  a Postfix SMTP client filter for the remote SMTP
               server's list of offered SASL mechanisms.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> (no)</b>
               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 dif-
+              client;  this  is  available  only with SASL authentication, and
+              disables SMTP connection caching to ensure that mail  from  dif-
               ferent senders will use the appropriate credentials.
 
        <b><a href="postconf.5.html#smtp_sasl_path">smtp_sasl_path</a> (empty)</b>
               Implementation-specific information that the Postfix SMTP client
-              passes  through  to  the  SASL  plug-in  implementation  that is
+              passes through  to  the  SASL  plug-in  implementation  that  is
               selected with <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.
 
        <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a> (cyrus)</b>
-              The SASL plug-in type that the Postfix SMTP  client  should  use
+              The  SASL  plug-in  type that the Postfix SMTP client should use
               for authentication.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> (empty)</b>
-              An  optional table to prevent repeated SASL authentication fail-
-              ures with the same remote SMTP  server  hostname,  username  and
+              An optional table to prevent repeated SASL authentication  fail-
+              ures  with  the  same  remote SMTP server hostname, username and
               password.
 
        <b><a href="postconf.5.html#smtp_sasl_auth_cache_time">smtp_sasl_auth_cache_time</a> (90d)</b>
-              The  maximal age of an <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> entry before it
+              The maximal age of an <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> entry before  it
               is removed.
 
        <b><a href="postconf.5.html#smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a> (yes)</b>
-              When a remote SMTP server rejects a SASL authentication  request
-              with  a 535 reply code, defer mail delivery instead of returning
+              When  a remote SMTP server rejects a SASL authentication request
+              with a 535 reply code, defer mail delivery instead of  returning
               mail as undeliverable.
 
        Available in Postfix version 2.9 and later:
 
        <b><a href="postconf.5.html#smtp_send_dummy_mail_auth">smtp_send_dummy_mail_auth</a> (no)</b>
-              Whether or not to append the "AUTH=&lt;&gt;" option to the  MAIL  FROM
+              Whether  or  not to append the "AUTH=&lt;&gt;" option to the MAIL FROM
               command in SASL-authenticated SMTP sessions.
 
 <b>STARTTLS SUPPORT CONTROLS</b>
-       Detailed  information  about STARTTLS configuration may be found in the
+       Detailed information about STARTTLS configuration may be found  in  the
        <a href="TLS_README.html">TLS_README</a> document.
 
        <b><a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> (empty)</b>
@@ -379,20 +383,20 @@ SMTP(8)                                                                SMTP(8)
               <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>.
 
        <b><a href="postconf.5.html#smtp_sasl_tls_security_options">smtp_sasl_tls_security_options</a> ($<a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a>)</b>
-              The  SASL  authentication security options that the Postfix SMTP
+              The SASL authentication security options that the  Postfix  SMTP
               client uses for TLS encrypted SMTP sessions.
 
        <b><a href="postconf.5.html#smtp_starttls_timeout">smtp_starttls_timeout</a> (300s)</b>
-              Time limit for Postfix SMTP client  write  and  read  operations
+              Time  limit  for  Postfix  SMTP client write and read operations
               during TLS startup and shutdown handshake procedures.
 
        <b><a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> (empty)</b>
-              A  file  containing  CA certificates of root CAs trusted to sign
-              either remote SMTP server certificates or intermediate  CA  cer-
+              A file containing CA certificates of root CAs  trusted  to  sign
+              either  remote  SMTP server certificates or intermediate CA cer-
               tificates.
 
        <b><a href="postconf.5.html#smtp_tls_CApath">smtp_tls_CApath</a> (empty)</b>
-              Directory  with  PEM  format  certificate authority certificates
+              Directory with PEM  format  certificate  authority  certificates
               that the Postfix SMTP client uses to verify a remote SMTP server
               certificate.
 
@@ -400,7 +404,7 @@ SMTP(8)                                                                SMTP(8)
               File with the Postfix SMTP client RSA certificate in PEM format.
 
        <b><a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> (medium)</b>
-              The minimum TLS cipher grade that the Postfix SMTP  client  will
+              The  minimum  TLS cipher grade that the Postfix SMTP client will
               use with mandatory TLS encryption.
 
        <b><a href="postconf.5.html#smtp_tls_exclude_ciphers">smtp_tls_exclude_ciphers</a> (empty)</b>
@@ -408,8 +412,8 @@ SMTP(8)                                                                SMTP(8)
               client cipher list at all TLS security levels.
 
        <b><a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a> (empty)</b>
-              Additional list of ciphers or cipher types to exclude  from  the
-              Postfix  SMTP  client cipher list at mandatory TLS security lev-
+              Additional  list  of ciphers or cipher types to exclude from the
+              Postfix SMTP client cipher list at mandatory TLS  security  lev-
               els.
 
        <b><a href="postconf.5.html#smtp_tls_dcert_file">smtp_tls_dcert_file</a> (empty)</b>
@@ -425,7 +429,7 @@ SMTP(8)                                                                SMTP(8)
               Enable additional Postfix SMTP client logging of TLS activity.
 
        <b><a href="postconf.5.html#smtp_tls_note_starttls_offer">smtp_tls_note_starttls_offer</a> (no)</b>
-              Log  the  hostname of a remote SMTP server that offers STARTTLS,
+              Log the hostname of a remote SMTP server that  offers  STARTTLS,
               when TLS is not already enabled for that server.
 
        <b><a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> (empty)</b>
@@ -434,14 +438,14 @@ SMTP(8)                                                                SMTP(8)
               fied, this overrides the obsolete <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> parameter.
 
        <b><a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> (!SSLv2)</b>
-              List of SSL/TLS protocols that the Postfix SMTP client will  use
+              List  of SSL/TLS protocols that the Postfix SMTP client will use
               with mandatory TLS encryption.
 
        <b><a href="postconf.5.html#smtp_tls_scert_verifydepth">smtp_tls_scert_verifydepth</a> (9)</b>
               The verification depth for remote SMTP server certificates.
 
        <b><a href="postconf.5.html#smtp_tls_secure_cert_match">smtp_tls_secure_cert_match</a> (nexthop, dot-nexthop)</b>
-              How  the  Postfix  SMTP  client  verifies the server certificate
+              How the Postfix SMTP  client  verifies  the  server  certificate
               peername for the "secure" TLS security level.
 
        <b><a href="postconf.5.html#smtp_tls_session_cache_database">smtp_tls_session_cache_database</a> (empty)</b>
@@ -449,16 +453,16 @@ SMTP(8)                                                                SMTP(8)
               session cache.
 
        <b><a href="postconf.5.html#smtp_tls_session_cache_timeout">smtp_tls_session_cache_timeout</a> (3600s)</b>
-              The  expiration  time  of  Postfix SMTP client TLS session cache
+              The expiration time of Postfix SMTP  client  TLS  session  cache
               information.
 
        <b><a href="postconf.5.html#smtp_tls_verify_cert_match">smtp_tls_verify_cert_match</a> (hostname)</b>
-              How the Postfix SMTP  client  verifies  the  server  certificate
+              How  the  Postfix  SMTP  client  verifies the server certificate
               peername for the "verify" TLS security level.
 
        <b><a href="postconf.5.html#tls_daemon_random_bytes">tls_daemon_random_bytes</a> (32)</b>
-              The  number  of  pseudo-random bytes that an <a href="smtp.8.html"><b>smtp</b>(8)</a> or <a href="smtpd.8.html"><b>smtpd</b>(8)</a>
-              process requests from the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> server in order to seed  its
+              The number of pseudo-random bytes that an  <a href="smtp.8.html"><b>smtp</b>(8)</a>  or  <a href="smtpd.8.html"><b>smtpd</b>(8)</a>
+              process  requests from the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> server in order to seed its
               internal pseudo random number generator (PRNG).
 
        <b><a href="postconf.5.html#tls_high_cipherlist">tls_high_cipherlist</a> (ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH)</b>
@@ -474,52 +478,52 @@ SMTP(8)                                                                SMTP(8)
               The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
 
        <b><a href="postconf.5.html#tls_null_cipherlist">tls_null_cipherlist</a> (eNULL:!aNULL)</b>
-              The  OpenSSL  cipherlist  for  "NULL" grade ciphers that provide
+              The OpenSSL cipherlist for "NULL"  grade  ciphers  that  provide
               authentication without encryption.
 
        Available in Postfix version 2.4 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_tls_verified_security_options">smtp_sasl_tls_verified_security_options</a>           ($<a href="postconf.5.html#smtp_sasl_tls_security_options">smtp_sasl_tls_secu</a>-</b>
        <b><a href="postconf.5.html#smtp_sasl_tls_security_options">rity_options</a>)</b>
-              The SASL authentication security options that the  Postfix  SMTP
-              client  uses  for  TLS  encrypted  SMTP sessions with a verified
+              The  SASL  authentication security options that the Postfix SMTP
+              client uses for TLS encrypted  SMTP  sessions  with  a  verified
               server certificate.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a> (empty)</b>
-              List of acceptable remote SMTP server  certificate  fingerprints
-              for   the   "fingerprint"  TLS  security  level  (<b><a href="postconf.5.html#smtp_tls_security_level">smtp_tls_secu</a>-</b>
+              List  of  acceptable remote SMTP server certificate fingerprints
+              for  the  "fingerprint"  TLS  security   level   (<b><a href="postconf.5.html#smtp_tls_security_level">smtp_tls_secu</a>-</b>
               <b><a href="postconf.5.html#smtp_tls_security_level">rity_level</a></b> = fingerprint).
 
        <b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> (md5)</b>
-              The message digest  algorithm  used  to  construct  remote  SMTP
+              The  message  digest  algorithm  used  to  construct remote SMTP
               server certificate fingerprints.
 
        Available in Postfix version 2.6 and later:
 
        <b><a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a> (!SSLv2)</b>
-              List  of TLS protocols that the Postfix SMTP client will exclude
+              List of TLS protocols that the Postfix SMTP client will  exclude
               or include with opportunistic TLS encryption.
 
        <b><a href="postconf.5.html#smtp_tls_ciphers">smtp_tls_ciphers</a> (export)</b>
-              The minimum TLS cipher grade that the Postfix SMTP  client  will
+              The  minimum  TLS cipher grade that the Postfix SMTP client will
               use with opportunistic TLS encryption.
 
        <b><a href="postconf.5.html#smtp_tls_eccert_file">smtp_tls_eccert_file</a> (empty)</b>
-              File  with the Postfix SMTP client ECDSA certificate in PEM for-
+              File with the Postfix SMTP client ECDSA certificate in PEM  for-
               mat.
 
        <b><a href="postconf.5.html#smtp_tls_eckey_file">smtp_tls_eckey_file</a> ($<a href="postconf.5.html#smtp_tls_eccert_file">smtp_tls_eccert_file</a>)</b>
-              File with the Postfix SMTP client ECDSA private key in PEM  for-
+              File  with the Postfix SMTP client ECDSA private key in PEM for-
               mat.
 
        Available in Postfix version 2.7 and later:
 
        <b><a href="postconf.5.html#smtp_tls_block_early_mail_reply">smtp_tls_block_early_mail_reply</a> (no)</b>
-              Try  to  detect  a mail hijacking attack based on a TLS protocol
-              vulnerability (CVE-2009-3555), where an attacker prepends  mali-
-              cious  HELO,  MAIL, RCPT, DATA commands to a Postfix SMTP client
+              Try to detect a mail hijacking attack based on  a  TLS  protocol
+              vulnerability  (CVE-2009-3555), where an attacker prepends mali-
+              cious HELO, MAIL, RCPT, DATA commands to a Postfix  SMTP  client
               TLS session.
 
        Available in Postfix version 2.8 and later:
@@ -530,11 +534,11 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.11 and later:
 
        <b><a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a> (empty)</b>
-              Zero or more PEM-format  files  with  trust-anchor  certificates
+              Zero  or  more  PEM-format  files with trust-anchor certificates
               and/or public keys.
 
        <b><a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">smtp_tls_force_insecure_host_tlsa_lookup</a> (no)</b>
-              Lookup  the  associated  DANE TLSA RRset even when a hostname is
+              Lookup the associated DANE TLSA RRset even when  a  hostname  is
               not an alias and its address records lie in an unsigned zone.
 
        <b><a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> (yes)</b>
@@ -544,49 +548,49 @@ SMTP(8)                                                                SMTP(8)
               The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in <a href="master.5.html">master.cf</a>.
 
 <b>OBSOLETE STARTTLS CONTROLS</b>
-       The  following  configuration  parameters  exist for compatibility with
-       Postfix versions before 2.3. Support for these will  be  removed  in  a
+       The following configuration parameters  exist  for  compatibility  with
+       Postfix  versions  before  2.3.  Support for these will be removed in a
        future release.
 
        <b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
-              Opportunistic  mode: use TLS when a remote SMTP server announces
+              Opportunistic mode: use TLS when a remote SMTP server  announces
               STARTTLS support, otherwise send the mail in the clear.
 
        <b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
-              Enforcement mode: require  that  remote  SMTP  servers  use  TLS
+              Enforcement  mode:  require  that  remote  SMTP  servers use TLS
               encryption, and never send mail in the clear.
 
        <b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
-              With  mandatory  TLS  encryption,  require  that the remote SMTP
-              server hostname matches  the  information  in  the  remote  SMTP
+              With mandatory TLS encryption,  require  that  the  remote  SMTP
+              server  hostname  matches  the  information  in  the remote SMTP
               server certificate.
 
        <b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
-              Optional  lookup  tables  with the Postfix SMTP client TLS usage
-              policy by next-hop destination and by remote SMTP  server  host-
+              Optional lookup tables with the Postfix SMTP  client  TLS  usage
+              policy  by  next-hop destination and by remote SMTP server host-
               name.
 
        <b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
-              Obsolete  Postfix  &lt; 2.3 control for the Postfix SMTP client TLS
+              Obsolete Postfix &lt; 2.3 control for the Postfix SMTP  client  TLS
               cipher list.
 
 <b>RESOURCE AND RATE CONTROLS</b>
        <b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a>        ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
-              The maximal number of parallel deliveries to the  same  destina-
+              The  maximal  number of parallel deliveries to the same destina-
               tion via the smtp message delivery transport.
 
        <b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a> ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipient_limit</a>)</b>
-              The  maximal  number of recipients per message for the smtp mes-
+              The maximal number of recipients per message for the  smtp  mes-
               sage delivery transport.
 
        <b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
-              The Postfix SMTP client time limit for completing a TCP  connec-
+              The  Postfix SMTP client time limit for completing a TCP connec-
               tion, or zero (use the operating system built-in time limit).
 
        <b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
-              The  Postfix SMTP client time limit for sending the HELO or EHLO
-              command, and  for  receiving  the  initial  remote  SMTP  server
+              The Postfix SMTP client time limit for sending the HELO or  EHLO
+              command,  and  for  receiving  the  initial  remote  SMTP server
               response.
 
        <b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
@@ -598,19 +602,19 @@ SMTP(8)                                                                SMTP(8)
               mand, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
-              The  Postfix  SMTP  client  time limit for sending the MAIL FROM
+              The Postfix SMTP client time limit for  sending  the  MAIL  FROM
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
-              The Postfix SMTP client time limit for sending the SMTP RCPT  TO
+              The  Postfix SMTP client time limit for sending the SMTP RCPT TO
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
-              The  Postfix  SMTP  client  time limit for sending the SMTP DATA
+              The Postfix SMTP client time limit for  sending  the  SMTP  DATA
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
-              The Postfix SMTP client time limit for sending the SMTP  message
+              The  Postfix SMTP client time limit for sending the SMTP message
               content.
 
        <b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
@@ -624,13 +628,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> (5)</b>
-              The  maximal number of MX (mail exchanger) IP addresses that can
-              result from Postfix SMTP client mail exchanger lookups, or  zero
+              The maximal number of MX (mail exchanger) IP addresses that  can
+              result  from Postfix SMTP client mail exchanger lookups, or zero
               (no limit).
 
        <b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
-              The  maximal number of SMTP sessions per delivery request before
-              the Postfix SMTP client gives up  or  delivers  to  a  fall-back
+              The maximal number of SMTP sessions per delivery request  before
+              the  Postfix  SMTP  client  gives  up or delivers to a fall-back
               <a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
@@ -640,17 +644,17 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.2 and earlier:
 
        <b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
-              Keep Postfix LMTP client connections open for  up  to  $<a href="postconf.5.html#max_idle">max_idle</a>
+              Keep  Postfix  LMTP  client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
               seconds.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently  enable  SMTP  connection  caching for the specified
+              Permanently enable SMTP connection  caching  for  the  specified
               destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily enable SMTP connection caching while  a  destination
+              Temporarily  enable  SMTP connection caching while a destination
               has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
 
        <b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
@@ -664,37 +668,37 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
-              Time  limit for connection cache connect, send or receive opera-
+              Time limit for connection cache connect, send or receive  opera-
               tions.
 
        Available in Postfix version 2.9 and later:
 
        <b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
-              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 mes-
+              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  mes-
               sage).
 
        Available in Postfix version 2.11 and later:
 
        <b><a href="postconf.5.html#smtp_connection_reuse_count_limit">smtp_connection_reuse_count_limit</a> (0)</b>
-              When SMTP connection caching is enabled,  the  number  of  times
-              that  an SMTP session may be reused before it is closed, or zero
+              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).
 
 <b>TROUBLE SHOOTING CONTROLS</b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The increment in verbose logging level when a remote  client  or
+              The  increment  in verbose logging level when a remote client or
               server matches a pattern in the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
 
        <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional  list  of  remote  client or server hostname or network
+              Optional list of remote client or  server  hostname  or  network
               address  patterns  that  cause  the  verbose  logging  level  to
               increase by the amount specified in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
 
        <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The  recipient  of  postmaster notifications about mail delivery
+              The recipient of postmaster notifications  about  mail  delivery
               problems that are caused by policy, resource, software or proto-
               col errors.
 
@@ -708,46 +712,46 @@ SMTP(8)                                                                SMTP(8)
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
-              Where  the  Postfix  SMTP  client  should  deliver  mail when it
+              Where the Postfix  SMTP  client  should  deliver  mail  when  it
               detects a "mail loops back to myself" error condition.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The default location of the Postfix <a href="postconf.5.html">main.cf</a> and  <a href="master.5.html">master.cf</a>  con-
+              The  default  location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
               figuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How  much  time  a  Postfix  daemon process may take to handle a
+              How much time a Postfix daemon process  may  take  to  handle  a
               request before it is terminated by a built-in watchdog timer.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The maximal number of digits after the decimal point  when  log-
+              The  maximal  number of digits after the decimal point when log-
               ging sub-second delay values.
 
        <b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
               Disable DNS lookups in the Postfix SMTP and LMTP clients.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The  network  interface addresses that this mail system receives
+              The network interface addresses that this mail  system  receives
               mail on.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (all)</b>
-              The Internet protocols Postfix will attempt to use  when  making
+              The  Internet  protocols Postfix will attempt to use when making
               or accepting connections.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
-              The  time  limit  for  sending  or receiving information over an
+              The time limit for sending  or  receiving  information  over  an
               internal communication channel.
 
        <b><a href="postconf.5.html#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
-              When a remote LMTP server announces no DSN support, assume  that
-              the  server performs final delivery, and send "delivered" deliv-
+              When  a remote LMTP server announces no DSN support, assume that
+              the server performs final delivery, and send "delivered"  deliv-
               ery status notifications instead of "relayed".
 
        <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
               The default TCP port that the Postfix LMTP client connects to.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The maximum amount of time that an idle Postfix  daemon  process
+              The  maximum  amount of time that an idle Postfix daemon process
               waits for an incoming connection before terminating voluntarily.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
@@ -761,20 +765,20 @@ SMTP(8)                                                                SMTP(8)
               The process name of a Postfix command or daemon process.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The  network  interface addresses that this mail system receives
+              The network interface addresses that this mail  system  receives
               mail on by way of a proxy or network address translation unit.
 
        <b><a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> (any)</b>
               The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP
-              client  will  try  first,  when  a destination has IPv6 and IPv4
+              client will try first, when a  destination  has  IPv6  and  IPv4
               addresses with equal MX preference.
 
        <b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
-              An optional numerical network  address  that  the  Postfix  SMTP
+              An  optional  numerical  network  address  that the Postfix SMTP
               client should bind to when making an IPv4 connection.
 
        <b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
-              An  optional  numerical  network  address  that the Postfix SMTP
+              An optional numerical network  address  that  the  Postfix  SMTP
               client should bind to when making an IPv6 connection.
 
        <b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
@@ -794,8 +798,8 @@ SMTP(8)                                                                SMTP(8)
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              The  mail  system  name that is prepended to the process name in
-              syslog records, so that "smtpd"  becomes,  for  example,  "post-
+              The mail system name that is prepended to the  process  name  in
+              syslog  records,  so  that  "smtpd" becomes, for example, "post-
               fix/smtpd".
 
        Available with Postfix 2.2 and earlier:
index d37e870ddd6aa151714105ee3bfc96183de0a610..d3db13d00e0ceb13608ebf5d088b8da8fb704d4d 100644 (file)
@@ -425,6 +425,10 @@ PIPE(8)                                                                PIPE(8)
               The maximal number of incoming connections that a Postfix daemon
               process will service before terminating voluntarily.
 
+       <b><a href="postconf.5.html#pipe_bounce_defer_filter">pipe_bounce_defer_filter</a> ($<a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a>)</b>
+              Optional  filter  to  change arbitrary hard delivery errors into
+              soft errors and vice versa.
+
        <b><a href="postconf.5.html#process_id">process_id</a> (read-only)</b>
               The process ID of a Postfix command or daemon process.
 
@@ -435,16 +439,16 @@ PIPE(8)                                                                PIPE(8)
               The location of the Postfix top-level queue directory.
 
        <b><a href="postconf.5.html#recipient_delimiter">recipient_delimiter</a> (empty)</b>
-              The  set  of  characters  that can separate a user name from its
-              extension (example: user+foo), or a .forward file name from  its
+              The set of characters that can separate a  user  name  from  its
+              extension  (example: user+foo), or a .forward file name from its
               extension (example: .forward+foo).
 
        <b><a href="postconf.5.html#syslog_facility">syslog_facility</a> (mail)</b>
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              The  mail  system  name that is prepended to the process name in
-              syslog records, so that "smtpd"  becomes,  for  example,  "post-
+              The mail system name that is prepended to the  process  name  in
+              syslog  records,  so  that  "smtpd" becomes, for example, "post-
               fix/smtpd".
 
 <b>SEE ALSO</b>
index 2f40f954175581480aa61124343f322c56dae580..a4cf45faa877a27e24005eb2f72c80eb453f5f10 100644 (file)
@@ -1756,6 +1756,74 @@ Example:
 </pre>
 
 
+</DD>
+
+<DT><b><a name="default_bounce_defer_filter">default_bounce_defer_filter</a>
+(default: empty)</b></DT><DD>
+
+<p> Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa.  This is implemented by rewriting the
+three-number enhanced status code and the explanatory text in a
+Postfix delivery agent bounce/defer message. </p>
+
+<p> Specify zero or more "<a href="DATABASE_README.html">type:table</a>" lookup table names, separated
+by comma or whitespace. With each bounce or defer request, 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:  enhanced status codes must have a
+first numerical field of 4 (defer) or 5 (bounce), and the explanatory
+text field must be non-empty. Other results will result in a warning.
+</p>
+
+<p> Example: </p>
+
+<p> The following example turns specific soft TLS errors into hard
+errors, by overriding the first number in the enhanced status code.
+</p>
+
+<blockquote>
+<pre>
+/etc/postfix/<a href="postconf.5.html">main.cf</a>:
+    <a href="postconf.5.html#smtp_bounce_defer_filter">smtp_bounce_defer_filter</a> = <a href="pcre_table.5.html">pcre</a>:/etc/postfix/smtp_ndr_filter
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/smtp_ndr_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> Notes: </p>
+
+<ul>
+
+<li> <p> This feature will NOT override the <a href="postconf.5.html#soft_bounce">soft_bounce</a> 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. </p>
+
+</ul>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="default_database_type">default_database_type</a>
@@ -3852,6 +3920,17 @@ parameter. See there for details. </p>
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="lmtp_bounce_defer_filter">lmtp_bounce_defer_filter</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_bounce_defer_filter">smtp_bounce_defer_filter</a>
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="lmtp_cache_connection">lmtp_cache_connection</a>
@@ -6920,6 +6999,18 @@ This feature is available in Postfix 2.0 and later.
 </p>
 
 
+</DD>
+
+<DT><b><a name="pipe_bounce_defer_filter">pipe_bounce_defer_filter</a>
+(default: $<a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a>)</b></DT><DD>
+
+<p> Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See <a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a> for
+details.  </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="plaintext_reject_code">plaintext_reject_code</a>
@@ -9485,6 +9576,22 @@ that change the delivery time or destination are not available.
 <p> This feature is available in Postfix 2.5 and later. </p>
 
 
+</DD>
+
+<DT><b><a name="smtp_bounce_defer_filter">smtp_bounce_defer_filter</a>
+(default: $<a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a>)</b></DT><DD>
+
+<p> Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See <a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a> for
+details.  </p>
+
+<p> NOTE: This feature modifies error messages that are generated
+by the Postfix SMTP client, and that may or may not be derived from
+remote SMTP server responses.  In contrast, the <a href="postconf.5.html#smtp_reply_filter">smtp_reply_filter</a>
+feature modifies remote SMTP server responses that may result in
+email non-delivery or delivery. </p>
+
+
 </DD>
 
 <DT><b><a name="smtp_cname_overrides_servername">smtp_cname_overrides_servername</a>
@@ -18098,6 +18205,18 @@ This feature is available in Postfix 2.1 and later.
 </p>
 
 
+</DD>
+
+<DT><b><a name="virtual_bounce_defer_filter">virtual_bounce_defer_filter</a>
+(default: $<a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a>)</b></DT><DD>
+
+<p> Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See <a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a> for
+details.  </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="virtual_destination_concurrency_limit">virtual_destination_concurrency_limit</a>
index 7ab1a945daccde66ebc0192beeee6ce848339b40..a56176bb1602a371c6a0c8dec8072c96fb469a2e 100644 (file)
@@ -152,6 +152,10 @@ SMTP(8)                                                                SMTP(8)
        <b><a href="postconf.5.html#smtp_never_send_ehlo">smtp_never_send_ehlo</a> (no)</b>
               Never send EHLO at the start of an SMTP session.
 
+       <b><a href="postconf.5.html#smtp_bounce_defer_filter">smtp_bounce_defer_filter</a> ($<a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a>)</b>
+              Optional  filter  to  change arbitrary hard delivery errors into
+              soft errors and vice versa.
+
        <b><a href="postconf.5.html#smtp_defer_if_no_mx_address_found">smtp_defer_if_no_mx_address_found</a> (no)</b>
               Defer mail delivery when no MX record resolves to an IP address.
 
@@ -160,8 +164,8 @@ SMTP(8)                                                                SMTP(8)
               will send via SMTP.
 
        <b><a href="postconf.5.html#smtp_pix_workaround_delay_time">smtp_pix_workaround_delay_time</a> (10s)</b>
-              How   long   the  Postfix  SMTP  client  pauses  before  sending
-              ".&lt;CR&gt;&lt;LF&gt;"  in  order  to  work   around   the   PIX   firewall
+              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.
 
        <b><a href="postconf.5.html#smtp_pix_workaround_threshold_time">smtp_pix_workaround_threshold_time</a> (500s)</b>
@@ -170,19 +174,19 @@ SMTP(8)                                                                SMTP(8)
               delivery through firewalls with "smtp fixup" mode turned on.
 
        <b><a href="postconf.5.html#smtp_pix_workarounds">smtp_pix_workarounds</a> (disable_esmtp, delay_dotcrlf)</b>
-              A  list  that  specifies  zero or more workarounds for CISCO PIX
+              A list that specifies zero or more  workarounds  for  CISCO  PIX
               firewall bugs.
 
        <b><a href="postconf.5.html#smtp_pix_workaround_maps">smtp_pix_workaround_maps</a> (empty)</b>
-              Lookup tables, indexed by the remote SMTP server  address,  with
+              Lookup  tables,  indexed by the remote SMTP server address, with
               per-destination workarounds for CISCO PIX firewall bugs.
 
        <b><a href="postconf.5.html#smtp_quote_rfc821_envelope">smtp_quote_rfc821_envelope</a> (yes)</b>
-              Quote  addresses  in  Postfix  SMTP client MAIL FROM and RCPT TO
+              Quote addresses in Postfix SMTP client MAIL  FROM  and  RCPT  TO
               commands as required by <a href="http://tools.ietf.org/html/rfc5321">RFC 5321</a>.
 
        <b><a href="postconf.5.html#smtp_reply_filter">smtp_reply_filter</a> (empty)</b>
-              A mechanism to transform replies from remote  SMTP  servers  one
+              A  mechanism  to  transform replies from remote SMTP servers one
               line at a time.
 
        <b><a href="postconf.5.html#smtp_skip_5xx_greeting">smtp_skip_5xx_greeting</a> (yes)</b>
@@ -194,68 +198,68 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.0 and earlier:
 
        <b><a href="postconf.5.html#smtp_skip_4xx_greeting">smtp_skip_4xx_greeting</a> (yes)</b>
-              Skip  SMTP  servers  that greet with a 4XX status code (go away,
+              Skip SMTP servers that greet with a 4XX status  code  (go  away,
               try again later).
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_discard_ehlo_keyword_address_maps">smtp_discard_ehlo_keyword_address_maps</a> (empty)</b>
-              Lookup tables, indexed by the remote SMTP server  address,  with
-              case  insensitive  lists of EHLO keywords (pipelining, starttls,
+              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.
 
        <b><a href="postconf.5.html#smtp_discard_ehlo_keywords">smtp_discard_ehlo_keywords</a> (empty)</b>
-              A  case insensitive list of EHLO keywords (pipelining, starttls,
+              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.
 
        <b><a href="postconf.5.html#smtp_generic_maps">smtp_generic_maps</a> (empty)</b>
-              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
+              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.
 
        Available in Postfix version 2.2.9 and later:
 
        <b><a href="postconf.5.html#smtp_cname_overrides_servername">smtp_cname_overrides_servername</a> (version dependent)</b>
-              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
+              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.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#lmtp_discard_lhlo_keyword_address_maps">lmtp_discard_lhlo_keyword_address_maps</a> (empty)</b>
-              Lookup  tables,  indexed by the remote LMTP server address, with
-              case insensitive lists of LHLO keywords  (pipelining,  starttls,
+              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.
 
        <b><a href="postconf.5.html#lmtp_discard_lhlo_keywords">lmtp_discard_lhlo_keywords</a> (empty)</b>
-              A case insensitive list of LHLO keywords (pipelining,  starttls,
+              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.
 
        Available in Postfix version 2.4.4 and later:
 
        <b><a href="postconf.5.html#send_cyrus_sasl_authzid">send_cyrus_sasl_authzid</a> (no)</b>
-              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  auth-
+              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 auth-
               cid's password.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#smtp_header_checks">smtp_header_checks</a> (empty)</b>
-              Restricted  <a href="header_checks.5.html"><b>header_checks</b>(5)</a> tables for the Postfix SMTP client.
+              Restricted <a href="header_checks.5.html"><b>header_checks</b>(5)</a> tables for the Postfix SMTP  client.
 
        <b><a href="postconf.5.html#smtp_mime_header_checks">smtp_mime_header_checks</a> (empty)</b>
-              Restricted <b><a href="postconf.5.html#mime_header_checks">mime_header_checks</a></b>(5) tables  for  the  Postfix  SMTP
+              Restricted  <b><a href="postconf.5.html#mime_header_checks">mime_header_checks</a></b>(5)  tables  for  the Postfix SMTP
               client.
 
        <b><a href="postconf.5.html#smtp_nested_header_checks">smtp_nested_header_checks</a> (empty)</b>
-              Restricted  <b><a href="postconf.5.html#nested_header_checks">nested_header_checks</a></b>(5)  tables for the Postfix SMTP
+              Restricted <b><a href="postconf.5.html#nested_header_checks">nested_header_checks</a></b>(5) tables for the  Postfix  SMTP
               client.
 
        <b><a href="postconf.5.html#smtp_body_checks">smtp_body_checks</a> (empty)</b>
@@ -264,7 +268,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.6 and later:
 
        <b><a href="postconf.5.html#tcp_windowsize">tcp_windowsize</a> (0)</b>
-              An optional workaround for routers that break TCP  window  scal-
+              An  optional  workaround for routers that break TCP window scal-
               ing.
 
        Available in Postfix version 2.8 and later:
@@ -275,14 +279,14 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.9 and later:
 
        <b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
-              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  mes-
+              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 mes-
               sage).
 
        <b><a href="postconf.5.html#smtp_send_dummy_mail_auth">smtp_send_dummy_mail_auth</a> (no)</b>
-              Whether  or  not to append the "AUTH=&lt;&gt;" option to the MAIL FROM
+              Whether or not to append the "AUTH=&lt;&gt;" option to the  MAIL  FROM
               command in SASL-authenticated SMTP sessions.
 
        Available in Postfix version 2.11 and later:
@@ -306,7 +310,7 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_send_xforward_command">smtp_send_xforward_command</a> (no)</b>
-              Send  the  non-standard  XFORWARD  command when the Postfix SMTP
+              Send the non-standard XFORWARD command  when  the  Postfix  SMTP
               server EHLO response announces XFORWARD support.
 
 <b>SASL AUTHENTICATION CONTROLS</b>
@@ -314,62 +318,62 @@ SMTP(8)                                                                SMTP(8)
               Enable SASL authentication in the Postfix SMTP client.
 
        <b><a href="postconf.5.html#smtp_sasl_password_maps">smtp_sasl_password_maps</a> (empty)</b>
-              Optional Postfix  SMTP  client  lookup  tables  with  one  user-
-              name:password  entry  per  remote  hostname or domain, or sender
+              Optional  Postfix  SMTP  client  lookup  tables  with  one user-
+              name:password entry per remote hostname  or  domain,  or  sender
               address when sender-dependent authentication is enabled.
 
        <b><a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a> (noplaintext, noanonymous)</b>
               Postfix SMTP client SASL security options; as of Postfix 2.3 the
-              list  of available features depends on the SASL client implemen-
+              list of available features depends on the SASL client  implemen-
               tation that is selected with <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_mechanism_filter">smtp_sasl_mechanism_filter</a> (empty)</b>
-              If non-empty, a Postfix SMTP client filter for the  remote  SMTP
+              If  non-empty,  a Postfix SMTP client filter for the remote SMTP
               server's list of offered SASL mechanisms.
 
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#smtp_sender_dependent_authentication">smtp_sender_dependent_authentication</a> (no)</b>
               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 dif-
+              client;  this  is  available  only with SASL authentication, and
+              disables SMTP connection caching to ensure that mail  from  dif-
               ferent senders will use the appropriate credentials.
 
        <b><a href="postconf.5.html#smtp_sasl_path">smtp_sasl_path</a> (empty)</b>
               Implementation-specific information that the Postfix SMTP client
-              passes  through  to  the  SASL  plug-in  implementation  that is
+              passes through  to  the  SASL  plug-in  implementation  that  is
               selected with <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a></b>.
 
        <b><a href="postconf.5.html#smtp_sasl_type">smtp_sasl_type</a> (cyrus)</b>
-              The SASL plug-in type that the Postfix SMTP  client  should  use
+              The  SASL  plug-in  type that the Postfix SMTP client should use
               for authentication.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> (empty)</b>
-              An  optional table to prevent repeated SASL authentication fail-
-              ures with the same remote SMTP  server  hostname,  username  and
+              An optional table to prevent repeated SASL authentication  fail-
+              ures  with  the  same  remote SMTP server hostname, username and
               password.
 
        <b><a href="postconf.5.html#smtp_sasl_auth_cache_time">smtp_sasl_auth_cache_time</a> (90d)</b>
-              The  maximal age of an <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> entry before it
+              The maximal age of an <a href="postconf.5.html#smtp_sasl_auth_cache_name">smtp_sasl_auth_cache_name</a> entry before  it
               is removed.
 
        <b><a href="postconf.5.html#smtp_sasl_auth_soft_bounce">smtp_sasl_auth_soft_bounce</a> (yes)</b>
-              When a remote SMTP server rejects a SASL authentication  request
-              with  a 535 reply code, defer mail delivery instead of returning
+              When  a remote SMTP server rejects a SASL authentication request
+              with a 535 reply code, defer mail delivery instead of  returning
               mail as undeliverable.
 
        Available in Postfix version 2.9 and later:
 
        <b><a href="postconf.5.html#smtp_send_dummy_mail_auth">smtp_send_dummy_mail_auth</a> (no)</b>
-              Whether or not to append the "AUTH=&lt;&gt;" option to the  MAIL  FROM
+              Whether  or  not to append the "AUTH=&lt;&gt;" option to the MAIL FROM
               command in SASL-authenticated SMTP sessions.
 
 <b>STARTTLS SUPPORT CONTROLS</b>
-       Detailed  information  about STARTTLS configuration may be found in the
+       Detailed information about STARTTLS configuration may be found  in  the
        <a href="TLS_README.html">TLS_README</a> document.
 
        <b><a href="postconf.5.html#smtp_tls_security_level">smtp_tls_security_level</a> (empty)</b>
@@ -379,20 +383,20 @@ SMTP(8)                                                                SMTP(8)
               <a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a>.
 
        <b><a href="postconf.5.html#smtp_sasl_tls_security_options">smtp_sasl_tls_security_options</a> ($<a href="postconf.5.html#smtp_sasl_security_options">smtp_sasl_security_options</a>)</b>
-              The  SASL  authentication security options that the Postfix SMTP
+              The SASL authentication security options that the  Postfix  SMTP
               client uses for TLS encrypted SMTP sessions.
 
        <b><a href="postconf.5.html#smtp_starttls_timeout">smtp_starttls_timeout</a> (300s)</b>
-              Time limit for Postfix SMTP client  write  and  read  operations
+              Time  limit  for  Postfix  SMTP client write and read operations
               during TLS startup and shutdown handshake procedures.
 
        <b><a href="postconf.5.html#smtp_tls_CAfile">smtp_tls_CAfile</a> (empty)</b>
-              A  file  containing  CA certificates of root CAs trusted to sign
-              either remote SMTP server certificates or intermediate  CA  cer-
+              A file containing CA certificates of root CAs  trusted  to  sign
+              either  remote  SMTP server certificates or intermediate CA cer-
               tificates.
 
        <b><a href="postconf.5.html#smtp_tls_CApath">smtp_tls_CApath</a> (empty)</b>
-              Directory  with  PEM  format  certificate authority certificates
+              Directory with PEM  format  certificate  authority  certificates
               that the Postfix SMTP client uses to verify a remote SMTP server
               certificate.
 
@@ -400,7 +404,7 @@ SMTP(8)                                                                SMTP(8)
               File with the Postfix SMTP client RSA certificate in PEM format.
 
        <b><a href="postconf.5.html#smtp_tls_mandatory_ciphers">smtp_tls_mandatory_ciphers</a> (medium)</b>
-              The minimum TLS cipher grade that the Postfix SMTP  client  will
+              The  minimum  TLS cipher grade that the Postfix SMTP client will
               use with mandatory TLS encryption.
 
        <b><a href="postconf.5.html#smtp_tls_exclude_ciphers">smtp_tls_exclude_ciphers</a> (empty)</b>
@@ -408,8 +412,8 @@ SMTP(8)                                                                SMTP(8)
               client cipher list at all TLS security levels.
 
        <b><a href="postconf.5.html#smtp_tls_mandatory_exclude_ciphers">smtp_tls_mandatory_exclude_ciphers</a> (empty)</b>
-              Additional list of ciphers or cipher types to exclude  from  the
-              Postfix  SMTP  client cipher list at mandatory TLS security lev-
+              Additional  list  of ciphers or cipher types to exclude from the
+              Postfix SMTP client cipher list at mandatory TLS  security  lev-
               els.
 
        <b><a href="postconf.5.html#smtp_tls_dcert_file">smtp_tls_dcert_file</a> (empty)</b>
@@ -425,7 +429,7 @@ SMTP(8)                                                                SMTP(8)
               Enable additional Postfix SMTP client logging of TLS activity.
 
        <b><a href="postconf.5.html#smtp_tls_note_starttls_offer">smtp_tls_note_starttls_offer</a> (no)</b>
-              Log  the  hostname of a remote SMTP server that offers STARTTLS,
+              Log the hostname of a remote SMTP server that  offers  STARTTLS,
               when TLS is not already enabled for that server.
 
        <b><a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> (empty)</b>
@@ -434,14 +438,14 @@ SMTP(8)                                                                SMTP(8)
               fied, this overrides the obsolete <a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> parameter.
 
        <b><a href="postconf.5.html#smtp_tls_mandatory_protocols">smtp_tls_mandatory_protocols</a> (!SSLv2)</b>
-              List of SSL/TLS protocols that the Postfix SMTP client will  use
+              List  of SSL/TLS protocols that the Postfix SMTP client will use
               with mandatory TLS encryption.
 
        <b><a href="postconf.5.html#smtp_tls_scert_verifydepth">smtp_tls_scert_verifydepth</a> (9)</b>
               The verification depth for remote SMTP server certificates.
 
        <b><a href="postconf.5.html#smtp_tls_secure_cert_match">smtp_tls_secure_cert_match</a> (nexthop, dot-nexthop)</b>
-              How  the  Postfix  SMTP  client  verifies the server certificate
+              How the Postfix SMTP  client  verifies  the  server  certificate
               peername for the "secure" TLS security level.
 
        <b><a href="postconf.5.html#smtp_tls_session_cache_database">smtp_tls_session_cache_database</a> (empty)</b>
@@ -449,16 +453,16 @@ SMTP(8)                                                                SMTP(8)
               session cache.
 
        <b><a href="postconf.5.html#smtp_tls_session_cache_timeout">smtp_tls_session_cache_timeout</a> (3600s)</b>
-              The  expiration  time  of  Postfix SMTP client TLS session cache
+              The expiration time of Postfix SMTP  client  TLS  session  cache
               information.
 
        <b><a href="postconf.5.html#smtp_tls_verify_cert_match">smtp_tls_verify_cert_match</a> (hostname)</b>
-              How the Postfix SMTP  client  verifies  the  server  certificate
+              How  the  Postfix  SMTP  client  verifies the server certificate
               peername for the "verify" TLS security level.
 
        <b><a href="postconf.5.html#tls_daemon_random_bytes">tls_daemon_random_bytes</a> (32)</b>
-              The  number  of  pseudo-random bytes that an <a href="smtp.8.html"><b>smtp</b>(8)</a> or <a href="smtpd.8.html"><b>smtpd</b>(8)</a>
-              process requests from the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> server in order to seed  its
+              The number of pseudo-random bytes that an  <a href="smtp.8.html"><b>smtp</b>(8)</a>  or  <a href="smtpd.8.html"><b>smtpd</b>(8)</a>
+              process  requests from the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> server in order to seed its
               internal pseudo random number generator (PRNG).
 
        <b><a href="postconf.5.html#tls_high_cipherlist">tls_high_cipherlist</a> (ALL:!EXPORT:!LOW:!MEDIUM:+RC4:@STRENGTH)</b>
@@ -474,52 +478,52 @@ SMTP(8)                                                                SMTP(8)
               The OpenSSL cipherlist for "EXPORT" or higher grade ciphers.
 
        <b><a href="postconf.5.html#tls_null_cipherlist">tls_null_cipherlist</a> (eNULL:!aNULL)</b>
-              The  OpenSSL  cipherlist  for  "NULL" grade ciphers that provide
+              The OpenSSL cipherlist for "NULL"  grade  ciphers  that  provide
               authentication without encryption.
 
        Available in Postfix version 2.4 and later:
 
        <b><a href="postconf.5.html#smtp_sasl_tls_verified_security_options">smtp_sasl_tls_verified_security_options</a>           ($<a href="postconf.5.html#smtp_sasl_tls_security_options">smtp_sasl_tls_secu</a>-</b>
        <b><a href="postconf.5.html#smtp_sasl_tls_security_options">rity_options</a>)</b>
-              The SASL authentication security options that the  Postfix  SMTP
-              client  uses  for  TLS  encrypted  SMTP sessions with a verified
+              The  SASL  authentication security options that the Postfix SMTP
+              client uses for TLS encrypted  SMTP  sessions  with  a  verified
               server certificate.
 
        Available in Postfix version 2.5 and later:
 
        <b><a href="postconf.5.html#smtp_tls_fingerprint_cert_match">smtp_tls_fingerprint_cert_match</a> (empty)</b>
-              List of acceptable remote SMTP server  certificate  fingerprints
-              for   the   "fingerprint"  TLS  security  level  (<b><a href="postconf.5.html#smtp_tls_security_level">smtp_tls_secu</a>-</b>
+              List  of  acceptable remote SMTP server certificate fingerprints
+              for  the  "fingerprint"  TLS  security   level   (<b><a href="postconf.5.html#smtp_tls_security_level">smtp_tls_secu</a>-</b>
               <b><a href="postconf.5.html#smtp_tls_security_level">rity_level</a></b> = fingerprint).
 
        <b><a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> (md5)</b>
-              The message digest  algorithm  used  to  construct  remote  SMTP
+              The  message  digest  algorithm  used  to  construct remote SMTP
               server certificate fingerprints.
 
        Available in Postfix version 2.6 and later:
 
        <b><a href="postconf.5.html#smtp_tls_protocols">smtp_tls_protocols</a> (!SSLv2)</b>
-              List  of TLS protocols that the Postfix SMTP client will exclude
+              List of TLS protocols that the Postfix SMTP client will  exclude
               or include with opportunistic TLS encryption.
 
        <b><a href="postconf.5.html#smtp_tls_ciphers">smtp_tls_ciphers</a> (export)</b>
-              The minimum TLS cipher grade that the Postfix SMTP  client  will
+              The  minimum  TLS cipher grade that the Postfix SMTP client will
               use with opportunistic TLS encryption.
 
        <b><a href="postconf.5.html#smtp_tls_eccert_file">smtp_tls_eccert_file</a> (empty)</b>
-              File  with the Postfix SMTP client ECDSA certificate in PEM for-
+              File with the Postfix SMTP client ECDSA certificate in PEM  for-
               mat.
 
        <b><a href="postconf.5.html#smtp_tls_eckey_file">smtp_tls_eckey_file</a> ($<a href="postconf.5.html#smtp_tls_eccert_file">smtp_tls_eccert_file</a>)</b>
-              File with the Postfix SMTP client ECDSA private key in PEM  for-
+              File  with the Postfix SMTP client ECDSA private key in PEM for-
               mat.
 
        Available in Postfix version 2.7 and later:
 
        <b><a href="postconf.5.html#smtp_tls_block_early_mail_reply">smtp_tls_block_early_mail_reply</a> (no)</b>
-              Try  to  detect  a mail hijacking attack based on a TLS protocol
-              vulnerability (CVE-2009-3555), where an attacker prepends  mali-
-              cious  HELO,  MAIL, RCPT, DATA commands to a Postfix SMTP client
+              Try to detect a mail hijacking attack based on  a  TLS  protocol
+              vulnerability  (CVE-2009-3555), where an attacker prepends mali-
+              cious HELO, MAIL, RCPT, DATA commands to a Postfix  SMTP  client
               TLS session.
 
        Available in Postfix version 2.8 and later:
@@ -530,11 +534,11 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.11 and later:
 
        <b><a href="postconf.5.html#smtp_tls_trust_anchor_file">smtp_tls_trust_anchor_file</a> (empty)</b>
-              Zero or more PEM-format  files  with  trust-anchor  certificates
+              Zero  or  more  PEM-format  files with trust-anchor certificates
               and/or public keys.
 
        <b><a href="postconf.5.html#smtp_tls_force_insecure_host_tlsa_lookup">smtp_tls_force_insecure_host_tlsa_lookup</a> (no)</b>
-              Lookup  the  associated  DANE TLSA RRset even when a hostname is
+              Lookup the associated DANE TLSA RRset even when  a  hostname  is
               not an alias and its address records lie in an unsigned zone.
 
        <b><a href="postconf.5.html#tls_dane_trust_anchor_digest_enable">tls_dane_trust_anchor_digest_enable</a> (yes)</b>
@@ -544,49 +548,49 @@ SMTP(8)                                                                SMTP(8)
               The name of the <a href="tlsmgr.8.html"><b>tlsmgr</b>(8)</a> service entry in <a href="master.5.html">master.cf</a>.
 
 <b>OBSOLETE STARTTLS CONTROLS</b>
-       The  following  configuration  parameters  exist for compatibility with
-       Postfix versions before 2.3. Support for these will  be  removed  in  a
+       The following configuration parameters  exist  for  compatibility  with
+       Postfix  versions  before  2.3.  Support for these will be removed in a
        future release.
 
        <b><a href="postconf.5.html#smtp_use_tls">smtp_use_tls</a> (no)</b>
-              Opportunistic  mode: use TLS when a remote SMTP server announces
+              Opportunistic mode: use TLS when a remote SMTP server  announces
               STARTTLS support, otherwise send the mail in the clear.
 
        <b><a href="postconf.5.html#smtp_enforce_tls">smtp_enforce_tls</a> (no)</b>
-              Enforcement mode: require  that  remote  SMTP  servers  use  TLS
+              Enforcement  mode:  require  that  remote  SMTP  servers use TLS
               encryption, and never send mail in the clear.
 
        <b><a href="postconf.5.html#smtp_tls_enforce_peername">smtp_tls_enforce_peername</a> (yes)</b>
-              With  mandatory  TLS  encryption,  require  that the remote SMTP
-              server hostname matches  the  information  in  the  remote  SMTP
+              With mandatory TLS encryption,  require  that  the  remote  SMTP
+              server  hostname  matches  the  information  in  the remote SMTP
               server certificate.
 
        <b><a href="postconf.5.html#smtp_tls_per_site">smtp_tls_per_site</a> (empty)</b>
-              Optional  lookup  tables  with the Postfix SMTP client TLS usage
-              policy by next-hop destination and by remote SMTP  server  host-
+              Optional lookup tables with the Postfix SMTP  client  TLS  usage
+              policy  by  next-hop destination and by remote SMTP server host-
               name.
 
        <b><a href="postconf.5.html#smtp_tls_cipherlist">smtp_tls_cipherlist</a> (empty)</b>
-              Obsolete  Postfix  &lt; 2.3 control for the Postfix SMTP client TLS
+              Obsolete Postfix &lt; 2.3 control for the Postfix SMTP  client  TLS
               cipher list.
 
 <b>RESOURCE AND RATE CONTROLS</b>
        <b><a href="postconf.5.html#smtp_destination_concurrency_limit">smtp_destination_concurrency_limit</a>        ($<a href="postconf.5.html#default_destination_concurrency_limit">default_destination_concur</a>-</b>
        <b><a href="postconf.5.html#default_destination_concurrency_limit">rency_limit</a>)</b>
-              The maximal number of parallel deliveries to the  same  destina-
+              The  maximal  number of parallel deliveries to the same destina-
               tion via the smtp message delivery transport.
 
        <b><a href="postconf.5.html#smtp_destination_recipient_limit">smtp_destination_recipient_limit</a> ($<a href="postconf.5.html#default_destination_recipient_limit">default_destination_recipient_limit</a>)</b>
-              The  maximal  number of recipients per message for the smtp mes-
+              The maximal number of recipients per message for the  smtp  mes-
               sage delivery transport.
 
        <b><a href="postconf.5.html#smtp_connect_timeout">smtp_connect_timeout</a> (30s)</b>
-              The Postfix SMTP client time limit for completing a TCP  connec-
+              The  Postfix SMTP client time limit for completing a TCP connec-
               tion, or zero (use the operating system built-in time limit).
 
        <b><a href="postconf.5.html#smtp_helo_timeout">smtp_helo_timeout</a> (300s)</b>
-              The  Postfix SMTP client time limit for sending the HELO or EHLO
-              command, and  for  receiving  the  initial  remote  SMTP  server
+              The Postfix SMTP client time limit for sending the HELO or  EHLO
+              command,  and  for  receiving  the  initial  remote  SMTP server
               response.
 
        <b><a href="postconf.5.html#lmtp_lhlo_timeout">lmtp_lhlo_timeout</a> (300s)</b>
@@ -598,19 +602,19 @@ SMTP(8)                                                                SMTP(8)
               mand, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_mail_timeout">smtp_mail_timeout</a> (300s)</b>
-              The  Postfix  SMTP  client  time limit for sending the MAIL FROM
+              The Postfix SMTP client time limit for  sending  the  MAIL  FROM
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_rcpt_timeout">smtp_rcpt_timeout</a> (300s)</b>
-              The Postfix SMTP client time limit for sending the SMTP RCPT  TO
+              The  Postfix SMTP client time limit for sending the SMTP RCPT TO
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_init_timeout">smtp_data_init_timeout</a> (120s)</b>
-              The  Postfix  SMTP  client  time limit for sending the SMTP DATA
+              The Postfix SMTP client time limit for  sending  the  SMTP  DATA
               command, and for receiving the remote SMTP server response.
 
        <b><a href="postconf.5.html#smtp_data_xfer_timeout">smtp_data_xfer_timeout</a> (180s)</b>
-              The Postfix SMTP client time limit for sending the SMTP  message
+              The  Postfix SMTP client time limit for sending the SMTP message
               content.
 
        <b><a href="postconf.5.html#smtp_data_done_timeout">smtp_data_done_timeout</a> (600s)</b>
@@ -624,13 +628,13 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.1 and later:
 
        <b><a href="postconf.5.html#smtp_mx_address_limit">smtp_mx_address_limit</a> (5)</b>
-              The  maximal number of MX (mail exchanger) IP addresses that can
-              result from Postfix SMTP client mail exchanger lookups, or  zero
+              The maximal number of MX (mail exchanger) IP addresses that  can
+              result  from Postfix SMTP client mail exchanger lookups, or zero
               (no limit).
 
        <b><a href="postconf.5.html#smtp_mx_session_limit">smtp_mx_session_limit</a> (2)</b>
-              The  maximal number of SMTP sessions per delivery request before
-              the Postfix SMTP client gives up  or  delivers  to  a  fall-back
+              The maximal number of SMTP sessions per delivery request  before
+              the  Postfix  SMTP  client  gives  up or delivers to a fall-back
               <a href="postconf.5.html#relayhost">relay host</a>, or zero (no limit).
 
        <b><a href="postconf.5.html#smtp_rset_timeout">smtp_rset_timeout</a> (20s)</b>
@@ -640,17 +644,17 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.2 and earlier:
 
        <b><a href="postconf.5.html#lmtp_cache_connection">lmtp_cache_connection</a> (yes)</b>
-              Keep Postfix LMTP client connections open for  up  to  $<a href="postconf.5.html#max_idle">max_idle</a>
+              Keep  Postfix  LMTP  client connections open for up to $<a href="postconf.5.html#max_idle">max_idle</a>
               seconds.
 
        Available in Postfix version 2.2 and later:
 
        <b><a href="postconf.5.html#smtp_connection_cache_destinations">smtp_connection_cache_destinations</a> (empty)</b>
-              Permanently  enable  SMTP  connection  caching for the specified
+              Permanently enable SMTP connection  caching  for  the  specified
               destinations.
 
        <b><a href="postconf.5.html#smtp_connection_cache_on_demand">smtp_connection_cache_on_demand</a> (yes)</b>
-              Temporarily enable SMTP connection caching while  a  destination
+              Temporarily  enable  SMTP connection caching while a destination
               has a high volume of mail in the <a href="QSHAPE_README.html#active_queue">active queue</a>.
 
        <b><a href="postconf.5.html#smtp_connection_reuse_time_limit">smtp_connection_reuse_time_limit</a> (300s)</b>
@@ -664,37 +668,37 @@ SMTP(8)                                                                SMTP(8)
        Available in Postfix version 2.3 and later:
 
        <b><a href="postconf.5.html#connection_cache_protocol_timeout">connection_cache_protocol_timeout</a> (5s)</b>
-              Time  limit for connection cache connect, send or receive opera-
+              Time limit for connection cache connect, send or receive  opera-
               tions.
 
        Available in Postfix version 2.9 and later:
 
        <b><a href="postconf.5.html#smtp_per_record_deadline">smtp_per_record_deadline</a> (no)</b>
-              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 mes-
+              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  mes-
               sage).
 
        Available in Postfix version 2.11 and later:
 
        <b><a href="postconf.5.html#smtp_connection_reuse_count_limit">smtp_connection_reuse_count_limit</a> (0)</b>
-              When SMTP connection caching is enabled,  the  number  of  times
-              that  an SMTP session may be reused before it is closed, or zero
+              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).
 
 <b>TROUBLE SHOOTING CONTROLS</b>
        <b><a href="postconf.5.html#debug_peer_level">debug_peer_level</a> (2)</b>
-              The increment in verbose logging level when a remote  client  or
+              The  increment  in verbose logging level when a remote client or
               server matches a pattern in the <a href="postconf.5.html#debug_peer_list">debug_peer_list</a> parameter.
 
        <b><a href="postconf.5.html#debug_peer_list">debug_peer_list</a> (empty)</b>
-              Optional  list  of  remote  client or server hostname or network
+              Optional list of remote client or  server  hostname  or  network
               address  patterns  that  cause  the  verbose  logging  level  to
               increase by the amount specified in $<a href="postconf.5.html#debug_peer_level">debug_peer_level</a>.
 
        <b><a href="postconf.5.html#error_notice_recipient">error_notice_recipient</a> (postmaster)</b>
-              The  recipient  of  postmaster notifications about mail delivery
+              The recipient of postmaster notifications  about  mail  delivery
               problems that are caused by policy, resource, software or proto-
               col errors.
 
@@ -708,46 +712,46 @@ SMTP(8)                                                                SMTP(8)
 
 <b>MISCELLANEOUS CONTROLS</b>
        <b><a href="postconf.5.html#best_mx_transport">best_mx_transport</a> (empty)</b>
-              Where  the  Postfix  SMTP  client  should  deliver  mail when it
+              Where the Postfix  SMTP  client  should  deliver  mail  when  it
               detects a "mail loops back to myself" error condition.
 
        <b><a href="postconf.5.html#config_directory">config_directory</a> (see 'postconf -d' output)</b>
-              The default location of the Postfix <a href="postconf.5.html">main.cf</a> and  <a href="master.5.html">master.cf</a>  con-
+              The  default  location of the Postfix <a href="postconf.5.html">main.cf</a> and <a href="master.5.html">master.cf</a> con-
               figuration files.
 
        <b><a href="postconf.5.html#daemon_timeout">daemon_timeout</a> (18000s)</b>
-              How  much  time  a  Postfix  daemon process may take to handle a
+              How much time a Postfix daemon process  may  take  to  handle  a
               request before it is terminated by a built-in watchdog timer.
 
        <b><a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> (2)</b>
-              The maximal number of digits after the decimal point  when  log-
+              The  maximal  number of digits after the decimal point when log-
               ging sub-second delay values.
 
        <b><a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> (no)</b>
               Disable DNS lookups in the Postfix SMTP and LMTP clients.
 
        <b><a href="postconf.5.html#inet_interfaces">inet_interfaces</a> (all)</b>
-              The  network  interface addresses that this mail system receives
+              The network interface addresses that this mail  system  receives
               mail on.
 
        <b><a href="postconf.5.html#inet_protocols">inet_protocols</a> (all)</b>
-              The Internet protocols Postfix will attempt to use  when  making
+              The  Internet  protocols Postfix will attempt to use when making
               or accepting connections.
 
        <b><a href="postconf.5.html#ipc_timeout">ipc_timeout</a> (3600s)</b>
-              The  time  limit  for  sending  or receiving information over an
+              The time limit for sending  or  receiving  information  over  an
               internal communication channel.
 
        <b><a href="postconf.5.html#lmtp_assume_final">lmtp_assume_final</a> (no)</b>
-              When a remote LMTP server announces no DSN support, assume  that
-              the  server performs final delivery, and send "delivered" deliv-
+              When  a remote LMTP server announces no DSN support, assume that
+              the server performs final delivery, and send "delivered"  deliv-
               ery status notifications instead of "relayed".
 
        <b><a href="postconf.5.html#lmtp_tcp_port">lmtp_tcp_port</a> (24)</b>
               The default TCP port that the Postfix LMTP client connects to.
 
        <b><a href="postconf.5.html#max_idle">max_idle</a> (100s)</b>
-              The maximum amount of time that an idle Postfix  daemon  process
+              The  maximum  amount of time that an idle Postfix daemon process
               waits for an incoming connection before terminating voluntarily.
 
        <b><a href="postconf.5.html#max_use">max_use</a> (100)</b>
@@ -761,20 +765,20 @@ SMTP(8)                                                                SMTP(8)
               The process name of a Postfix command or daemon process.
 
        <b><a href="postconf.5.html#proxy_interfaces">proxy_interfaces</a> (empty)</b>
-              The  network  interface addresses that this mail system receives
+              The network interface addresses that this mail  system  receives
               mail on by way of a proxy or network address translation unit.
 
        <b><a href="postconf.5.html#smtp_address_preference">smtp_address_preference</a> (any)</b>
               The address type ("ipv6", "ipv4" or "any") that the Postfix SMTP
-              client  will  try  first,  when  a destination has IPv6 and IPv4
+              client will try first, when a  destination  has  IPv6  and  IPv4
               addresses with equal MX preference.
 
        <b><a href="postconf.5.html#smtp_bind_address">smtp_bind_address</a> (empty)</b>
-              An optional numerical network  address  that  the  Postfix  SMTP
+              An  optional  numerical  network  address  that the Postfix SMTP
               client should bind to when making an IPv4 connection.
 
        <b><a href="postconf.5.html#smtp_bind_address6">smtp_bind_address6</a> (empty)</b>
-              An  optional  numerical  network  address  that the Postfix SMTP
+              An optional numerical network  address  that  the  Postfix  SMTP
               client should bind to when making an IPv6 connection.
 
        <b><a href="postconf.5.html#smtp_helo_name">smtp_helo_name</a> ($<a href="postconf.5.html#myhostname">myhostname</a>)</b>
@@ -794,8 +798,8 @@ SMTP(8)                                                                SMTP(8)
               The syslog facility of Postfix logging.
 
        <b><a href="postconf.5.html#syslog_name">syslog_name</a> (see 'postconf -d' output)</b>
-              The  mail  system  name that is prepended to the process name in
-              syslog records, so that "smtpd"  becomes,  for  example,  "post-
+              The mail system name that is prepended to the  process  name  in
+              syslog  records,  so  that  "smtpd" becomes, for example, "post-
               fix/smtpd".
 
        Available with Postfix 2.2 and earlier:
index b2534932ea7336a2bf703ad105ef18f578a171c3..d290a2cfd390ccdaaec0e6a5f70f7053b4200062 100644 (file)
@@ -261,6 +261,10 @@ VIRTUAL(8)                                                          VIRTUAL(8)
               syslog  records,  so  that  "smtpd" becomes, for example, "post-
               fix/smtpd".
 
+       <b><a href="postconf.5.html#virtual_bounce_defer_filter">virtual_bounce_defer_filter</a> ($<a href="postconf.5.html#default_bounce_defer_filter">default_bounce_defer_filter</a>)</b>
+              Optional filter to change arbitrary hard  delivery  errors  into
+              soft errors and vice versa.
+
 <b>SEE ALSO</b>
        <a href="qmgr.8.html">qmgr(8)</a>, queue manager
        <a href="bounce.8.html">bounce(8)</a>, delivery status reports
@@ -276,15 +280,15 @@ VIRTUAL(8)                                                          VIRTUAL(8)
        The Secure Mailer license must be distributed with this software.
 
 <b>HISTORY</b>
-       This delivery agent was originally based on the Postfix local  delivery
-       agent.  Modifications mainly consisted of removing code that either was
+       This  delivery agent was originally based on the Postfix local delivery
+       agent. Modifications mainly consisted of removing code that either  was
        not  applicable  or  that  was  not  safe  in  this  context:  aliases,
        ~user/.forward files, delivery to "|command" or to /file/name.
 
-       The  <b>Delivered-To:</b> message header appears in the <b>qmail</b> system by Daniel
+       The <b>Delivered-To:</b> message header appears in the <b>qmail</b> system by  Daniel
        Bernstein.
 
-       The <b>maildir</b> structure appears in the <b>qmail</b> system by Daniel  Bernstein.
+       The  <b>maildir</b> structure appears in the <b>qmail</b> system by Daniel Bernstein.
 
 <b>AUTHOR(S)</b>
        Wietse Venema
index 4bf9e47f48fcc01dd842cbcbcbce87156883163c..f267df9d617f12ab2f74ccb1e4aad2544d58f207 100644 (file)
@@ -80,9 +80,8 @@ 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 acquire an exclusive
-lock between updating the database and starting another
-write transaction.
+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
index 4e83b67b9a9cde8064faf71e768918b56368fc57..90024f6b162d7c3719c0479183b553273d233eff 100644 (file)
@@ -1021,6 +1021,71 @@ debugger_command =
 .fi
 .ad
 .ft R
+.SH default_bounce_defer_filter (default: empty)
+Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa.  This is implemented by rewriting the
+three-number enhanced status code and the explanatory text in a
+Postfix delivery agent bounce/defer message.
+.PP
+Specify zero or more "type:table" lookup table names, separated
+by comma or whitespace. With each bounce or defer request, the
+tables are queried in the specified order with one line of text
+that is structured as follows:
+.sp
+.in +4
+enhanced-status-code SPACE explanatory-text
+.in -4
+.PP
+The first table match wins. The lookup result must have the
+same structure as the query:  enhanced status codes must have a
+first numerical field of 4 (defer) or 5 (bounce), and the explanatory
+text field must be non-empty. Other results will result in a warning.
+.PP
+Example:
+.PP
+The following example turns specific soft TLS errors into hard
+errors, by overriding the first number in the enhanced status code.
+.sp
+.in +4
+.nf
+.na
+.ft C
+/etc/postfix/main.cf:
+    smtp_bounce_defer_filter = pcre:/etc/postfix/smtp_ndr_filter
+.fi
+.ad
+.ft R
+.in -4
+.sp
+.in +4
+.nf
+.na
+.ft C
+/etc/postfix/smtp_ndr_filter:
+    /^4(\e.\ed+\e.\ed+ TLS is required, but host \eS+ refused to start TLS: .+)/
+        5$1
+    /^4(\e.\ed+\e.\ed+ 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.\ed+.\ed+ TLS is required, but our TLS engine is unavailable
+    # 4.\ed+.\ed+ TLS is required, but unavailable
+    # 4.\ed+.\ed+ Cannot start TLS: handshake failure
+.fi
+.ad
+.ft R
+.in -4
+.PP
+Notes:
+.IP \(bu
+This feature will NOT override the soft_bounce safety net.
+.IP \(bu
+This feature will change the enhanced status code and text
+that is logged to the maillog file, and that is reported to the
+sender.
+.br
+.PP
+This feature is available in Postfix 2.12 and later.
 .SH default_database_type (default: see "postconf -d" output)
 The default database type for use in \fBnewaliases\fR(1), \fBpostalias\fR(1)
 and \fBpostmap\fR(1) commands. On many UNIX systems the default type is
@@ -2275,6 +2340,11 @@ The LMTP-specific version of the smtp_body_checks configuration
 parameter. See there for details.
 .PP
 This feature is available in Postfix 2.5 and later.
+.SH lmtp_bounce_defer_filter (default: empty)
+The LMTP-specific version of the smtp_bounce_defer_filter
+configuration parameter.  See there for details.
+.PP
+This feature is available in Postfix 2.12 and later.
 .SH lmtp_cache_connection (default: yes)
 Keep Postfix LMTP client connections open for up to $max_idle
 seconds. When the LMTP client receives a request for the same
@@ -4097,6 +4167,12 @@ The name of the \fBpickup\fR(8) service. This service picks up local mail
 submissions from the Postfix maildrop queue.
 .PP
 This feature is available in Postfix 2.0 and later.
+.SH pipe_bounce_defer_filter (default: $default_bounce_defer_filter)
+Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See default_bounce_defer_filter for
+details.
+.PP
+This feature is available in Postfix 2.12 and later.
 .SH plaintext_reject_code (default: 450)
 The numerical Postfix SMTP server response code when a request
 is rejected by the \fBreject_plaintext_session\fR restriction.
@@ -5770,6 +5846,16 @@ These tables are searched while mail is being delivered.  Actions
 that change the delivery time or destination are not available.
 .PP
 This feature is available in Postfix 2.5 and later.
+.SH smtp_bounce_defer_filter (default: $default_bounce_defer_filter)
+Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See default_bounce_defer_filter for
+details.
+.PP
+NOTE: This feature modifies error messages that are generated
+by the Postfix SMTP client, and that may or may not be derived from
+remote SMTP server responses.  In contrast, the smtp_reply_filter
+feature modifies remote SMTP server responses that may result in
+email non-delivery or delivery.
 .SH smtp_cname_overrides_servername (default: version dependent)
 When the remote SMTP servername is a DNS CNAME, replace the
 servername with the result from CNAME expansion for the purpose of
@@ -12246,6 +12332,12 @@ reach the sum of the expansion and recursion limits.  This may
 change in the future.
 .PP
 This feature is available in Postfix 2.1 and later.
+.SH virtual_bounce_defer_filter (default: $default_bounce_defer_filter)
+Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See default_bounce_defer_filter for
+details.
+.PP
+This feature is available in Postfix 2.12 and later.
 .SH virtual_destination_concurrency_limit (default: $default_destination_concurrency_limit)
 The maximal number of parallel deliveries to the same destination
 via the virtual message delivery transport. This limit is enforced
index 41d5159648bb122a1e1db3d5591d9b2775340162..e30f1c8d197498a55d4b7c9c985efec0cfade5bd 100644 (file)
@@ -409,6 +409,9 @@ for an incoming connection before terminating voluntarily.
 .IP "\fBmax_use (100)\fR"
 The maximal number of incoming connections that a Postfix daemon
 process will service before terminating voluntarily.
+.IP "\fBpipe_bounce_defer_filter ($default_bounce_defer_filter)\fR"
+Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa.
 .IP "\fBprocess_id (read-only)\fR"
 The process ID of a Postfix command or daemon process.
 .IP "\fBprocess_name (read-only)\fR"
index f29492d8514d3214f0b429189c2a39082c93f638..77292a46022a1af810426c458be17f5403e7fab8 100644 (file)
@@ -163,6 +163,9 @@ Ignore DNS MX lookups that produce no response.
 Always send EHLO at the start of an SMTP session.
 .IP "\fBsmtp_never_send_ehlo (no)\fR"
 Never send EHLO at the start of an SMTP session.
+.IP "\fBsmtp_bounce_defer_filter ($default_bounce_defer_filter)\fR"
+Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa.
 .IP "\fBsmtp_defer_if_no_mx_address_found (no)\fR"
 Defer mail delivery when no MX record resolves to an IP address.
 .IP "\fBsmtp_line_length_limit (998)\fR"
index 809474d9adc4cd24b4f3645c449acc8e98a0191e..c242e6d81c1c770aa57ba6b9c324b1c500469f81 100644 (file)
@@ -281,6 +281,9 @@ The syslog facility of Postfix logging.
 .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
 The mail system name that is prepended to the process name in syslog
 records, so that "smtpd" becomes, for example, "postfix/smtpd".
+.IP "\fBvirtual_bounce_defer_filter ($default_bounce_defer_filter)\fR"
+Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa.
 .SH "SEE ALSO"
 .na
 .nf
index 5a50fe1f2cd990af613fc9dc15dd3b07a3f7bcf7..edc7613769adb17ad754e6103bb194c910cdec3e 100755 (executable)
@@ -133,6 +133,7 @@ while (<>) {
     s;\bdaemon_timeout\b;<a href="postconf.5.html#daemon_timeout">$&</a>;g;
     s;\bdebug_peer_level\b;<a href="postconf.5.html#debug_peer_level">$&</a>;g;
     s;\bdebug_peer_list\b;<a href="postconf.5.html#debug_peer_list">$&</a>;g;
+    s;\bdefault_bounce_defer_filter\b;<a href="postconf.5.html#default_bounce_defer_filter">$&</a>;g;
     s;\bdefault_data[-</Bb>]*\n* *[<Bb>]*base_type\b;<a href="postconf.5.html#default_database_type">$&</a>;g;
     s;\bdefault_deliv[-</Bb>]*\n* *[<Bb>]*ery_slot_cost\b;<a href="postconf.5.html#default_delivery_slot_cost">$&</a>;g;
     s;\bdefault_deliv[-</Bb>]*\n* *[<Bb>]*ery_slot_discount\b;<a href="postconf.5.html#default_delivery_slot_discount">$&</a>;g;
@@ -212,6 +213,7 @@ while (<>) {
     s;\blmtp_address_preference\b;<a href="postconf.5.html#lmtp_address_preference">$&</a>;g;
     s;\blmtp_body_checks\b;<a href="postconf.5.html#lmtp_body_checks">$&</a>;g;
     s;\blmtp_cname_overrides_servername\b;<a href="postconf.5.html#lmtp_cname_overrides_servername">$&</a>;g;
+    s;\blmtp_bounce_defer_filter\b;<a href="postconf.5.html#lmtp_bounce_defer_filter">$&</a>;g;
     s;\blmtp_dns_resolver_options\b;<a href="postconf.5.html#lmtp_dns_resolver_options">$&</a>;g;
     s;\blmtp_dns_support_level\b;<a href="postconf.5.html#lmtp_dns_support_level">$&</a>;g;
     s;\blmtp_header_checks\b;<a href="postconf.5.html#lmtp_header_checks">$&</a>;g;
@@ -357,6 +359,7 @@ while (<>) {
     s;\bpar[-</bB>]*\n* *[<bB>]*ent_domain_matches_subdomains\b;<a href="postconf.5.html#parent_domain_matches_subdomains">$&</a>;g;
     s;\bpermit_mx_backup_networks\b;<a href="postconf.5.html#permit_mx_backup_networks">$&</a>;g;
     s;\bpickup_service_name\b;<a href="postconf.5.html#pickup_service_name">$&</a>;g;
+    s;\bpipe_bounce_defer_filter\b;<a href="postconf.5.html#pipe_bounce_defer_filter">$&</a>;g;
     s;\bplaintext_reject_code\b;<a href="postconf.5.html#plaintext_reject_code">$&</a>;g;
     s;\bpost[-</bB>]*\n* *[<bB>]*multi_start_commands\b;<a href="postconf.5.html#postmulti_start_commands">$&</a>;g;
     s;\bpost[-</bB>]*\n* *[<bB>]*multi_stop_commands\b;<a href="postconf.5.html#postmulti_stop_commands">$&</a>;g;
@@ -451,6 +454,7 @@ while (<>) {
     s;\bsmtp_connection_cache_time_limit\b;<a href="postconf.5.html#smtp_connection_cache_time_limit">$&</a>;g;
     s;\bsmtp_connection_cache_destinations\b;<a href="postconf.5.html#smtp_connection_cache_destinations">$&</a>;g;
 
+    s;\bsmtp_bounce_defer_filter\b;<a href="postconf.5.html#smtp_bounce_defer_filter">$&</a>;g;
     s;\bsmtp_data_done_timeout\b;<a href="postconf.5.html#smtp_data_done_timeout">$&</a>;g;
     s;\bsmtp_data_init_timeout\b;<a href="postconf.5.html#smtp_data_init_timeout">$&</a>;g;
     s;\bsmtp_data_xfer_timeout\b;<a href="postconf.5.html#smtp_data_xfer_timeout">$&</a>;g;
@@ -601,6 +605,7 @@ while (<>) {
     s;\bvir[-</bB>]*\n*[ <bB>]*tual_alias_maps\b;<a href="postconf.5.html#virtual_alias_maps">$&</a>;g;
     s;\bvir[-</bB>]*\n*[ <bB>]*tual_maps\b;<a href="postconf.5.html#virtual_maps">$&</a>;g;
     s;\bvir[-</bB>]*\n*[ <bB>]*tual_alias_recursion_limit\b;<a href="postconf.5.html#virtual_alias_recursion_limit">$&</a>;g;
+    s;\bvir[-</bB>]*\n*[ <bB>]*tual_bounce_defer_filter\b;<a href="postconf.5.html#virtual_bounce_defer_filter">$&</a>;g;
     s;\bvir[-</bB>]*\n*[ <bB>]*tual_gid_maps\b;<a href="postconf.5.html#virtual_gid_maps">$&</a>;g;
     s;\bvir[-</bB>]*\n*[ <bB>]*tual_mail[-</bB>]*\n* *[<bB>]*box_base\b;<a href="postconf.5.html#virtual_mailbox_base">$&</a>;g;
     s;\bvir[-</bB>]*\n*[ <bB>]*tual_mail[-</bB>]*\n* *[<bB>]*box_domains\b;<a href="postconf.5.html#virtual_mailbox_domains">$&</a>;g;
index 55d6c8718e95a2700a3c295dfcac3016d358cf24..a52033d83cb0164e8ee8d5fa85abc5ec1ec578ff 100644 (file)
@@ -2651,6 +2651,7 @@ the local Postfix system. This requires super-user privileges. </p>
 <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}"
@@ -2697,9 +2698,9 @@ an unsigned public key certificate. </p>
 
 <blockquote>
 <pre>
-% <b>openssl req -new -nodes -keyout foo-key.pem -out foo-req.pem</b>
+% <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 1024 bit RSA private key
+Generating a 2048 bit RSA private key
 ........................................++++++
 ....++++++
 writing new private key to 'foo-key.pem'
index 48d807e35c2399abfe8904147f666b07bc82d72d..0bd337f0d2a0947eb7b4f83d449a990e06488202 100644 (file)
@@ -68,9 +68,8 @@
 #      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 acquire an exclusive
-#      lock between updating the database and starting another
-#      write transaction.
+#      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
index 937a454bd68b1ab3420e1e0f0ae03656e3bfaf9f..c27a5c463fad7b43e680b1326ca01a9840716fb4 100644 (file)
@@ -15615,3 +15615,102 @@ whether any digest TLSA records are acceptable in usage "2" (trust
 anchor assertion) TLSA records. </p>
 
 <p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM default_bounce_defer_filter
+
+<p> Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa.  This is implemented by rewriting the
+three-number enhanced status code and the explanatory text in a
+Postfix delivery agent bounce/defer message. </p>
+
+<p> Specify zero or more "type:table" lookup table names, separated
+by comma or whitespace. With each bounce or defer request, 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:  enhanced status codes must have a
+first numerical field of 4 (defer) or 5 (bounce), and the explanatory
+text field must be non-empty. Other results will result in a warning.
+</p>
+
+<p> Example: </p>
+
+<p> The following example turns 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_bounce_defer_filter = pcre:/etc/postfix/smtp_ndr_filter
+</pre>
+</blockquote>
+
+<blockquote>
+<pre>
+/etc/postfix/smtp_ndr_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> 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. </p>
+
+</ul>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM smtp_bounce_defer_filter $default_bounce_defer_filter
+
+<p> Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See default_bounce_defer_filter for
+details.  </p>
+
+<p> NOTE: This feature modifies error messages that are generated
+by the Postfix SMTP client, and that may or may not be derived from
+remote SMTP server responses.  In contrast, the smtp_reply_filter
+feature modifies remote SMTP server responses that may result in
+email non-delivery or delivery. </p>
+
+%PARAM lmtp_bounce_defer_filter 
+
+<p> The LMTP-specific version of the smtp_bounce_defer_filter
+configuration parameter.  See there for details. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM pipe_bounce_defer_filter $default_bounce_defer_filter
+
+<p> Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See default_bounce_defer_filter for
+details.  </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM virtual_bounce_defer_filter $default_bounce_defer_filter
+
+<p> Optional filter to change arbitrary hard delivery errors into
+soft errors and vice versa. See default_bounce_defer_filter for
+details.  </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
index f008a0d073f2d86ef5b4520519af8309ce38efeb..f5799eb0e87e9716b3e5382353cf7c0d08c81a3d 100644 (file)
@@ -32,7 +32,7 @@ SRCS  = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
        match_service.c mail_conf_nint.c addr_match_list.c mail_conf_nbool.c \
        smtp_reply_footer.c safe_ultostr.c verify_sender_addr.c \
        dict_memcache.c mail_version.c memcache_proto.c server_acl.c \
-       mkmap_fail.c haproxy_srvr.c
+       mkmap_fail.c haproxy_srvr.c ndr_filter.c
 OBJS   = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
        clnt_stream.o conv_time.o db_common.o debug_peer.o debug_process.o \
@@ -66,7 +66,7 @@ OBJS  = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
        match_service.o mail_conf_nint.o addr_match_list.o mail_conf_nbool.o \
        smtp_reply_footer.o safe_ultostr.o verify_sender_addr.o \
        dict_memcache.o mail_version.o memcache_proto.o server_acl.o \
-       mkmap_fail.o haproxy_srvr.o
+       mkmap_fail.o haproxy_srvr.o ndr_filter.o
 HDRS   = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
        conv_time.h db_common.h debug_peer.h debug_process.h defer.h \
@@ -93,7 +93,7 @@ HDRS  = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
        fold_addr.h header_body_checks.h data_redirect.h match_service.h \
        addr_match_list.h smtp_reply_footer.h safe_ultostr.h \
        verify_sender_addr.h dict_memcache.h memcache_proto.h server_acl.h \
-       haproxy_srvr.h
+       haproxy_srvr.h ndr_filter.h
 TESTSRC        = rec2stream.c stream2rec.c recdump.c
 DEFS   = -I. -I$(INC_DIR) -D$(SYSTYPE)
 CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -666,6 +666,7 @@ bounce.o: log_adhoc.h
 bounce.o: mail_params.h
 bounce.o: mail_proto.h
 bounce.o: msg_stats.h
+bounce.o: ndr_filter.h
 bounce.o: rcpt_print.h
 bounce.o: recipient_list.h
 bounce.o: trace.h
@@ -811,6 +812,7 @@ defer.o: mail_params.h
 defer.o: mail_proto.h
 defer.o: mail_queue.h
 defer.o: msg_stats.h
+defer.o: ndr_filter.h
 defer.o: rcpt_print.h
 defer.o: recipient_list.h
 defer.o: trace.h
@@ -928,10 +930,46 @@ dict_memcache.o: dict_memcache.c
 dict_memcache.o: dict_memcache.h
 dict_memcache.o: memcache_proto.h
 dict_memcache.o: string_list.h
+dict_mysql.o: ../../include/argv.h
+dict_mysql.o: ../../include/dict.h
+dict_mysql.o: ../../include/events.h
+dict_mysql.o: ../../include/find_inet.h
+dict_mysql.o: ../../include/match_list.h
+dict_mysql.o: ../../include/msg.h
+dict_mysql.o: ../../include/myflock.h
+dict_mysql.o: ../../include/mymalloc.h
+dict_mysql.o: ../../include/myrand.h
+dict_mysql.o: ../../include/split_at.h
+dict_mysql.o: ../../include/stringops.h
 dict_mysql.o: ../../include/sys_defs.h
+dict_mysql.o: ../../include/vbuf.h
+dict_mysql.o: ../../include/vstream.h
+dict_mysql.o: ../../include/vstring.h
+dict_mysql.o: cfg_parser.h
+dict_mysql.o: db_common.h
 dict_mysql.o: dict_mysql.c
+dict_mysql.o: dict_mysql.h
+dict_mysql.o: string_list.h
+dict_pgsql.o: ../../include/argv.h
+dict_pgsql.o: ../../include/dict.h
+dict_pgsql.o: ../../include/events.h
+dict_pgsql.o: ../../include/find_inet.h
+dict_pgsql.o: ../../include/match_list.h
+dict_pgsql.o: ../../include/msg.h
+dict_pgsql.o: ../../include/myflock.h
+dict_pgsql.o: ../../include/mymalloc.h
+dict_pgsql.o: ../../include/myrand.h
+dict_pgsql.o: ../../include/split_at.h
+dict_pgsql.o: ../../include/stringops.h
 dict_pgsql.o: ../../include/sys_defs.h
+dict_pgsql.o: ../../include/vbuf.h
+dict_pgsql.o: ../../include/vstream.h
+dict_pgsql.o: ../../include/vstring.h
+dict_pgsql.o: cfg_parser.h
+dict_pgsql.o: db_common.h
 dict_pgsql.o: dict_pgsql.c
+dict_pgsql.o: dict_pgsql.h
+dict_pgsql.o: string_list.h
 dict_proxy.o: ../../include/argv.h
 dict_proxy.o: ../../include/attr.h
 dict_proxy.o: ../../include/dict.h
@@ -1768,6 +1806,20 @@ namadr_list.o: ../../include/match_list.h
 namadr_list.o: ../../include/sys_defs.h
 namadr_list.o: namadr_list.c
 namadr_list.o: namadr_list.h
+ndr_filter.o: ../../include/argv.h
+ndr_filter.o: ../../include/dict.h
+ndr_filter.o: ../../include/msg.h
+ndr_filter.o: ../../include/myflock.h
+ndr_filter.o: ../../include/mymalloc.h
+ndr_filter.o: ../../include/sys_defs.h
+ndr_filter.o: ../../include/vbuf.h
+ndr_filter.o: ../../include/vstream.h
+ndr_filter.o: ../../include/vstring.h
+ndr_filter.o: dsn.h
+ndr_filter.o: dsn_util.h
+ndr_filter.o: maps.h
+ndr_filter.o: ndr_filter.c
+ndr_filter.o: ndr_filter.h
 off_cvt.o: ../../include/msg.h
 off_cvt.o: ../../include/sys_defs.h
 off_cvt.o: ../../include/vbuf.h
index d260be766b866513c4337177fe291e0d3b7c95ae..fe14c4dbb965193ec8c6f4ef573760287d2b0843 100644 (file)
 /*     RECIPIENT *rcpt;
 /*     const char *relay;
 /*     DSN     *dsn;
+/*
+/*     void    bounce_client_init(title, maps)
+/*     const char *title;
+/*     const char *maps;
+/* INTERNAL API
+/*     NDR_FILTER *bounce_defer_filter;
+/*
+/*     int     bounce_append_intern(flags, id, stats, recipient, relay, dsn)
+/*     int     flags;
+/*     const char *id;
+/*     MSG_STATS *stats;
+/*     RECIPIENT *rcpt;
+/*     const char *relay;
 /* DESCRIPTION
 /*     This module implements the client interface to the message
 /*     bounce service, which maintains a per-message log of status
 /*     return address in a manner that depends on the recipient
 /*     address.
 /*
+/*     bounce_client_init() initializes an optional DSN filter.
+/*
+/*     bounce_append_intern() is for use after the DSN filter. DSN
+/*     filtering is not yet supported for bounce_one().
+/*
 /*     Arguments:
 /* .IP flags
 /*     The bitwise OR of zero or more of the following (specify
 /*     zero value. Otherwise, the functions return a non-zero result,
 /*     and when BOUNCE_FLAG_CLEAN is disabled, log that message
 /*     delivery is deferred.
+/* .IP title
+/*     The origin of the optional DSN filter lookup table names.
+/* .IP maps
+/*     The optional "type:table" DSN filter lookup table names,
+/*     separated by comma or whitespace.
 /* BUGS
 /*     Should be replaced by routines with an attribute-value based
 /*     interface instead of an interface that uses a rigid argument list.
 
 /* Global library. */
 
+#define BOUNCE_DEFER_INTERN
 #include <mail_params.h>
 #include <mail_proto.h>
 #include <log_adhoc.h>
 #include <trace.h>
 #include <bounce.h>
 
-/* bounce_append - append dsn_text to per-message bounce log */
+/* Shared internally, between bounce and defer clients. */
+
+NDR_FILTER *bounce_defer_filter;
+
+/* bounce_append - append delivery status to per-message bounce log */
 
 int     bounce_append(int flags, const char *id, MSG_STATS *stats,
                              RECIPIENT *rcpt, const char *relay,
                              DSN *dsn)
 {
     DSN     my_dsn = *dsn;
-    int     status;
+    DSN    *dsn_res;
 
     /*
      * Sanity check. If we're really confident, change this into msg_panic
@@ -187,6 +215,27 @@ int     bounce_append(int flags, const char *id, MSG_STATS *stats,
        my_dsn.status = "5.0.0";
     }
 
+    /*
+     * DSN filter (Postfix 2.12).
+     */
+    if (bounce_defer_filter != 0
+      && (dsn_res = ndr_filter_lookup(bounce_defer_filter, &my_dsn)) != 0) {
+       if (dsn_res->status[0] == '4')
+           return (defer_append_intern(flags, id, stats, rcpt, relay, dsn_res));
+       my_dsn = *dsn_res;
+    }
+    return (bounce_append_intern(flags, id, stats, rcpt, relay, &my_dsn));
+}
+
+/* bounce_append_intern - append delivery status to per-message bounce log */
+
+int     bounce_append_intern(int flags, const char *id, MSG_STATS *stats,
+                                    RECIPIENT *rcpt, const char *relay,
+                                    DSN *dsn)
+{
+    DSN     my_dsn = *dsn;
+    int     status;
+
     /*
      * MTA-requested address verification information is stored in the verify
      * service database.
@@ -259,7 +308,7 @@ int     bounce_append(int flags, const char *id, MSG_STATS *stats,
            vstring_sprintf(junk, "%s or %s service failure",
                            var_bounce_service, var_trace_service);
            my_dsn.reason = vstring_str(junk);
-           status = defer_append(flags, id, stats, rcpt, relay, &my_dsn);
+           status = defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn);
            vstring_free(junk);
        } else {
            status = -1;
@@ -428,3 +477,15 @@ int     bounce_one(int flags, const char *queue, const char *id,
        return (status);
     }
 }
+
+/* bounce_client_init - initialize bounce/defer DSN filter */
+
+void    bounce_client_init(const char *title, const char *maps)
+{
+    const char myname[] = "bounce_client_init";
+
+    if (bounce_defer_filter != 0)
+       msg_panic("%s: duplicate initialization", myname);
+    if (*maps)
+       bounce_defer_filter = ndr_filter_create(title, maps);
+}
index 31f7398d24648ed0d70eb969fbcec491ef9cf594..bb71278419dcc56aaeaa24bc8f77cd5e5122fe2d 100644 (file)
@@ -35,6 +35,7 @@ extern int bounce_one(int, const char *, const char *, const char *,
                              const char *, const char *,
                              int, MSG_STATS *, RECIPIENT *,
                              const char *, DSN *);
+extern void bounce_client_init(const char *, const char *);
 
  /*
   * Bounce/defer protocol commands.
@@ -65,6 +66,25 @@ extern int bounce_one(int, const char *, const char *, const char *,
   */
 #define BOUNCE_FLAG_KEEP       BOUNCE_FLAG_NONE
 
+ /*
+  * Start of private API.
+  */
+
+#ifdef BOUNCE_DEFER_INTERN
+
+#include <ndr_filter.h>
+
+extern NDR_FILTER *bounce_defer_filter;
+
+extern int bounce_append_intern(int, const char *, MSG_STATS *, RECIPIENT *,
+                                       const char *, DSN *);
+extern int bounce_one_intern(int, const char *, const char *, const char *,
+                                    const char *, const char *,
+                                    int, MSG_STATS *, RECIPIENT *,
+                                    const char *, DSN *);
+
+#endif
+
 /* LICENSE
 /* .ad
 /* .fi
index a2b44a3e46f65bb4db297109ca15b1927e340672..a05b8bf5989d9993d073f4ff2cdbc369383529f9 100644 (file)
 /*     const char *sender;
 /*     const char *dsn_envid;
 /*     int     dsn_ret;
+/* INTERNAL API
+/*     int     defer_append_intern(flags, id, stats, rcpt, relay, dsn)
+/*     int     flags;
+/*     const char *id;
+/*     MSG_STATS *stats;
+/*     RECIPIENT *rcpt;
+/*     const char *relay;
 /* DESCRIPTION
 /*     This module implements a client interface to the defer service,
 /*     which maintains a per-message logfile with status records for
@@ -56,6 +63,8 @@
 /*     question has been deferred.  The defer log is not deleted,
 /*     and no recipients are deleted from the original queue file.
 /*
+/*     defer_append_intern() is for use after the DSN filter.
+/*
 /*     Arguments:
 /* .IP flags
 /*     The bit-wise OR of zero or more of the following (specify
 
 /* Global library. */
 
+#define BOUNCE_DEFER_INTERN
 #include <mail_params.h>
 #include <mail_queue.h>
 #include <mail_proto.h>
@@ -154,9 +164,8 @@ int     defer_append(int flags, const char *id, MSG_STATS *stats,
                             RECIPIENT *rcpt, const char *relay,
                             DSN *dsn)
 {
-    const char *rcpt_domain;
     DSN     my_dsn = *dsn;
-    int     status;
+    DSN    *dsn_res;
 
     /*
      * Sanity check.
@@ -166,6 +175,28 @@ int     defer_append(int flags, const char *id, MSG_STATS *stats,
        my_dsn.status = "4.0.0";
     }
 
+    /*
+     * DSN filter (Postfix 2.12).
+     */
+    if (bounce_defer_filter != 0
+      && (dsn_res = ndr_filter_lookup(bounce_defer_filter, &my_dsn)) != 0) {
+       if (dsn_res->status[0] == '5')
+           return (bounce_append_intern(flags, id, stats, rcpt, relay, dsn_res));
+       my_dsn = *dsn_res;
+    }
+    return (defer_append_intern(flags, id, stats, rcpt, relay, &my_dsn));
+}
+
+/* defer_append_intern - defer message delivery */
+
+int     defer_append_intern(int flags, const char *id, MSG_STATS *stats,
+                                   RECIPIENT *rcpt, const char *relay,
+                                   DSN *dsn)
+{
+    const char *rcpt_domain;
+    DSN     my_dsn = *dsn;
+    int     status;
+
     /*
      * MTA-requested address verification information is stored in the verify
      * service database.
index ba9be7d698d07afebf1fcbb60fe281fb98515884..55f98034d83fb889ff745b319227b2b55f47f971 100644 (file)
@@ -26,6 +26,16 @@ extern int defer_flush(int, const char *, const char *, const char *,
 extern int defer_warn(int, const char *, const char *, const char *,
                              const char *, int);
 
+ /*
+  * Start of private API.
+  */
+#ifdef BOUNCE_DEFER_INTERN
+
+extern int defer_append_intern(int, const char *, MSG_STATS *, RECIPIENT *,
+                                      const char *, DSN *);
+
+#endif
+
 /* LICENSE
 /* .ad
 /* .fi
index aa78c3b9c57e44647182535a1e7994ba168dd6d5..79cf950d5395698369c042b0df25fa2cc7768628 100644 (file)
@@ -18,7 +18,7 @@
 /* .in -4
 /*     } DSN;
 /*
-/*     DSN     *create(status, action, reason, dtype, dtext, mtype, mname)
+/*     DSN     *dsn_create(status, action, reason, dtype, dtext, mtype, mname)
 /*     const char *status;
 /*     const char *action;
 /*     const char *reason;
index 2d919776c050e844a87c35476fcd16c73c10bff9..f322af6517c0602c14c0fd02ea402629ffd96682 100644 (file)
 /*     bool    var_multi_enable;
 /*     bool    var_long_queue_ids;
 /*     bool    var_daemon_open_fatal;
+/*     char    *var_ndr_filter;
 /*
 /*     void    mail_params_init()
 /*
@@ -314,6 +315,7 @@ char   *var_multi_name;
 bool    var_multi_enable;
 bool    var_long_queue_ids;
 bool    var_daemon_open_fatal;
+char   *var_ndr_filter;
 
 const char null_format_string[1] = "";
 
@@ -589,6 +591,7 @@ void    mail_params_init()
        VAR_INT_FILT_CLASSES, DEF_INT_FILT_CLASSES, &var_int_filt_classes, 0, 0,
        /* multi_instance_wrapper may have dependencies but not dependents. */
        VAR_MULTI_WRAPPER, DEF_MULTI_WRAPPER, &var_multi_wrapper, 0, 0,
+       VAR_NDR_FILTER, DEF_NDR_FILTER, &var_ndr_filter, 0, 0,
        0,
     };
     static const CONFIG_STR_FN_TABLE function_str_defaults_2[] = {
index 12fd0e157d6dafbb49fd51160f3d0d44efaca02a..07d89471ccf2d323147f4b01252312948bc9e516 100644 (file)
@@ -3744,6 +3744,27 @@ extern char *var_sm_fix_eol;
 #define DEF_DAEMON_OPEN_FATAL  0
 extern bool var_daemon_open_fatal;
 
+ /*
+  * Optional DSN bounce/defer filter.
+  */
+#define VAR_NDR_FILTER                 "default_bounce_defer_filter"
+#define DEF_NDR_FILTER                 ""
+extern char *var_ndr_filter;
+
+#define VAR_SMTP_NDR_FILTER            "smtp_bounce_defer_filter"
+#define DEF_SMTP_NDR_FILTER            "$" VAR_NDR_FILTER
+#define VAR_LMTP_NDR_FILTER            "lmtp_bounce_defer_filter"
+#define DEF_LMTP_NDR_FILTER            "$" VAR_NDR_FILTER
+extern char *var_smtp_ndr_filter;
+
+#define VAR_PIPE_NDR_FILTER            "pipe_bounce_defer_filter"
+#define DEF_PIPE_NDR_FILTER            "$" VAR_NDR_FILTER
+extern char *var_pipe_ndr_filter;
+
+#define VAR_VIRT_NDR_FILTER            "virtual_bounce_defer_filter"
+#define DEF_VIRT_NDR_FILTER            "$" VAR_NDR_FILTER
+extern char *var_virt_ndr_filter;
+
 /* LICENSE
 /* .ad
 /* .fi
index 49aabae86c4568a4ca67ed297ce2c0fdffb87b5c..e4d4282ba8a3fcc89ad81ed460c828368c574ce7 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change both the patchlevel and the release date. Snapshots have no
   * patchlevel; they change the release date only.
   */
-#define MAIL_RELEASE_DATE      "20140223"
+#define MAIL_RELEASE_DATE      "20140316"
 #define MAIL_VERSION_NUMBER    "2.12"
 
 #ifdef SNAPSHOT
diff --git a/postfix/src/global/ndr_filter.c b/postfix/src/global/ndr_filter.c
new file mode 100644 (file)
index 0000000..b0e216c
--- /dev/null
@@ -0,0 +1,178 @@
+/*++
+/* NAME
+/*     ndr_filter 3
+/* SUMMARY
+/*     bounce or defer NDR filter
+/* SYNOPSIS
+/*     #include <ndr_filter.h>
+/*
+/*     NDR_FILTER *ndr_filter_create(
+/*     const char *title,
+/*     const char *map_names)
+/*
+/*     DSN     *ndr_filter_lookup(
+/*     NDR_FILTER *fp,
+/*     DSN     dsn)
+/*
+/*     void    dsn_free(
+/*     NDR_FILTER *fp)
+/* DESCRIPTION
+/*     This module maps a bounce or defer non-delivery status code
+/*     and text into a bounce or defer non-delivery status code
+/*     and text. The other DSN attributes are passed through without
+/*     modification.
+/*
+/*     ndr_filter_create() instantiates a bounce or defer NDR filter.
+/*
+/*     ndr_filter_lookup() queries the specified filter. The DSN
+/*     must be a bounce or defer DSN. If a match is found and the
+/*     result is properly formatted, the result value must specify
+/*     a bounce or defer DSN. The result is in part overwritten
+/*     upon each call, and is in part a shallow copy of the dsn
+/*     argument.  The result is a null pointer when no valid match
+/*     is found. This function must not be called with the result
+/*     from a ndr_filter_lookup() call.
+/*
+/*     dsn_free() destroys the specified NDR filter.
+/*
+/*     Arguments:
+/* .IP title
+/*     Origin of the mapnames argument, typically a configuration
+/*     parameter name. This is reported in diagnostics.
+/* .IP mapnames
+/*     List of lookup tables, separated by whitespace or comma.
+/* .IP fp
+/*     filter created with ndr_filter_create()
+/* .IP dsn
+/*     A bounce or defer DSN data structure. The ndr_filter_lookup()
+/*     result value is in part a shallow copy of this argument.
+/* SEE ALSO
+/*     maps(3) multi-table search
+/* DIAGNOSTICS
+/*     Panic: invalid dsn argument; recursive call. Fatal error:
+/*     memory allocation problem. Warning: invalid DSN lookup
+/*     result.
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+ /*
+  * System libraries.
+  */
+#include <sys_defs.h>
+
+ /*
+  * Utility library.
+  */
+#include <msg.h>
+#include <mymalloc.h>
+#include <vstring.h>
+
+ /*
+  * Global library.
+  */
+#include <maps.h>
+#include <dsn.h>
+#include <dsn_util.h>
+#include <maps.h>
+#include <ndr_filter.h>
+
+ /*
+  * Private data structure.
+  */
+struct NDR_FILTER {
+    MAPS   *maps;                      /* Replacement (status, text) */
+    VSTRING *buffer;                   /* Status code and text */
+    DSN_SPLIT dp;                      /* Parsing aid */
+    DSN     dsn;                       /* Shallow copy */
+};
+
+ /*
+  * SLMs.
+  */
+#define STR(x) vstring_str(x)
+
+/* ndr_filter_create - create bounce/defer NDR filter */
+
+NDR_FILTER *ndr_filter_create(const char *title, const char *map_names)
+{
+    const char myname[] = "ndr_filter_create";
+    NDR_FILTER *fp;
+
+    if (msg_verbose)
+       msg_info("%s: %s %s", myname, title, map_names);
+
+    fp = (NDR_FILTER *) mymalloc(sizeof(*fp));
+    fp->buffer = vstring_alloc(100);
+    fp->maps = maps_create(title, map_names, DICT_FLAG_LOCK);
+    return (fp);
+}
+
+/* ndr_filter_lookup - apply bounce/defer NDR filter */
+
+DSN    *ndr_filter_lookup(NDR_FILTER *fp, DSN *dsn)
+{
+    const char myname[] = "ndr_filter_lookup";
+    const char *result;
+
+    if (msg_verbose)
+       msg_info("%s: %s %s", myname, dsn->status, dsn->reason);
+
+#define IS_NDR_DSN(s) \
+       (dsn_valid(s) && (s)[1] == '.' && ((s)[0] == '4' || (s)[0] == '5'))
+
+    /*
+     * Sanity check. We filter only bounce/defer DSNs.
+     */
+    if (!IS_NDR_DSN(dsn->status))
+       msg_panic("%s: dsn argument with bad status code: %s",
+                 myname, dsn->status);
+
+    /*
+     * Sanity check. An NDR filter must not be invoked with its own result.
+     */
+    if (dsn->reason == fp->dsn.reason)
+       msg_panic("%s: recursive call is not allowed", myname);
+
+    /*
+     * Look up replacement status and text.
+     */
+    vstring_sprintf(fp->buffer, "%s %s", dsn->status, dsn->reason);
+    if ((result = maps_find(fp->maps, STR(fp->buffer), 0)) != 0) {
+       /* Sanity check. We accept only bounce/defer DSNs. */
+       if (!IS_NDR_DSN(result)) {
+           msg_warn("%s: bad status code: %s", fp->maps->title, result);
+           return (0);
+       } else {
+           vstring_strcpy(fp->buffer, result);
+           dsn_split(&fp->dp, "can't happen", STR(fp->buffer));
+           (void) DSN_ASSIGN(&fp->dsn, DSN_STATUS(fp->dp.dsn),
+                             (result[0] == '4' ? "delayed" : "failed"),
+                             fp->dp.text, dsn->dtype, dsn->dtext,
+                             dsn->mtype, dsn->mname);
+           return (&fp->dsn);
+       }
+    }
+    return (0);
+}
+
+/* ndr_filter_free - destroy bounce/defer NDR filter */
+
+void    ndr_filter_free(NDR_FILTER *fp)
+{
+    const char myname[] = "ndr_filter_free";
+
+    if (msg_verbose)
+       msg_info("%s: %s", myname, fp->maps->title);
+
+    maps_free(fp->maps);
+    vstring_free(fp->buffer);
+    myfree((char *) fp);
+}
diff --git a/postfix/src/global/ndr_filter.h b/postfix/src/global/ndr_filter.h
new file mode 100644 (file)
index 0000000..1a1f7d1
--- /dev/null
@@ -0,0 +1,34 @@
+#ifndef _NDR_FILTER_H_INCLUDED_
+#define _NDR_FILTER_H_INCLUDED_
+
+/*++
+/* NAME
+/*     ndr_filter 3h
+/* SUMMARY
+/*     bounce/defer DSN filter
+/* SYNOPSIS
+/*     #include <ndr_filter.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * External interface.
+  */
+typedef struct NDR_FILTER NDR_FILTER;
+
+extern NDR_FILTER *ndr_filter_create(const char *, const char *);
+extern DSN *ndr_filter_lookup(NDR_FILTER *, DSN *);
+extern void ndr_filter_free(NDR_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
+/*--*/
+
+#endif
index 9a74c6917fe1e42a5bd0ce9042268dff1f872ec9..6b1e2c0bac3615a8b00a2bcdae54d23ce0f2c43c 100644 (file)
@@ -86,9 +86,15 @@ depend: $(MAKES)
 
 # do not edit below this line - it is generated by 'make depend'
 event_server.o: ../../include/argv.h
+event_server.o: ../../include/attr.h
+event_server.o: ../../include/bounce.h
 event_server.o: ../../include/chroot_uid.h
 event_server.o: ../../include/debug_process.h
+event_server.o: ../../include/deliver_request.h
 event_server.o: ../../include/dict.h
+event_server.o: ../../include/dsn.h
+event_server.o: ../../include/dsn_buf.h
+event_server.o: ../../include/ndr_filter.h
 event_server.o: ../../include/events.h
 event_server.o: ../../include/htable.h
 event_server.o: ../../include/iostuff.h
@@ -99,10 +105,12 @@ event_server.o: ../../include/mail_params.h
 event_server.o: ../../include/mail_task.h
 event_server.o: ../../include/mail_version.h
 event_server.o: ../../include/msg.h
+event_server.o: ../../include/msg_stats.h
 event_server.o: ../../include/msg_syslog.h
 event_server.o: ../../include/msg_vstream.h
 event_server.o: ../../include/myflock.h
 event_server.o: ../../include/mymalloc.h
+event_server.o: ../../include/recipient_list.h
 event_server.o: ../../include/resolve_local.h
 event_server.o: ../../include/safe_open.h
 event_server.o: ../../include/sane_accept.h
@@ -284,9 +292,15 @@ master_watch.o: ../../include/sys_defs.h
 master_watch.o: master.h
 master_watch.o: master_watch.c
 multi_server.o: ../../include/argv.h
+multi_server.o: ../../include/attr.h
+multi_server.o: ../../include/bounce.h
 multi_server.o: ../../include/chroot_uid.h
 multi_server.o: ../../include/debug_process.h
+multi_server.o: ../../include/deliver_request.h
 multi_server.o: ../../include/dict.h
+multi_server.o: ../../include/dsn.h
+multi_server.o: ../../include/dsn_buf.h
+multi_server.o: ../../include/ndr_filter.h
 multi_server.o: ../../include/events.h
 multi_server.o: ../../include/htable.h
 multi_server.o: ../../include/iostuff.h
@@ -297,10 +311,12 @@ multi_server.o: ../../include/mail_params.h
 multi_server.o: ../../include/mail_task.h
 multi_server.o: ../../include/mail_version.h
 multi_server.o: ../../include/msg.h
+multi_server.o: ../../include/msg_stats.h
 multi_server.o: ../../include/msg_syslog.h
 multi_server.o: ../../include/msg_vstream.h
 multi_server.o: ../../include/myflock.h
 multi_server.o: ../../include/mymalloc.h
+multi_server.o: ../../include/recipient_list.h
 multi_server.o: ../../include/resolve_local.h
 multi_server.o: ../../include/safe_open.h
 multi_server.o: ../../include/sane_accept.h
@@ -317,9 +333,15 @@ multi_server.o: mail_server.h
 multi_server.o: master_proto.h
 multi_server.o: multi_server.c
 single_server.o: ../../include/argv.h
+single_server.o: ../../include/attr.h
+single_server.o: ../../include/bounce.h
 single_server.o: ../../include/chroot_uid.h
 single_server.o: ../../include/debug_process.h
+single_server.o: ../../include/deliver_request.h
 single_server.o: ../../include/dict.h
+single_server.o: ../../include/dsn.h
+single_server.o: ../../include/dsn_buf.h
+single_server.o: ../../include/ndr_filter.h
 single_server.o: ../../include/events.h
 single_server.o: ../../include/htable.h
 single_server.o: ../../include/iostuff.h
@@ -330,10 +352,12 @@ single_server.o: ../../include/mail_params.h
 single_server.o: ../../include/mail_task.h
 single_server.o: ../../include/mail_version.h
 single_server.o: ../../include/msg.h
+single_server.o: ../../include/msg_stats.h
 single_server.o: ../../include/msg_syslog.h
 single_server.o: ../../include/msg_vstream.h
 single_server.o: ../../include/myflock.h
 single_server.o: ../../include/mymalloc.h
+single_server.o: ../../include/recipient_list.h
 single_server.o: ../../include/resolve_local.h
 single_server.o: ../../include/safe_open.h
 single_server.o: ../../include/sane_accept.h
@@ -350,9 +374,15 @@ single_server.o: mail_server.h
 single_server.o: master_proto.h
 single_server.o: single_server.c
 trigger_server.o: ../../include/argv.h
+trigger_server.o: ../../include/attr.h
+trigger_server.o: ../../include/bounce.h
 trigger_server.o: ../../include/chroot_uid.h
 trigger_server.o: ../../include/debug_process.h
+trigger_server.o: ../../include/deliver_request.h
 trigger_server.o: ../../include/dict.h
+trigger_server.o: ../../include/dsn.h
+trigger_server.o: ../../include/dsn_buf.h
+trigger_server.o: ../../include/ndr_filter.h
 trigger_server.o: ../../include/events.h
 trigger_server.o: ../../include/htable.h
 trigger_server.o: ../../include/iostuff.h
@@ -363,10 +393,12 @@ trigger_server.o: ../../include/mail_params.h
 trigger_server.o: ../../include/mail_task.h
 trigger_server.o: ../../include/mail_version.h
 trigger_server.o: ../../include/msg.h
+trigger_server.o: ../../include/msg_stats.h
 trigger_server.o: ../../include/msg_syslog.h
 trigger_server.o: ../../include/msg_vstream.h
 trigger_server.o: ../../include/myflock.h
 trigger_server.o: ../../include/mymalloc.h
+trigger_server.o: ../../include/recipient_list.h
 trigger_server.o: ../../include/resolve_local.h
 trigger_server.o: ../../include/safe_open.h
 trigger_server.o: ../../include/sane_accept.h
index aa6f97d1b25da988cba557bf76272ac2b429f3c5..ad19ba2774fb988c9d6c1ee616bc7b2295fbddcb 100644 (file)
 /* .IP "MAIL_SERVER_WATCHDOG (int *)"
 /*     Override the default 1000s watchdog timeout. The value is
 /*     used after command-line and main.cf file processing.
+/* .IP "MAIL_SERVER_BOUNCE_INIT (const char *, const char **)"
+/*     Initialize the DSN filter for the bounce/defer service
+/*     clients with the specified map source and map names.
 /* .PP
 /*     event_server_disconnect() should be called by the application
 /*     to close a client connection.
 #include <resolve_local.h>
 #include <mail_flow.h>
 #include <mail_version.h>
+#include <bounce.h>
 
 /* Process manager. */
 
@@ -556,6 +560,8 @@ NORETURN event_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     char   *generation;
     int     msg_vstream_needed = 0;
     int     redo_syslog_init = 0;
+    const char *ndr_filter_title;
+    const char **ndr_filter_maps;
 
     /*
      * Process environment options as early as we can.
@@ -766,6 +772,11 @@ NORETURN event_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
        case MAIL_SERVER_SLOW_EXIT:
            event_server_slow_exit = va_arg(ap, MAIL_SERVER_SLOW_EXIT_FN);
            break;
+       case MAIL_SERVER_BOUNCE_INIT:
+           ndr_filter_title = va_arg(ap, const char *);
+           ndr_filter_maps = va_arg(ap, const char **);
+           bounce_client_init(ndr_filter_title, *ndr_filter_maps);
+           break;
        default:
            msg_panic("%s: unknown argument type: %d", myname, key);
        }
index 267bdaf03b99fa9511cf6f1c4f73af0009f21423..60b79e3a5997cc53bf1798df5a0ca2e3797fd7b6 100644 (file)
@@ -38,6 +38,7 @@
 
 #define MAIL_SERVER_IN_FLOW_DELAY      20
 #define MAIL_SERVER_SLOW_EXIT  21
+#define MAIL_SERVER_BOUNCE_INIT        22
 
 typedef void (*MAIL_SERVER_INIT_FN) (char *, char **);
 typedef int (*MAIL_SERVER_LOOP_FN) (char *, char **);
index 19c04040d78f9bf8dfa440d42fda725d63858d43..20179207d690c51921492a0842e6519a1b959141 100644 (file)
 /*     This service must be configured with process limit of 0.
 /* .IP MAIL_SERVER_PRIVILEGED
 /*     This service must be configured as privileged.
+/* .IP "MAIL_SERVER_BOUNCE_INIT (const char *, const char **)"
+/*     Initialize the DSN filter for the bounce/defer service
+/*     clients with the specified map source and map names.
 /* .PP
 /*     multi_server_disconnect() should be called by the application
 /*     to close a client connection.
 #include <resolve_local.h>
 #include <mail_flow.h>
 #include <mail_version.h>
+#include <bounce.h>
 
 /* Process manager. */
 
@@ -393,9 +397,9 @@ static void multi_server_wakeup(int fd, HTABLE *attr)
     stream = vstream_fdopen(fd, O_RDWR);
     tmp = concatenate(multi_server_name, " socket", (char *) 0);
     vstream_control(stream,
-                    VSTREAM_CTL_PATH, tmp,
-                    VSTREAM_CTL_CONTEXT, (char *) attr,
-                    VSTREAM_CTL_END);
+                   VSTREAM_CTL_PATH, tmp,
+                   VSTREAM_CTL_CONTEXT, (char *) attr,
+                   VSTREAM_CTL_END);
     myfree(tmp);
     timed_ipc_setup(stream);
     multi_server_saved_flags = vstream_flags(stream);
@@ -552,6 +556,8 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
     char   *generation;
     int     msg_vstream_needed = 0;
     int     redo_syslog_init = 0;
+    const char *ndr_filter_title;
+    const char **ndr_filter_maps;
 
     /*
      * Process environment options as early as we can.
@@ -602,7 +608,7 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
      * Register dictionaries that use higher-level interfaces and protocols.
      */
     mail_dict_init();
+
     /*
      * After database open error, continue execution with reduced
      * functionality.
@@ -756,6 +762,11 @@ NORETURN multi_server_main(int argc, char **argv, MULTI_SERVER_FN service,...)
                msg_fatal("service %s requires privileged operation",
                          service_name);
            break;
+       case MAIL_SERVER_BOUNCE_INIT:
+           ndr_filter_title = va_arg(ap, const char *);
+           ndr_filter_maps = va_arg(ap, const char **);
+           bounce_client_init(ndr_filter_title, *ndr_filter_maps);
+           break;
        default:
            msg_panic("%s: unknown argument type: %d", myname, key);
        }
index 01bc89218a15feb2f0e9b16b7eb63ba9eb9ce183..a5d068a602cfe2aea604fc16d29661ae3519b596 100644 (file)
 /*     This service must be configured with process limit of 0.
 /* .IP MAIL_SERVER_PRIVILEGED
 /*     This service must be configured as privileged.
+/* .IP "MAIL_SERVER_BOUNCE_INIT (const char *, const char **)"
+/*     Initialize the DSN filter for the bounce/defer service
+/*     clients with the specified map source and map names.
 /* .PP
 /*     The var_use_limit variable limits the number of clients that
 /*     a server can service before it commits suicide.
 #include <resolve_local.h>
 #include <mail_flow.h>
 #include <mail_version.h>
+#include <bounce.h>
 
 /* Process manager. */
 
@@ -430,6 +434,8 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
     char   *generation;
     int     msg_vstream_needed = 0;
     int     redo_syslog_init = 0;
+    const char *ndr_filter_title;
+    const char **ndr_filter_maps;
 
     /*
      * Process environment options as early as we can.
@@ -631,6 +637,11 @@ NORETURN single_server_main(int argc, char **argv, SINGLE_SERVER_FN service,...)
                msg_fatal("service %s requires privileged operation",
                          service_name);
            break;
+       case MAIL_SERVER_BOUNCE_INIT:
+           ndr_filter_title = va_arg(ap, const char *);
+           ndr_filter_maps = va_arg(ap, const char **);
+           bounce_client_init(ndr_filter_title, *ndr_filter_maps);
+           break;
        default:
            msg_panic("%s: unknown argument type: %d", myname, key);
        }
index cdfdd75bbddca4f3eddf9501cef2aaa5160af0af..05d3f2f9cc84d51cf08ce1b7e123ab982a58e7e1 100644 (file)
 /* .IP "MAIL_SERVER_WATCHDOG (int *)"
 /*     Override the default 1000s watchdog timeout. The value is
 /*     used after command-line and main.cf file processing.
+/* .IP "MAIL_SERVER_BOUNCE_INIT (const char *, const char **)"
+/*     Initialize the DSN filter for the bounce/defer service
+/*     clients with the specified map source and map names.
 /* .PP
 /*     The var_use_limit variable limits the number of clients that
 /*     a server can service before it commits suicide.
 #include <resolve_local.h>
 #include <mail_flow.h>
 #include <mail_version.h>
+#include <bounce.h>
 
 /* Process manager. */
 
@@ -433,6 +437,8 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
     char   *generation;
     int     msg_vstream_needed = 0;
     int     redo_syslog_init = 0;
+    const char *ndr_filter_title;
+    const char **ndr_filter_maps;
 
     /*
      * Process environment options as early as we can.
@@ -483,7 +489,7 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
      * Register dictionaries that use higher-level interfaces and protocols.
      */
     mail_dict_init();
+
     /*
      * After database open error, continue execution with reduced
      * functionality.
@@ -637,6 +643,11 @@ NORETURN trigger_server_main(int argc, char **argv, TRIGGER_SERVER_FN service,..
        case MAIL_SERVER_WATCHDOG:
            trigger_server_watchdog = *va_arg(ap, int *);
            break;
+       case MAIL_SERVER_BOUNCE_INIT:
+           ndr_filter_title = va_arg(ap, const char *);
+           ndr_filter_maps = va_arg(ap, const char **);
+           bounce_client_init(ndr_filter_title, *ndr_filter_maps);
+           break;
        default:
            msg_panic("%s: unknown argument type: %d", myname, key);
        }
index b2e59e105bff908dce87a5133e049bf4c61e4dc3..35a9a3e791552f9dcac750c4c0ffa4bb3b3f04fb 100644 (file)
 /* .IP "\fBmax_use (100)\fR"
 /*     The maximal number of incoming connections that a Postfix daemon
 /*     process will service before terminating voluntarily.
+/* .IP "\fBpipe_bounce_defer_filter ($default_bounce_defer_filter)\fR"
+/*     Optional filter to change arbitrary hard delivery errors into
+/*     soft errors and vice versa.
 /* .IP "\fBprocess_id (read-only)\fR"
 /*     The process ID of a Postfix command or daemon process.
 /* .IP "\fBprocess_name (read-only)\fR"
   */
 int     var_command_maxtime;           /* You can now leave this here. */
 
+ /*
+  * Other main.cf parameters.
+  */
+char   *var_pipe_ndr_filter;
+
  /*
   * For convenience. Instead of passing around lists of parameters, bundle
   * them up in convenient structures.
@@ -1021,25 +1029,18 @@ static int eval_command_status(int command_status, char *service,
     case PIPE_STAT_BOUNCE:
     case PIPE_STAT_DEFER:
        (void) DSN_FROM_DSN_BUF(why);
-       if (STR(why->status)[0] != '4') {
-           for (n = 0; n < request->rcpt_list.len; n++) {
-               rcpt = request->rcpt_list.info + n;
-               status = bounce_append(DEL_REQ_TRACE_FLAGS(request->flags),
-                                      request->queue_id,
-                                      &request->msg_stats, rcpt,
-                                      service, &why->dsn);
-               if (status == 0)
-                   deliver_completed(request->fp, rcpt->offset);
-               result |= status;
-           }
-       } else {
-           for (n = 0; n < request->rcpt_list.len; n++) {
-               rcpt = request->rcpt_list.info + n;
-               result |= defer_append(DEL_REQ_TRACE_FLAGS(request->flags),
-                                      request->queue_id,
-                                      &request->msg_stats, rcpt,
-                                      service, &why->dsn);
-           }
+       for (n = 0; n < request->rcpt_list.len; n++) {
+           rcpt = request->rcpt_list.info + n;
+           /* XXX Maybe encapsulate this with ndr_append(). */
+           status = (STR(why->status)[0] != '4' ?
+                     bounce_append : defer_append)
+               (DEL_REQ_TRACE_FLAGS(request->flags),
+                request->queue_id,
+                &request->msg_stats, rcpt,
+                service, &why->dsn);
+           if (status == 0)
+               deliver_completed(request->fp, rcpt->offset);
+           result |= status;
        }
        break;
     case PIPE_STAT_CORRUPT:
@@ -1325,6 +1326,10 @@ int     main(int argc, char **argv)
        VAR_COMMAND_MAXTIME, DEF_COMMAND_MAXTIME, &var_command_maxtime, 1, 0,
        0,
     };
+    static const CONFIG_STR_TABLE str_table[] = {
+       VAR_PIPE_NDR_FILTER, DEF_PIPE_NDR_FILTER, &var_pipe_ndr_filter, 0, 0,
+       0,
+    };
 
     /*
      * Fingerprint executables and core dumps.
@@ -1337,5 +1342,7 @@ int     main(int argc, char **argv)
                       MAIL_SERVER_POST_INIT, drop_privileges,
                       MAIL_SERVER_PRE_ACCEPT, pre_accept,
                       MAIL_SERVER_PRIVILEGED,
+                      MAIL_SERVER_BOUNCE_INIT, VAR_PIPE_NDR_FILTER,
+                      &var_pipe_ndr_filter,
                       0);
 }
index a39c6a4981c1437a4d7aa545feaaadc6d5320026..cc17d9b084aa66813484276aa4565e86cdd8d75b 100644 (file)
@@ -57,6 +57,7 @@
        VAR_LMTP_RESP_FILTER, DEF_LMTP_RESP_FILTER, &var_smtp_resp_filter, 0, 0,
        VAR_LMTP_ADDR_PREF, DEF_LMTP_ADDR_PREF, &var_smtp_addr_pref, 1, 0,
        VAR_LMTP_DNS_RES_OPT, DEF_LMTP_DNS_RES_OPT, &var_smtp_dns_res_opt, 0, 0,
+       VAR_LMTP_NDR_FILTER, DEF_LMTP_NDR_FILTER, &var_smtp_ndr_filter, 0, 0,
        0,
     };
     static const CONFIG_TIME_TABLE lmtp_time_table[] = {
index 65beb67c5bf631a25f110066555e5998abd2cd35..1fe10044c800407f67a6b50a0351e84305600140 100644 (file)
 /*     Always send EHLO at the start of an SMTP session.
 /* .IP "\fBsmtp_never_send_ehlo (no)\fR"
 /*     Never send EHLO at the start of an SMTP session.
+/* .IP "\fBsmtp_bounce_defer_filter ($default_bounce_defer_filter)\fR"
+/*     Optional filter to change arbitrary hard delivery errors into
+/*     soft errors and vice versa.
 /* .IP "\fBsmtp_defer_if_no_mx_address_found (no)\fR"
 /*     Defer mail delivery when no MX record resolves to an IP address.
 /* .IP "\fBsmtp_line_length_limit (998)\fR"
@@ -876,6 +879,7 @@ char   *var_smtp_dns_res_opt;
 char   *var_smtp_dns_support;
 bool    var_smtp_rec_deadline;
 bool    var_smtp_dummy_mail_auth;
+char   *var_smtp_ndr_filter;
 
  /* Special handling of 535 AUTH errors. */
 char   *var_smtp_sasl_auth_cache_name;
@@ -1271,5 +1275,7 @@ int     main(int argc, char **argv)
                       MAIL_SERVER_PRE_INIT, pre_init,
                       MAIL_SERVER_POST_INIT, post_init,
                       MAIL_SERVER_PRE_ACCEPT, pre_accept,
+                      MAIL_SERVER_BOUNCE_INIT, VAR_SMTP_NDR_FILTER,
+                      &var_smtp_ndr_filter,
                       0);
 }
index 3f7aeea0753f18ffd0012d7010123d349e0a7081..5fcbed6dbc942424e006d0056d5ca79dcbf9e16e 100644 (file)
@@ -510,7 +510,7 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path)
      */
 #ifdef USE_TLS
     if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
-       msg_info("TLS policy lookup error for %s/%s: %s",
+       msg_warn("TLS policy lookup error for %s/%s: %s",
                 STR(iter->host), STR(iter->addr), STR(why->reason));
        return;
     }
@@ -716,7 +716,7 @@ static int smtp_reuse_session(SMTP_STATE *state, DNS_RR **addr_list,
        iter->rr = addr;
 #ifdef USE_TLS
        if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
-           msg_info("TLS policy lookup error for %s/%s: %s",
+           msg_warn("TLS policy lookup error for %s/%s: %s",
                     STR(iter->dest), STR(iter->host), STR(why->reason));
            continue;
            /* XXX Assume there is no code at the end of this loop. */
@@ -956,7 +956,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
            iter->rr = addr;
 #ifdef USE_TLS
            if (!smtp_tls_policy_cache_query(why, state->tls, iter)) {
-               msg_info("TLS policy lookup for %s/%s: %s",
+               msg_warn("TLS policy lookup for %s/%s: %s",
                         STR(iter->dest), STR(iter->host), STR(why->reason));
                continue;
                /* XXX Assume there is no code at the end of this loop. */
index 98c93b36897c0f14341c5ad7701ab6bc55da3bde..616ca7ad8c7da67e32fbfde3015b353cf652d633 100644 (file)
@@ -58,6 +58,7 @@
        VAR_SMTP_RESP_FILTER, DEF_SMTP_RESP_FILTER, &var_smtp_resp_filter, 0, 0,
        VAR_SMTP_ADDR_PREF, DEF_SMTP_ADDR_PREF, &var_smtp_addr_pref, 1, 0,
        VAR_SMTP_DNS_RES_OPT, DEF_SMTP_DNS_RES_OPT, &var_smtp_dns_res_opt, 0, 0,
+       VAR_SMTP_NDR_FILTER, DEF_SMTP_NDR_FILTER, &var_smtp_ndr_filter, 0, 0,
        0,
     };
     static const CONFIG_TIME_TABLE smtp_time_table[] = {
index 15880a3167739007279e97626cb754a78c3a5662..f280810e1e9c76e1e633442aa267386af257378c 100644 (file)
@@ -525,8 +525,8 @@ static void *policy_create(const char *unused_key, void *context)
     /*
      * DANE initialization may change the security level to something else,
      * so do this early, so that we use the right level below.  Note that
-     * "dane-only" changes to "dane" after any fallback strategies are
-     * applied.
+     * "dane-only" changes to "dane" once we obtain the requisite TLSA
+     * records.
      */
     if (tls->level == TLS_LEV_DANE || tls->level == TLS_LEV_DANE_ONLY)
        dane_init(tls, iter);
@@ -706,6 +706,7 @@ static int global_tls_level(void)
 
 #define NONDANE_CONFIG 0               /* Administrator's fault */
 #define NONDANE_DEST   1               /* Remote server's fault */
+#define DANE_UNUSABLE  2               /* Remote server's fault */
 
 static void PRINTFLIKE(4, 5) dane_incompat(SMTP_TLS_POLICY *tls,
                                                   SMTP_ITERATOR *iter,
@@ -716,12 +717,12 @@ static void PRINTFLIKE(4, 5) dane_incompat(SMTP_TLS_POLICY *tls,
 
     va_start(ap, fmt);
     if (tls->level == TLS_LEV_DANE) {
-       tls->level = TLS_LEV_MAY;
+       tls->level = (errtype == DANE_UNUSABLE) ? TLS_LEV_ENCRYPT : TLS_LEV_MAY;
        if (errtype == NONDANE_CONFIG)
            vmsg_warn(fmt, ap);
        else if (msg_verbose)
            vmsg_info(fmt, ap);
-    } else {
+    } else {                                   /* dane-only */
        if (errtype == NONDANE_CONFIG) {
            vmsg_warn(fmt, ap);
            MARK_INVALID(tls->why, &tls->level);
@@ -816,7 +817,8 @@ static void dane_init(SMTP_TLS_POLICY *tls, SMTP_ITERATOR *iter)
      * given verifier some of the CAs are surely not trustworthy).
      */
     if (tls_dane_unusable(dane)) {
-       dane_incompat(tls, iter, NONDANE_DEST, "TLSA records unusable");
+       dane_incompat(tls, iter, DANE_UNUSABLE, "TLSA records unusable");
+       tls_dane_free(dane);
        return;
     }
 
index 386e9668fb18cb7234207a7b74e93261ffe642bb..b976b7bfcf5dae61fb44f056547b12955a4ea3eb 100644 (file)
 /*     The policy is: non-final server: log an informational record
 /*     with the reason why the host is being skipped; final server:
 /*     defer delivery of all remaining recipients.
+/*     Retry plaintext delivery after TLS post-handshake session
+/*     failure, provided that at least one recipient was not
+/*     deferred or rejected during the TLS phase, and that global
+/*     preconditions for plaintext fallback are met.
 /*     The session is marked as "do not cache".
 /*     The result is non-zero.
 /*
index 8fdcb62fd40838fe34273c7b924d3d5d58fa2ab4..79175eef7c44c5c73f468bc2d7cc4f70609ea31d 100644 (file)
@@ -4783,6 +4783,16 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient,
                                   recipient, reply_class,
                                   dp.text));
     }
+    if (strcmp(STR(reply->transport), MAIL_SERVICE_RETRY) == 0) {
+       dsn_split(&dp, strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
+                 "4.1.0" : "4.1.1", STR(reply->nexthop));
+       return (smtpd_check_reject(state, MAIL_ERROR_BOUNCE, 450,
+                                  smtpd_dsn_fix(DSN_STATUS(dp.dsn),
+                                                reply_class),
+                                  "<%s>: %s rejected: %s",
+                                  recipient, reply_class,
+                                  dp.text));
+    }
 
     /*
      * Search the recipient lookup tables of the respective address class.
index 61937ae42e20b36eba153c656fd3ca87bcb6fa9a..1fe782ff76a4dd2352d661f570dd7fe5b03bf5b9 100644 (file)
@@ -152,7 +152,8 @@ static void update_entry(const char *new_channel, const char *new_nexthop,
        vstring_strcpy(channel, new_channel);
        if (*new_nexthop != 0)
            vstring_strcpy(nexthop, new_nexthop);
-       else if (strcmp(STR(channel), MAIL_SERVICE_ERROR) != 0)
+       else if (strcmp(STR(channel), MAIL_SERVICE_ERROR) != 0
+                && strcmp(STR(channel), MAIL_SERVICE_RETRY) != 0)
            vstring_strcpy(nexthop, rcpt_domain);
        else
            vstring_strcpy(nexthop, "Address is undeliverable");
index 95eab25089ffbee21c0e197b1eed32157939d628..106ad780487d27255d728bd5d7db51a50c29927a 100644 (file)
 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
 /*     The mail system name that is prepended to the process name in syslog
 /*     records, so that "smtpd" becomes, for example, "postfix/smtpd".
+/* .IP "\fBvirtual_bounce_defer_filter ($default_bounce_defer_filter)\fR"
+/*     Optional filter to change arbitrary hard delivery errors into
+/*     soft errors and vice versa.
 /* SEE ALSO
 /*     qmgr(8), queue manager
 /*     bounce(8), delivery status reports
@@ -334,6 +337,7 @@ char   *var_virt_mailbox_lock;
 long    var_virt_mailbox_limit;
 char   *var_mail_spool_dir;            /* XXX dependency fix */
 bool    var_strict_mbox_owner;
+char   *var_virt_ndr_filter;
 
  /*
   * Mappings.
@@ -510,6 +514,7 @@ int     main(int argc, char **argv)
        VAR_VIRT_GID_MAPS, DEF_VIRT_GID_MAPS, &var_virt_gid_maps, 0, 0,
        VAR_VIRT_MAILBOX_BASE, DEF_VIRT_MAILBOX_BASE, &var_virt_mailbox_base, 1, 0,
        VAR_VIRT_MAILBOX_LOCK, DEF_VIRT_MAILBOX_LOCK, &var_virt_mailbox_lock, 1, 0,
+       VAR_VIRT_NDR_FILTER, DEF_VIRT_NDR_FILTER, &var_virt_ndr_filter, 0, 0,
        0,
     };
     static const CONFIG_BOOL_TABLE bool_table[] = {
@@ -531,5 +536,7 @@ int     main(int argc, char **argv)
                       MAIL_SERVER_POST_INIT, post_init,
                       MAIL_SERVER_PRE_ACCEPT, pre_accept,
                       MAIL_SERVER_PRIVILEGED,
+                      MAIL_SERVER_BOUNCE_INIT, VAR_VIRT_NDR_FILTER,
+                      &var_virt_ndr_filter,
                       0);
 }