]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.12-20141126
authorWietse Venema <wietse@porcupine.org>
Wed, 26 Nov 2014 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <postfix-users@dukhovni.org>
Thu, 27 Nov 2014 05:02:20 +0000 (00:02 -0500)
53 files changed:
postfix/.indent.pro
postfix/HISTORY
postfix/README_FILES/AAAREADME
postfix/README_FILES/BUILTIN_FILTER_README
postfix/README_FILES/COMPATIBILITY_README
postfix/README_FILES/DATABASE_README
postfix/RELEASE_NOTES
postfix/WISHLIST
postfix/html/BUILTIN_FILTER_README.html
postfix/html/COMPATIBILITY_README.html
postfix/html/DATABASE_README.html
postfix/html/index.html
postfix/html/postconf.1.html
postfix/html/postconf.5.html
postfix/html/smtpd.8.html
postfix/man/man1/postconf.1
postfix/man/man5/postconf.5
postfix/man/man8/smtpd.8
postfix/mantools/postlink
postfix/proto/BUILTIN_FILTER_README.html
postfix/proto/COMPATIBILITY_README.html
postfix/proto/DATABASE_README.html
postfix/proto/postconf.proto
postfix/src/dns/Makefile.in
postfix/src/dns/dns.h
postfix/src/dns/dns_lookup.c
postfix/src/dns/mxonly_test.ref [new file with mode: 0644]
postfix/src/dns/nullmx_test.ref [new file with mode: 0644]
postfix/src/dns/nxdomain_test.ref [new file with mode: 0644]
postfix/src/dns/test_dns_lookup.c
postfix/src/global/header_body_checks.c
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/global/mime_state.c
postfix/src/postconf/postconf.c
postfix/src/posttls-finger/posttls-finger.c
postfix/src/smtp/smtp_addr.c
postfix/src/smtpd/Makefile.in
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/smtpd/smtpd_check.ref
postfix/src/smtpd/smtpd_check_access
postfix/src/smtpd/smtpd_nullmx.in [new file with mode: 0644]
postfix/src/smtpd/smtpd_nullmx.ref [new file with mode: 0644]
postfix/src/smtpd/smtpd_resolve.c
postfix/src/smtpd/smtpd_server.ref
postfix/src/util/Makefile.in
postfix/src/util/dict_inline.c [new file with mode: 0644]
postfix/src/util/dict_inline.h [new file with mode: 0644]
postfix/src/util/dict_inline.ref [new file with mode: 0644]
postfix/src/util/dict_open.c
postfix/src/util/dict_static.c
postfix/src/util/dict_static.ref [new file with mode: 0644]

index eca753160d855ade74d87d3601d731440637e6d3..b9f3a9ea13396362747966a7760e8da152eecf42 100644 (file)
@@ -82,6 +82,7 @@
 -TDICT_ENV
 -TDICT_FAIL
 -TDICT_HT
+-TDICT_INLINE
 -TDICT_LDAP
 -TDICT_LMDB
 -TDICT_MC
index 60f891e0d881049aa16942563849b705de195005..97c7109f37dc37ab84feaae11b155453abd79859 100644 (file)
@@ -20799,3 +20799,47 @@ Apologies for any names omitted.
        Cleanup: don't write back-to-back queue file pointer records
        when the "add recipient" action was a NOOP (e.g., because
        the recipient was a duplicate). File: cleanup/cleanup_milter.c.
+
+20141120
+
+       Documentation: COMPATIBILITY_README now has "purpose of
+       this document" section, plus a separate section for turning
+       off the safety net. File: proto/COMPATIBILITY_README.html
+
+20131121
+
+       Cleanup: replace mua_mumble with msa_mumble in master.cf
+       submission and smtps service parameter overrides. File:
+       proto/BUILTIN_FILTER_README.html.
+
+       Feature: "static:{ text with whitespace }".  This could be
+       used as check_mumble_access static:{reject text...} at the
+       end of smtpd_mumble_restrictions. Files: util/dict_static.c,
+       util/Makefile.in, util/dict_static_test.ref,
+       proto/DATABASE_README.html.  postconf/postconf.c (manpage).
+
+20141126
+
+       Feature: "inline:{key=value, { key = text with comma/space}}
+       avoids the need to create a database for just a few entries.
+       Files: util/dict_inline.[hc], mantools/postlink,
+       proto/DATABASE_README.html. postconf/postconf.c (manpage),
+       util/dict_inline.[hc], util/dict_open.c, util/Makefile.in,
+       util/dict_inline_test.ref.
+
+       Cleanup: report nullmx DNS records as "domain does not
+       accept mail", instead of "invalid DNS response".  The Postfix
+       SMTP client already bounced mail for such domains, and the
+       Postfix SMTP server already rejected such domains with
+       reject_unknown_sender/recipient_domain. This introduces a
+       new SMTP server configuration parameter nullmx_reject_code
+       (default: 556).  Files: src/dns/dns_lookup.[hc], dns/Makefile,in,
+       dns/nullmx_test.ref, src/smtp/smtp_addr.c, src/smtpd/smtpd_check.c,
+       smtpd/smtpd_check_nullmx.in, smtpd/smtpd_check_nullmx.ref,
+       mantools/postlink, proto/postconf.proto, smtpd/smtpd.c.
+
+       Cleanup: added some missing libdns tests: dns/Makefile,in,
+       dns/mxonly_test,ref, dns/nxdomain_test.ref
+
+       Cleanup: libglobal "make test" had suffered from bitrot.
+       Files: global/mime_state.c, global/header_body_checks.c.
index e966f2cbaa4f60be6af46607c014839e8f100d08..d4e10f0706824aac4dffe91bc345e67b6830c60c 100644 (file)
@@ -13,8 +13,8 @@ G\bGe\ben\bne\ber\bra\bal\bl c\bco\bon\bnf\bfi\big\bgu\bur\bra\bat\bti\bio\bon\bn
   * FORWARD_SECRECY_README: TLS Forward Secrecy
   * IPV6_README: IP Version 6 Support
   * IPV6_README: IP Version 6 Support
-  * SMTPUTF8_README: SMTPUTF8 support
-  * COMPATIBILITY_README: Backwards-Compatibility Support
+  * SMTPUTF8_README: SMTPUTF8 Support
+  * COMPATIBILITY_README: Backwards-Compatibility Safety Net
   * INSTALL: Installation from source code
 
 P\bPr\bro\bob\bbl\ble\bem\bm s\bso\bol\blv\bvi\bin\bng\bg
index 36740fdc5236cdd05d396990233d5388eb44ce86..5ed04169de4c4a65235cbd58df7b599088238b7c 100644 (file)
@@ -265,11 +265,11 @@ First, we define a few "user-defined" parameters that will override settings
 for the submission and smtps services.
 
     /etc/postfix/main.cf:
-        mua_cleanup_service_name = mua_cleanup
-        mua_header_checks = pcre:/etc/postfix/mua_header_checks
-        mua_body_checks = pcre:/etc/postfix/mua_body_checks
+        msa_cleanup_service_name = msa_cleanup
+        msa_header_checks = pcre:/etc/postfix/msa_header_checks
+        msa_body_checks = pcre:/etc/postfix/msa_body_checks
 
-Next, we define mua_cleanup as a dedicated cleanup service that will be used
+Next, we define msa_cleanup as a dedicated cleanup service that will be used
 only by the submission and smtps services. This service uses the header_checks
 and body_checks overrides that were defined above.
 
@@ -279,20 +279,20 @@ and body_checks overrides that were defined above.
         #                   (yes)   (yes)   (yes)   (never) (100)
         # =================================================================
         smtp          inet  n       -       n       -       -       smtpd
-        mua_cleanup   unix  n       -       n       -       0       cleanup
-            -o header_checks=$mua_header_checks
-            -o body_checks=$mua_body_checks
+        msa_cleanup   unix  n       -       n       -       0       cleanup
+            -o header_checks=$msa_header_checks
+            -o body_checks=$msa_body_checks
         submission    inet  n       -       n       -       -       smtpd
-            -o cleanup_service_name=$mua_cleanup_service_name
+            -o cleanup_service_name=$msa_cleanup_service_name
             -o syslog_name=postfix/submission
             ...[see sample master.cf file for more]...
         smtps         inet  n       -       n       -       -       smtpd
-            -o cleanup_service_name=$mua_cleanup_service_name
+            -o cleanup_service_name=$msa_cleanup_service_name
             -o syslog_name=postfix/smtps
             -o smtpd_tls_wrappermode=yes
             ...[see sample master.cf file for more]...
 
-By keeping the "mua_xxx" parameter settings in main.cf, you keep your master.cf
+By keeping the "msa_xxx" parameter settings in main.cf, you keep your master.cf
 file simple, and you minimize the amount of duplication.
 
 C\bCo\bon\bnf\bfi\big\bgu\bur\bri\bin\bng\bg h\bhe\bea\bad\bde\ber\br/\b/b\bbo\bod\bdy\by c\bch\bhe\bec\bck\bks\bs f\bfo\bor\br m\bma\bai\bil\bl t\bto\bo s\bso\bom\bme\be d\bdo\bom\bma\bai\bin\bns\bs o\bon\bnl\bly\by
index 74d7c579f74b5ebb36d9876912f8a8ddab3475a6..f3978c15bdadc925eed2d8d7b17b58a24b5029c7 100644 (file)
@@ -1,18 +1,33 @@
-P\bPo\bos\bst\btf\bfi\bix\bx B\bBa\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-C\bCo\bom\bmp\bpa\bat\bti\bib\bbi\bil\bli\bit\bty\by S\bSu\bup\bpp\bpo\bor\brt\bt
+P\bPo\bos\bst\btf\bfi\bix\bx B\bBa\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-C\bCo\bom\bmp\bpa\bat\bti\bib\bbi\bil\bli\bit\bty\by S\bSa\baf\bft\bty\by N\bNe\bet\bt
 
 -------------------------------------------------------------------------------
 
+P\bPu\bur\brp\bpo\bos\bse\be o\bof\bf t\bth\bhi\bis\bs d\bdo\boc\bcu\bum\bme\ben\bnt\bt
+
+Postfix 2.12 introduces a safety net that runs Postfix programs with backwards-
+compatible default settings after an upgrade. The safety net will log a warning
+whenever a "new" default setting could have an negative effect on your mail
+flow.
+
+This document provides information on the following topics:
+
+  * Detailed descriptions of Postfix backwards-compatibility warnings.
+
+  * What backwards-compatible settings you may have to make permanent in
+    main.cf or master.cf.
+
+  * How to turn off Postfix backwards-compatibility warnings.
+
 O\bOv\bve\ber\brv\bvi\bie\bew\bw
 
-Postfix 2.12 introduces a safety net that causes Postfix programs to run with
-backwards-compatible default settings after an upgrade to a newer Postfix
-version. Backwards compatibility is turned on when the main.cf
-compatibility_level value is less than the Postfix built-in value.
+With backwards compatibility turned on, Postfix logs a message whenever a
+backwards-compatible default setting may be required for continuity of service.
+Based on this logging the system administrator can decide if any backwards-
+compatible settings need to be made permanent in main.cf or master.cf, before
+turning off the backwards-compatibility safety net as described at the end of
+this document.
 
-With backwards compatibility turned on, Postfix looks for settings that are
-left at their implicit default value, and logs a message when a backwards-
-compatible default setting is required for continuity of service. The following
-messages may be logged:
+The following messages may be logged:
 
   * Using backwards-compatible default setting append_dot_mydomain=yes
 
@@ -29,19 +44,8 @@ administrator should make the backwards-compatible setting permanent in main.cf
 or master.cf, as detailed in the sections that follow.
 
 When no more backwards-compatible settings need to be made permanent, the
-administrator should turn off backwards compatibility by updating the
-compatibility_level setting in main.cf.
-
-    # p\bpo\bos\bst\btc\bco\bon\bnf\bf c\bco\bom\bmp\bpa\bat\bti\bib\bbi\bil\bli\bit\bty\by_\b_l\ble\bev\bve\bel\bl=\b=N\bN
-    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
-
-For N specify the number that is logged in your postfix(1) warning message:
-
-    warning: To disable backwards compatibility use "postconf
-    compatibility_level=N" and "postfix reload"
-
-Sites that don't care about backwards compatibility may set
-"compatibility_level = 9999" at their own risk.
+system administrator should turn off the backwards-compatibility safety net as
+described at the end of this document.
 
 U\bUs\bsi\bin\bng\bg b\bba\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-c\bco\bom\bmp\bpa\bat\bti\bib\bbl\ble\be d\bde\bef\bfa\bau\bul\blt\bt s\bse\bet\btt\bti\bin\bng\bg a\bap\bpp\bpe\ben\bnd\bd_\b_d\bdo\bot\bt_\b_m\bmy\byd\bdo\bom\bma\bai\bin\bn=\b=y\bye\bes\bs
 
@@ -175,3 +179,19 @@ setting "smtputf8_enable = no" permanent in main.cf:
     # p\bpo\bos\bst\btc\bco\bon\bnf\bf s\bsm\bmt\btp\bpu\but\btf\bf8\b8_\b_e\ben\bna\bab\bbl\ble\be=\b=n\bno\bo
     # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
 
+T\bTu\bur\brn\bni\bin\bng\bg o\bof\bff\bf t\bth\bhe\be b\bba\bac\bck\bkw\bwa\bar\brd\bds\bs-\b-c\bco\bom\bmp\bpa\bat\bti\bib\bbi\bil\bli\bit\bty\by s\bsa\baf\bfe\bet\bty\by n\bne\bet\bt
+
+Backwards compatibility is turned off by updating the compatibility_level
+setting in main.cf.
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf c\bco\bom\bmp\bpa\bat\bti\bib\bbi\bil\bli\bit\bty\by_\b_l\ble\bev\bve\bel\bl=\b=N\bN
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+For N specify the number that is logged in your postfix(1) warning message:
+
+    warning: To disable backwards compatibility use "postconf
+    compatibility_level=N" and "postfix reload"
+
+Sites that don't care about backwards compatibility may set
+"compatibility_level = 9999" at their own risk.
+
index 2d4d4ffa840ce5145c1287bd433018aaa25472a6..0eb2c3aedce7856836351990564fb56b6edc2930 100644 (file)
@@ -212,6 +212,12 @@ To find out what database types your Postfix system supports, use the "p\bpo\bos\bs
         are created with the postmap(1) or postalias(1) command, and private
         databases are maintained by Postfix daemons. The database name as used
         in "hash:table" is the database file name without the ".db" suffix.
+    inline (read-only)
+        A non-shared, in-memory lookup table. Example: "inline:{ key=value,
+        { key = text with whitespace or comma }}". Key-value pairs are
+        separated by whitespace or comma; whitespace after "{" and before "}"
+        is ignored. Inline tables eliminate the need to create a database file
+        for just a few fixed elements. See also the static: map type.
     i\bin\bnt\bte\ber\brn\bna\bal\bl
         A non-shared, in-memory hash table. Its content are lost when a process
         terminates.
@@ -282,6 +288,9 @@ To find out what database types your Postfix system supports, use the "p\bpo\bos\bs
     s\bst\bta\bat\bti\bic\bc (read-only)
         A table that always returns its name as the lookup result. For example,
         "static:foobar" always returns the string "foobar" as lookup result.
+        Specify "static:{ text with whitespace }" when the result contains
+        whitespace; this form ignores whitespace after "{" and before "}". See
+        also the inline: map type.
     t\btc\bcp\bp
         TCP/IP client. The protocol is described in tcp_table(5). The lookup
         table name is "tcp:host:port" where "host" specifies a symbolic
index 59aba34e45c66403097082f7a3902196b7964a04..585c45dfd72dee888f75aa06ac2ea3f0581a13ed 100644 (file)
@@ -59,6 +59,30 @@ Maintainers may also benefit from the makedefs documentation
 (mantools/srctoman - makedefs | nroff -man | less) with information
 about build options that are not described in the INSTALL instructions.
 
+Major changes with snapshot 20141126
+====================================
+
+Nullmx support (MX records with a null hostname). This change affects
+error messages only.  The Postfix SMTP client already bounced mail
+for such domains, and the Postfix SMTP server already rejected such
+domains with reject_unknown_sender/recipient_domain. This introduces
+a new SMTP server configuration parameter nullmx_reject_code (default:
+556).
+
+Major changes with snapshot 20141119
+====================================
+
+Support for BCC actions in header/body_checks and milter_header_checks.
+There is no limit on the number of BCC actions that may be specified,
+other than the implicit limit due to finite storage. BCC support
+will not be implemented in Postfix delivery agents.
+
+It works in the same way as always_bcc and sender/recipient_bcc_maps:
+there can be only one address per action, recipients are added with
+the NOTIFY=NONE delivery status notification option, and duplicate
+recipients are ignored (with the same delivery status notification
+options).
+
 Major changes with snapshot 20141011
 ====================================
 
index 9c8988a9dbe28b220908d15907b97b7f7d3155fa..693f37bf354160a5a6cf215af94c004166414a38 100644 (file)
@@ -8,17 +8,20 @@ Wish list:
 
        Things to do after the stable release:
 
+       Log command=good/bad statistics in postscreen?
+
+       Implement smtpd_client_auth_rate limit?
+
        Make the access map BCC action consistent with header_checks.
 
+       smtpd_checks tests either must use a DNS dummy resolver
+       (override the res_search API) or all names must be under
+       porcupine.org (but that does not work for address->name
+       lookups, and cannot simulate some errors).
+
        Find a way to show non-default OPT, DEBUG etc. settings at
        the top of the makedefs.out file.
 
-       Inline table for quick tests.  Short form example: inline:{
-       name1=value1, name2=value2 } would instantiate a table with
-       tuples (name1, value1) and (name2, value2). Long form example
-       allows space around =, and space/comma in values: inline:{
-       { name1 = value1 }, { name2 = value2 } }.
-
        Update smtputf8_enable in postconf(5)
 
        Clobber ORCPT when sender is owner-mumble?
index 35882242d02e0262a52e8897d2028e70b8644c01..8550a985e0472272d4c990bca029f6d4e658d329 100644 (file)
@@ -414,13 +414,13 @@ override settings for the submission and smtps services. </p>
 <blockquote>
 <pre>
 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
-    mua_cleanup_service_name = mua_cleanup
-    mua_header_checks = <a href="pcre_table.5.html">pcre</a>:/etc/postfix/mua_header_checks
-    mua_body_checks = <a href="pcre_table.5.html">pcre</a>:/etc/postfix/mua_body_checks
+    msa_cleanup_service_name = msa_cleanup
+    msa_header_checks = <a href="pcre_table.5.html">pcre</a>:/etc/postfix/msa_header_checks
+    msa_body_checks = <a href="pcre_table.5.html">pcre</a>:/etc/postfix/msa_body_checks
 </pre>
 </blockquote>
 
-<p> Next, we define mua_cleanup as a dedicated cleanup service that
+<p> Next, we define msa_cleanup as a dedicated cleanup service that
 will be used only by the submission and smtps services.  This service
 uses the <a href="postconf.5.html#header_checks">header_checks</a> and <a href="postconf.5.html#body_checks">body_checks</a> overrides that were defined
 above. </p>
@@ -433,22 +433,22 @@ above. </p>
     #                   (yes)   (yes)   (yes)   (never) (100)
     # =================================================================
     smtp          inet  n       -       n       -       -       smtpd
-    mua_cleanup   unix  n       -       n       -       0       cleanup
-        -o <a href="postconf.5.html#header_checks">header_checks</a>=$mua_header_checks
-        -o <a href="postconf.5.html#body_checks">body_checks</a>=$mua_body_checks
+    msa_cleanup   unix  n       -       n       -       0       cleanup
+        -o <a href="postconf.5.html#header_checks">header_checks</a>=$msa_header_checks
+        -o <a href="postconf.5.html#body_checks">body_checks</a>=$msa_body_checks
     submission    inet  n       -       n       -       -       smtpd
-        -o <a href="postconf.5.html#cleanup_service_name">cleanup_service_name</a>=$mua_cleanup_service_name
+        -o <a href="postconf.5.html#cleanup_service_name">cleanup_service_name</a>=$msa_cleanup_service_name
         -o <a href="postconf.5.html#syslog_name">syslog_name</a>=postfix/submission
         <i>...[see sample <a href="master.5.html">master.cf</a> file for more]...</i>
     smtps         inet  n       -       n       -       -       smtpd
-        -o <a href="postconf.5.html#cleanup_service_name">cleanup_service_name</a>=$mua_cleanup_service_name
+        -o <a href="postconf.5.html#cleanup_service_name">cleanup_service_name</a>=$msa_cleanup_service_name
         -o <a href="postconf.5.html#syslog_name">syslog_name</a>=postfix/smtps
         -o <a href="postconf.5.html#smtpd_tls_wrappermode">smtpd_tls_wrappermode</a>=yes
         <i>...[see sample <a href="master.5.html">master.cf</a> file for more]...</i>
 </pre>
 </blockquote>
 
-<p> By keeping the "mua_xxx" parameter settings in <a href="postconf.5.html">main.cf</a>, you
+<p> By keeping the "msa_xxx" parameter settings in <a href="postconf.5.html">main.cf</a>, you
 keep your <a href="master.5.html">master.cf</a> file simple, and you minimize the amount
 of duplication. </p>
 
index 56e242ab8d41f3f821009c384ead6243caa93f2f..4c0cfdb8a0e944584fd3981618fa6d4d68cb495e 100644 (file)
@@ -5,7 +5,7 @@
 
 <head>
 
-<title>Postfix Backwards-Compatibility Support</title>
+<title>Postfix Backwards-Compatibility Safty Net</title>
 
 <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
 
 <body>
 
 <h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
-Backwards-Compatibility Support</h1>
+Backwards-Compatibility Safty Net</h1>
 
 <hr>
 
-<h2>Overview </h2>
+<h2>Purpose of this document </h2>
 
-<p> Postfix 2.12 introduces a safety net that causes Postfix programs
-to run with backwards-compatible default settings after an upgrade
-to a newer Postfix version.  Backwards compatibility is turned on
-when the <a href="postconf.5.html">main.cf</a> <a href="postconf.5.html#compatibility_level">compatibility_level</a> value is less than the Postfix
-built-in value. </p>
+<p> Postfix 2.12 introduces a safety net that runs Postfix programs
+with backwards-compatible default settings after an upgrade. The
+safety net will log a warning whenever a "new" default setting could
+have an negative effect on your mail flow. </p>
 
-<p> With backwards compatibility turned on, Postfix looks for
-settings that are left at their implicit default value, and logs a
-message when a backwards-compatible default setting is required for
-continuity of service.  The following messages may be logged: </p>
+<p>This document provides information on the following topics: </p>
+
+<ul>
+
+<li> <p> <a href="#overview">Detailed descriptions</a> of Postfix
+backwards-compatibility warnings.
+
+<li> <p> What backwards-compatible settings you may have to make
+permanent in <a href="postconf.5.html">main.cf</a> or <a href="master.5.html">master.cf</a>.  </p>
+
+<li> <p> <a href="#turnoff">How to turn off</a> Postfix
+backwards-compatibility warnings. </p>
+
+</ul>
+
+<h2> <a name="overview"> Overview </a> </h2>
+
+<p>  With backwards compatibility turned on, Postfix logs a message
+whenever a backwards-compatible default setting may be required for
+continuity of service.  Based on this logging the system administrator
+can decide if any backwards-compatible settings need to be made
+permanent in main.cf or master.cf, before <a href="#turnoff">turning
+off the backwards-compatibility safety net</a> as described at the
+end of this document.  </p>
+
+<p> The following messages may be logged: </p>
 
 <ul>
 
@@ -56,27 +77,9 @@ setting permanent in <a href="postconf.5.html">main.cf</a> or <a href="master.5.
 sections that follow. </p>
 
 <p> When no more backwards-compatible settings need to be made
-permanent, the administrator should turn off backwards compatibility
-by updating the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting in <a href="postconf.5.html">main.cf</a>. </p>
-
-<blockquote>
-<pre>
-# <b>postconf <a href="postconf.5.html#compatibility_level">compatibility_level</a>=<i>N</i></b>
-# <b>postfix reload</b>
-</pre>
-</blockquote>
-
-<p> For <i>N</i> specify the number that is logged in your <a href="postfix.1.html">postfix(1)</a>
-warning message: </p>
-
-<blockquote>
-<pre>
-warning: To disable backwards compatibility use "postconf <a href="postconf.5.html#compatibility_level">compatibility_level</a>=<i>N</i>" and "postfix reload"
-</pre>
-</blockquote>
-
-<p> Sites that don't care about backwards compatibility may set
-"<a href="postconf.5.html#compatibility_level">compatibility_level</a> = 9999" at their own risk. </p>
+permanent, the system administrator should <a href="#turnoff">turn
+off the backwards-compatibility safety net</a> as described at the
+end of this document.  </p>
 
 <h2> <a name="append_dot_mydomain"> Using backwards-compatible default
 setting append_dot_mydomain=yes</a> </h2>
@@ -295,6 +298,30 @@ in <a href="postconf.5.html">main.cf</a>:
 </pre>
 </blockquote>
 
+<h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2>
+
+<p> Backwards compatibility is turned off by updating the
+<a href="postconf.5.html#compatibility_level">compatibility_level</a> setting in <a href="postconf.5.html">main.cf</a>. </p>
+
+<blockquote>
+<pre>
+# <b>postconf <a href="postconf.5.html#compatibility_level">compatibility_level</a>=<i>N</i></b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> For <i>N</i> specify the number that is logged in your <a href="postfix.1.html">postfix(1)</a>
+warning message: </p>
+
+<blockquote>
+<pre>
+warning: To disable backwards compatibility use "postconf <a href="postconf.5.html#compatibility_level">compatibility_level</a>=<i>N</i>" and "postfix reload"
+</pre>
+</blockquote>
+
+<p> Sites that don't care about backwards compatibility may set
+"<a href="postconf.5.html#compatibility_level">compatibility_level</a> = 9999" at their own risk. </p>
+
 </body>
 
 </html>
index b90023dc58773b383cd2056d8f6a65462f3c9519..25bef163ac86ae67d98329ad1482e1d3763a9501 100644 (file)
@@ -313,6 +313,15 @@ private databases are maintained by Postfix daemons. The database
 name as used in "<a href="DATABASE_README.html#types">hash</a>:table" is the database file name without the
 ".db" suffix.  </dd>
 
+<dt> <b></b>inline (read-only) </dt>
+
+<dd> A non-shared, in-memory lookup table. Example: "<a href="DATABASE_README.html#types">inline</a>:{
+<i>key=value</i>, { <i>key = text with whitespace or comma</i> }}".
+Key-value pairs are separated by whitespace or comma; whitespace
+after "{" and before "}" is ignored. Inline tables eliminate the
+need to create a database file for just a few fixed elements. See
+also the <a href="DATABASE_README.html#types">static</a>: map type. </dd>
+
 <dt> <b>internal</b> </dt>
 
 <dd> A non-shared, in-memory hash table. Its content are lost when
@@ -425,7 +434,9 @@ server. See <a href="socketmap_table.5.html">socketmap_table(5)</a> for details.
 
 <dd> A table that always returns its name as the lookup result.
 For example, "<a href="DATABASE_README.html#types">static</a>:foobar" always returns the string "foobar" as
-lookup result. </dd>
+lookup result. Specify "<a href="DATABASE_README.html#types">static</a>:{ <i>text with whitespace</i> }"
+when the result contains whitespace; this form ignores whitespace
+after "{" and before "}". See also the <a href="DATABASE_README.html#types">inline</a>: map type.  </dd>
 
 <dt> <b>tcp</b> </dt>
 
index 4936ae5cea37630b9dac3eb594d1e27b221e9610..edf9019e7f784c466e7772c9901e48079118af0c 100644 (file)
@@ -48,9 +48,9 @@ configuration examples </a>
 
 <li> <a href="IPV6_README.html"> IP Version 6 Support </a>
 
-<li> <a href="SMTPUTF8_README.html"> SMTPUTF8 support </a>
+<li> <a href="SMTPUTF8_README.html"> SMTPUTF8 Support </a>
 
-<li> <a href="COMPATIBILITY_README.html"> Backwards-Compatibility Support</a>
+<li> <a href="COMPATIBILITY_README.html"> Backwards-Compatibility Safety Net</a>
 
 <li> <a href="INSTALL.html"> Installation from source code </a>
 
index b07ef86bb4c0f56df420792c32e6738981b57e79..4678c9063f2c11e60a8df86eeab7a507bae3b1f5 100644 (file)
@@ -225,6 +225,15 @@ POSTCONF(1)                                                        POSTCONF(1)
               <b>hash</b>   An indexed file type based on hashing.  Available on sys-
                      tems with support for Berkeley DB databases.
 
+              <b>inline</b> (read-only)
+                     A  non-shared, in-memory lookup table. Example: "<b><a href="DATABASE_README.html#types">inline</a>:{</b>
+                     <i>key</i><b>=</b><i>value</i><b>, {</b> <i>key</i> <b>=</b> <i>text with  whitespace  or  comma</i>  <b>}}</b>".
+                     Key-value  pairs  are  separated  by whitespace or comma;
+                     whitespace after "{" and before "}"  is  ignored.  Inline
+                     tables  eliminate  the need to create a database file for
+                     just a few fixed elements.   See  also  the  <i><a href="DATABASE_README.html#types">static</a>:</i>  map
+                     type.
+
               <b>internal</b>
                      A  non-shared, in-memory hash table. Its content are lost
                      when a process terminates.
@@ -294,59 +303,62 @@ POSTCONF(1)                                                        POSTCONF(1)
               <b>static</b> (read-only)
                      A  table  that  always returns its name as lookup result.
                      For example, <b><a href="DATABASE_README.html#types">static</a>:foobar</b> always returns the string <b>foo-</b>
-                     <b>bar</b> as lookup result.
+                     <b>bar</b>  as lookup result. Specify "<b><a href="DATABASE_README.html#types">static</a>:{</b> <i>text with white-</i>
+                     <i>space</i> <b>}</b>" when the result contains whitespace;  this  form
+                     ignores whitespace after "{" and before "}". See also the
+                     <i><a href="DATABASE_README.html#types">inline</a>:</i> map.
 
               <b>tcp</b> (read-only)
                      TCP/IP client. The protocol is described in <a href="tcp_table.5.html"><b>tcp_table</b>(5)</a>.
 
               <b>texthash</b> (read-only)
-                     Produces similar results as <a href="DATABASE_README.html#types">hash</a>: files, except that  you
-                     don't  need  to run the <a href="postmap.1.html"><b>postmap</b>(1)</a> command before you can
-                     use the file, and that it does not detect  changes  after
+                     Produces  similar results as <a href="DATABASE_README.html#types">hash</a>: files, except that you
+                     don't need to run the <a href="postmap.1.html"><b>postmap</b>(1)</a> command before  you  can
+                     use  the  file, and that it does not detect changes after
                      the file is read.
 
               <b>unionmap</b> (read-only)
-                     A  table  that sends each query to multiple lookup tables
-                     and that concatenates all  found  results,  separated  by
+                     A table that sends each query to multiple  lookup  tables
+                     and  that  concatenates  all  found results, separated by
                      comma.  The table name syntax is the same as for <b>pipemap</b>.
 
               <b>unix</b> (read-only)
-                     A limited view of the UNIX authentication  database.  The
+                     A  limited  view of the UNIX authentication database. The
                      following tables are implemented:
 
                      <b>unix:passwd.byname</b>
-                            The  table  is the UNIX password database. The key
-                            is a login name.  The result is  a  password  file
+                            The table is the UNIX password database.  The  key
+                            is  a  login  name.  The result is a password file
                             entry in <b>passwd</b>(5) format.
 
                      <b>unix:group.byname</b>
                             The table is the UNIX group database. The key is a
-                            group name.  The result is a group file  entry  in
+                            group  name.   The result is a group file entry in
                             <b>group</b>(5) format.
 
-              Other  table types may exist depending on how Postfix was built.
+              Other table types may exist depending on how Postfix was  built.
 
-       <b>-M</b>     Show <a href="master.5.html"><b>master.cf</b></a> file contents instead of <a href="postconf.5.html"><b>main.cf</b></a>  file  contents.
+       <b>-M</b>     Show  <a href="master.5.html"><b>master.cf</b></a>  file contents instead of <a href="postconf.5.html"><b>main.cf</b></a> file contents.
               Specify <b>-Mf</b> to fold long lines for human readability.
 
               Specify zero or more arguments, each with a <i>service-name</i> or <i>ser-</i>
-              <i>vice-name/service-type</i> pair, where  <i>service-name</i>  is  the  first
-              field  of  a  <a href="master.5.html">master.cf</a>  entry and <i>service-type</i> is one of (<b>inet</b>,
+              <i>vice-name/service-type</i>  pair,  where  <i>service-name</i>  is the first
+              field of a <a href="master.5.html">master.cf</a> entry and <i>service-type</i>  is  one  of  (<b>inet</b>,
               <b>unix</b>, <b>fifo</b>, or <b>pass</b>).
 
-              If <i>service-name</i> or <i>service-name/service-type</i> is specified,  only
-              the  matching  <a href="master.5.html">master.cf</a>  entries  will  be output. For example,
-              "<b>postconf -Mf smtp</b>" will output all services named  "smtp",  and
-              "<b>postconf  -Mf smtp/inet</b>" will output only the smtp service that
-              listens on the network.  Trailing service type fields  that  are
+              If  <i>service-name</i> or <i>service-name/service-type</i> is specified, only
+              the matching <a href="master.5.html">master.cf</a> entries  will  be  output.  For  example,
+              "<b>postconf  -Mf  smtp</b>" will output all services named "smtp", and
+              "<b>postconf -Mf smtp/inet</b>" will output only the smtp service  that
+              listens  on  the network.  Trailing service type fields that are
               omitted will be handled as "*" wildcard fields.
 
               This feature is available with Postfix 2.9 and later. The syntax
-              was changed from "<i>name.type</i>" to "<i>name/type</i>",  and  "*"  wildcard
+              was  changed  from  "<i>name.type</i>" to "<i>name/type</i>", and "*" wildcard
               support was added with Postfix 2.11.
 
        <b>-n</b>     Show only configuration parameters that have explicit <i>name=value</i>
-              settings in <a href="postconf.5.html"><b>main.cf</b></a>.  Specify <b>-nf</b> to fold long lines  for  human
+              settings  in  <a href="postconf.5.html"><b>main.cf</b></a>.  Specify <b>-nf</b> to fold long lines for human
               readability (Postfix 2.9 and later).
 
        <b>-o</b> <i>name=value</i>
@@ -358,50 +370,50 @@ POSTCONF(1)                                                        POSTCONF(1)
 
               This feature is available with Postfix 2.11 and later.
 
-       <b>-P</b>     Show  <a href="master.5.html"><b>master.cf</b></a>  service parameter settings (by default all ser-
+       <b>-P</b>     Show <a href="master.5.html"><b>master.cf</b></a> service parameter settings (by default  all  ser-
               vices   and   all   parameters).    formatted   as   one   "<i>ser-</i>
-              <i>vice/type/parameter=value</i>"  per  line.  Specify <b>-Pf</b> to fold long
+              <i>vice/type/parameter=value</i>" per line.  Specify <b>-Pf</b> to  fold  long
               lines.
 
-              Specify one or more "<i>service/type/parameter</i>"  instances  on  the
-              <a href="postconf.1.html"><b>postconf</b>(1)</a>  command  line  to limit the output to parameters of
-              interest.  Trailing parameter name or service type  fields  that
+              Specify  one  or  more "<i>service/type/parameter</i>" instances on the
+              <a href="postconf.1.html"><b>postconf</b>(1)</a> command line to limit the output  to  parameters  of
+              interest.   Trailing  parameter name or service type fields that
               are omitted will be handled as "*" wildcard fields.
 
               This feature is available with Postfix 2.11 and later.
 
        <b>-t</b> [<i>template</i><b>_</b><i>file</i>]
-              Display  the templates for text that appears at the beginning of
-              delivery status notification (DSN) messages,  without  expanding
+              Display the templates for text that appears at the beginning  of
+              delivery  status  notification (DSN) messages, without expanding
               $<b>name</b> expressions.
 
               To override the built-in templates, specify a template file name
-              at the end of the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line, or  specify  a  file
+              at  the  end  of the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line, or specify a file
               name in <a href="postconf.5.html"><b>main.cf</b></a> with the <b><a href="postconf.5.html#bounce_template_file">bounce_template_file</a></b> parameter.
 
-              To  force  selection of the built-in templates, specify an empty
-              template file name on the <a href="postconf.1.html"><b>postconf</b>(1)</a>  command  line  (in  shell
+              To force selection of the built-in templates, specify  an  empty
+              template  file  name  on  the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line (in shell
               language: "").
 
               This feature is available with Postfix 2.3 and later.
 
-       <b>-v</b>     Enable  verbose  logging  for  debugging  purposes.  Multiple <b>-v</b>
+       <b>-v</b>     Enable verbose  logging  for  debugging  purposes.  Multiple  <b>-v</b>
               options make the software increasingly verbose.
 
-       <b>-x</b>     Expand <i>$name</i> in  <a href="postconf.5.html"><b>main.cf</b></a>  or  <a href="master.5.html"><b>master.cf</b></a>  parameter  values.  The
+       <b>-x</b>     Expand  <i>$name</i>  in  <a href="postconf.5.html"><b>main.cf</b></a>  or  <a href="master.5.html"><b>master.cf</b></a>  parameter values. The
               expansion is recursive.
 
               This feature is available with Postfix 2.10 and later.
 
-       <b>-X</b>     Edit  the  <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and remove the parameters
+       <b>-X</b>     Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and remove  the  parameters
               named on the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.  Specify a list of param-
               eter names, not "<i>name=value</i>" pairs.
 
-              With  <b>-M</b>,  edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and remove one
-              or more service entries as specified with "<i>service/type</i>" on  the
+              With <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and  remove  one
+              or  more service entries as specified with "<i>service/type</i>" on the
               <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
 
-              With  <b>-P</b>,  edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and remove one
+              With <b>-P</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and  remove  one
               or more service parameter settings (-o parameter=value settings)
               as specied with "<i>service/type/parameter</i>" on the <a href="postconf.1.html"><b>postconf</b>(1)</a> com-
               mand line.
@@ -410,10 +422,10 @@ POSTCONF(1)                                                        POSTCONF(1)
               into place.  Specify quotes to protect special characters on the
               <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
 
-              There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform  the  reverse  opera-
+              There  is  no  <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the reverse opera-
               tion.
 
-              This  feature is available with Postfix 2.10 and later.  Support
+              This feature is available with Postfix 2.10 and later.   Support
               for -M and -P was added with Postfix 2.11.
 
        <b>-#</b>     Edit the <a href="postconf.5.html"><b>main.cf</b></a> configuration file, and comment out the parame-
@@ -421,18 +433,18 @@ POSTCONF(1)                                                        POSTCONF(1)
               eters revert to their default values.  Specify a list of parame-
               ter names, not "<i>name=value</i>" pairs.
 
-              With  <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and comment out
-              one or more service entries as specified with "<i>service/type</i>"  on
+              With <b>-M</b>, edit the <a href="master.5.html"><b>master.cf</b></a> configuration file, and comment  out
+              one  or more service entries as specified with "<i>service/type</i>" on
               the <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
 
               In all cases the file is copied to a temporary file then renamed
               into place.  Specify quotes to protect special characters on the
               <a href="postconf.1.html"><b>postconf</b>(1)</a> command line.
 
-              There  is  no  <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform the reverse opera-
+              There is no <a href="postconf.1.html"><b>postconf</b>(1)</a> command to perform  the  reverse  opera-
               tion.
 
-              This feature is available with Postfix 2.6  and  later.  Support
+              This  feature  is  available with Postfix 2.6 and later. Support
               for -M was added with Postfix 2.11.
 
 <b>DIAGNOSTICS</b>
@@ -443,18 +455,18 @@ POSTCONF(1)                                                        POSTCONF(1)
               Directory with Postfix configuration files.
 
 <b>CONFIGURATION PARAMETERS</b>
-       The  following  <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to this pro-
+       The following <a href="postconf.5.html"><b>main.cf</b></a> parameters are especially relevant to  this  pro-
        gram.
 
-       The text below provides only a parameter summary. See  <a href="postconf.5.html"><b>postconf</b>(5)</a>  for
+       The  text  below provides only a parameter summary. See <a href="postconf.5.html"><b>postconf</b>(5)</a> for
        more details including examples.
 
        <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#bounce_template_file">bounce_template_file</a> (empty)</b>
-              Pathname of a configuration file with bounce message  templates.
+              Pathname  of a configuration file with bounce message templates.
 
 <b>FILES</b>
        /etc/postfix/<a href="postconf.5.html">main.cf</a>, Postfix configuration parameters
index c75a5652a822ef2e19bab97b6927271da610ae4a..6a7ecf623e759e33cc2392556fd5c9ec1160d40d 100644 (file)
@@ -2703,7 +2703,7 @@ sub-second delay values.  Specify a number in the range 0..6.  </p>
 
 <p> Large delay values are rounded off to an integral number seconds;
 delay values below the <a href="postconf.5.html#delay_logging_resolution_limit">delay_logging_resolution_limit</a> are logged
-as "0", and small delay values are logged with at most two-digit
+as "0", and delay values under 100s are logged with at most two-digit
 precision.  </p>
 
 <p> The format of the "delays=a/b/c/d" logging is as follows: </p>
@@ -7161,6 +7161,20 @@ Examples:
 </pre>
 
 
+</DD>
+
+<DT><b><a name="nullmx_reject_code">nullmx_reject_code</a>
+(default: 556)</b></DT><DD>
+
+<p> The numerical reply code when the Postfix SMTP server rejects
+a sender or recipient address because its domain has a nullmx DNS
+record (an MX record with an empty hostname). This is one of the
+possible replies from <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a> and
+<a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a>. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
+
+
 </DD>
 
 <DT><b><a name="owner_request_special">owner_request_special</a>
@@ -14678,7 +14692,9 @@ no DNS A
 record or 2) a malformed MX record such as a record with
 a zero-length MX hostname (Postfix version 2.3 and later). <br> The
 <a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies the numerical
-response code for rejected requests (default: 450).  The response
+response code for rejected requests (default: 450). The <a href="postconf.5.html#nullmx_reject_code">nullmx_reject_code</a>
+parameter specifies the response code for domains with a nullmx
+DNS record (default: 556, Postfix 2.12 and later).  The response
 is always 450 in case of a temporary DNS error. <br> The
 <a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a> parameter specifies the action
 after a temporary DNS error (default: <a href="postconf.5.html#defer_if_permit">defer_if_permit</a>).  </dd>
@@ -15422,7 +15438,9 @@ no DNS A
 record, or 2) a malformed MX record such as a record with
 a zero-length MX hostname (Postfix version 2.3 and later). <br> The
 <a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies the numerical
-response code for rejected requests (default: 450).  The response
+response code for rejected requests (default: 450). The <a href="postconf.5.html#nullmx_reject_code">nullmx_reject_code</a>
+parameter specifies the response code for domains with a nullmx
+DNS record (default 556, Postfix 2.12 and later).  The response
 is always 450 in case of a temporary DNS error. <br> The
 <a href="postconf.5.html#unknown_address_tempfail_action">unknown_address_tempfail_action</a> parameter specifies the action
 after a temporary DNS error (default: <a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). </dd>
@@ -18373,8 +18391,10 @@ specify an empty value to disable this feature.  </p>
 <p>
 The numerical Postfix SMTP server response code when a sender or
 recipient address is rejected by the <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>
-or <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> restriction.  The response is
-always 450 in case of a temporary DNS error.
+or <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a> restriction. The <a href="postconf.5.html#nullmx_reject_code">nullmx_reject_code</a>
+is used for domains with a nullmx DNS record (Postfix 2.12 and
+later).  The response is always 450 in case of a temporary DNS
+error.
 </p>
 
 <p>
index 61ac92c302c5a858e4e651d60109ba0aa01b72a7..0968fd182686066733539f38f03e6267eedcc082 100644 (file)
@@ -1146,6 +1146,13 @@ SMTPD(8)                                                              SMTPD(8)
               <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a> or  <a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a>
               fail due to a temporary error condition.
 
+       Available in Postfix version 2.12 and later:
+
+       <b><a href="postconf.5.html#nullmx_reject_code">nullmx_reject_code</a> (556)</b>
+              The  numerical reply code when the Postfix SMTP server rejects a
+              sender or recipient address because its domain has a nullmx  DNS
+              record (an MX record with an empty hostname).
+
 <b>MISCELLANEOUS CONTROLS</b>
        <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-
index 8ba48b9b5cf6c504be573b4c01d9f3ba9e47b814..442bcfc6d4020ed2a4424573e87f306e667b790c 100644 (file)
@@ -252,6 +252,14 @@ Postfix error tests.
 .IP \fBhash\fR
 An indexed file type based on hashing.  Available on systems
 with support for Berkeley DB databases.
+.IP "\fBinline\fR (read-only)"
+A non-shared, in-memory lookup table. Example: "\fBinline:{
+\fIkey\fB=\fIvalue\fB, { \fIkey\fB = \fItext with whitespace
+or comma\fB }}\fR". Key-value pairs are separated by
+whitespace or comma; whitespace after "{" and before "}"
+is ignored. Inline tables eliminate the need to create a
+database file for just a few fixed elements.  See also the
+\fIstatic:\fR map type.
 .IP \fBinternal\fR
 A non-shared, in-memory hash table. Its content are lost
 when a process terminates.
@@ -310,7 +318,10 @@ SQLite database. This is described in \fBsqlite_table\fR(5).
 .IP "\fBstatic\fR (read-only)"
 A table that always returns its name as lookup result. For
 example, \fBstatic:foobar\fR always returns the string
-\fBfoobar\fR as lookup result.
+\fBfoobar\fR as lookup result. Specify "\fBstatic:{ \fItext
+with whitespace\fB }\fR" when the result contains whitespace;
+this form ignores whitespace after "{" and before "}". See
+also the \fIinline:\fR map.
 .IP "\fBtcp\fR (read-only)"
 TCP/IP client. The protocol is described in \fBtcp_table\fR(5).
 .IP "\fBtexthash\fR (read-only)"
index b7d189cb988a6b4ae081174da7c66f923d622640..dc7b02b0a19ea42ae2fe306620eb39bd7cd67333 100644 (file)
@@ -1713,7 +1713,7 @@ sub-second delay values.  Specify a number in the range 0..6.
 .PP
 Large delay values are rounded off to an integral number seconds;
 delay values below the delay_logging_resolution_limit are logged
-as "0", and small delay values are logged with at most two-digit
+as "0", and delay values under 100s are logged with at most two-digit
 precision.
 .PP
 The format of the "delays=a/b/c/d" logging is as follows:
@@ -4345,6 +4345,14 @@ notify_classes = 2bounce, resource, software
 .fi
 .ad
 .ft R
+.SH nullmx_reject_code (default: 556)
+The numerical reply code when the Postfix SMTP server rejects
+a sender or recipient address because its domain has a nullmx DNS
+record (an MX record with an empty hostname). This is one of the
+possible replies from reject_unknown_sender_domain and
+reject_unknown_recipient_domain.
+.PP
+This feature is available in Postfix 2.12 and later.
 .SH owner_request_special (default: yes)
 Give special treatment to owner-listname and listname-request
 address localparts: don't split such addresses when the
@@ -9800,7 +9808,9 @@ a zero-length MX hostname (Postfix version 2.3 and later).
 .br
 The
 unknown_address_reject_code parameter specifies the numerical
-response code for rejected requests (default: 450).  The response
+response code for rejected requests (default: 450). The nullmx_reject_code
+parameter specifies the response code for domains with a nullmx
+DNS record (default: 556, Postfix 2.12 and later).  The response
 is always 450 in case of a temporary DNS error.
 .br
 The
@@ -10383,7 +10393,9 @@ a zero-length MX hostname (Postfix version 2.3 and later).
 .br
 The
 unknown_address_reject_code parameter specifies the numerical
-response code for rejected requests (default: 450).  The response
+response code for rejected requests (default: 450). The nullmx_reject_code
+parameter specifies the response code for domains with a nullmx
+DNS record (default 556, Postfix 2.12 and later).  The response
 is always 450 in case of a temporary DNS error.
 .br
 The
@@ -12571,8 +12583,10 @@ undisclosed_recipients_header = To: undisclosed-recipients:;
 .SH unknown_address_reject_code (default: 450)
 The numerical Postfix SMTP server response code when a sender or
 recipient address is rejected by the reject_unknown_sender_domain
-or reject_unknown_recipient_domain restriction.  The response is
-always 450 in case of a temporary DNS error.
+or reject_unknown_recipient_domain restriction. The nullmx_reject_code
+is used for domains with a nullmx DNS record (Postfix 2.12 and
+later).  The response is always 450 in case of a temporary DNS
+error.
 .PP
 Do not change this unless you have a complete understanding of RFC 5321.
 .SH unknown_address_tempfail_action (default: $reject_tempfail_action)
index 0a8d7c15170e056d3c8831c558124ec512592c29..cbaa577c704e8d39ffa17e3d43f69911e8f9fbc9 100644 (file)
@@ -1001,6 +1001,12 @@ fails due to an temporary error condition.
 The Postfix SMTP server's action when reject_unknown_sender_domain
 or reject_unknown_recipient_domain fail due to a temporary error
 condition.
+.PP
+Available in Postfix version 2.12 and later:
+.IP "\fBnullmx_reject_code (556)\fR"
+The numerical reply code when the Postfix SMTP server rejects
+a sender or recipient address because its domain has a nullmx DNS
+record (an MX record with an empty hostname).
 .SH "MISCELLANEOUS CONTROLS"
 .na
 .nf
index 97ee2364c5ab8dce66371cdd107dce5898422ba5..9ad06ed01612eee4d7c4858e573dea58d9052014 100755 (executable)
@@ -410,6 +410,7 @@ while (<>) {
     s;\bno_address_mappings\b;<a href="postconf.5.html#no_address_mappings">$&</a>;g;
     s;\bno_header_body_checks\b;<a href="postconf.5.html#no_header_body_checks">$&</a>;g;
     s;\bno_milters\b;<a href="postconf.5.html#no_milters">$&</a>;g;
+    s;\bnullmx_reject_code\b;<a href="postconf.5.html#nullmx_reject_code">$&</a>;g;
     s;\brecip[-</bB>]*\n* *[<bB>]*i[-</bB>]*\n* *[<bB>]*ent_bcc_maps\b;<a href="postconf.5.html#recipient_bcc_maps">$&</a>;g;
     s;\brecip[-</bB>]*\n* *[<bB>]*i[-</bB>]*\n* *[<bB>]*ent_canoni[-</bB>]*\n* *[<bB>]*cal_classes\b;<a href="postconf.5.html#recipient_canonical_classes">$&</a>;g;
     s;\brecip[-</bB>]*\n* *[<bB>]*i[-</bB>]*\n* *[<bB>]*ent_canoni[-</bB>]*\n* *[<bB>]*cal_maps\b;<a href="postconf.5.html#recipient_canonical_maps">$&</a>;g;
@@ -1142,6 +1143,7 @@ while (<>) {
     s/\b(texthash):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
     #s/\b(unix):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
     s/\b(unionmap):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
+    s/\b(inline):/<a href="DATABASE_README.html#types">$1<\/a>:/g;
 
     # Do nice links for smtp:host:port etc.
 
index 4cccb87e49c4af17cf434af5a99bba78faee8179..503b0aa9262852a58aec6088b49a799af1d78617 100644 (file)
@@ -414,13 +414,13 @@ override settings for the submission and smtps services. </p>
 <blockquote>
 <pre>
 /etc/postfix/main.cf:
-    mua_cleanup_service_name = mua_cleanup
-    mua_header_checks = pcre:/etc/postfix/mua_header_checks
-    mua_body_checks = pcre:/etc/postfix/mua_body_checks
+    msa_cleanup_service_name = msa_cleanup
+    msa_header_checks = pcre:/etc/postfix/msa_header_checks
+    msa_body_checks = pcre:/etc/postfix/msa_body_checks
 </pre>
 </blockquote>
 
-<p> Next, we define mua_cleanup as a dedicated cleanup service that
+<p> Next, we define msa_cleanup as a dedicated cleanup service that
 will be used only by the submission and smtps services.  This service
 uses the header_checks and body_checks overrides that were defined
 above. </p>
@@ -433,22 +433,22 @@ above. </p>
     #                   (yes)   (yes)   (yes)   (never) (100)
     # =================================================================
     smtp          inet  n       -       n       -       -       smtpd
-    mua_cleanup   unix  n       -       n       -       0       cleanup
-        -o header_checks=$mua_header_checks
-        -o body_checks=$mua_body_checks
+    msa_cleanup   unix  n       -       n       -       0       cleanup
+        -o header_checks=$msa_header_checks
+        -o body_checks=$msa_body_checks
     submission    inet  n       -       n       -       -       smtpd
-        -o cleanup_service_name=$mua_cleanup_service_name
+        -o cleanup_service_name=$msa_cleanup_service_name
         -o syslog_name=postfix/submission
         <i>...[see sample master.cf file for more]...</i>
     smtps         inet  n       -       n       -       -       smtpd
-        -o cleanup_service_name=$mua_cleanup_service_name
+        -o cleanup_service_name=$msa_cleanup_service_name
         -o syslog_name=postfix/smtps
         -o smtpd_tls_wrappermode=yes
         <i>...[see sample master.cf file for more]...</i>
 </pre>
 </blockquote>
 
-<p> By keeping the "mua_xxx" parameter settings in main.cf, you
+<p> By keeping the "msa_xxx" parameter settings in main.cf, you
 keep your master.cf file simple, and you minimize the amount
 of duplication. </p>
 
index 46b35537a68a36f6bd07c86d0cb6ffe8887c9cec..c9032148168b6e4d190a168acb0c4f2dc92ebab8 100644 (file)
@@ -5,7 +5,7 @@
 
 <head>
 
-<title>Postfix Backwards-Compatibility Support</title>
+<title>Postfix Backwards-Compatibility Safty Net</title>
 
 <meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
 
 <body>
 
 <h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix
-Backwards-Compatibility Support</h1>
+Backwards-Compatibility Safty Net</h1>
 
 <hr>
 
-<h2>Overview </h2>
+<h2>Purpose of this document </h2>
 
-<p> Postfix 2.12 introduces a safety net that causes Postfix programs
-to run with backwards-compatible default settings after an upgrade
-to a newer Postfix version.  Backwards compatibility is turned on
-when the main.cf compatibility_level value is less than the Postfix
-built-in value. </p>
+<p> Postfix 2.12 introduces a safety net that runs Postfix programs
+with backwards-compatible default settings after an upgrade. The
+safety net will log a warning whenever a "new" default setting could
+have an negative effect on your mail flow. </p>
 
-<p> With backwards compatibility turned on, Postfix looks for
-settings that are left at their implicit default value, and logs a
-message when a backwards-compatible default setting is required for
-continuity of service.  The following messages may be logged: </p>
+<p>This document provides information on the following topics: </p>
+
+<ul>
+
+<li> <p> <a href="#overview">Detailed descriptions</a> of Postfix
+backwards-compatibility warnings.
+
+<li> <p> What backwards-compatible settings you may have to make
+permanent in main.cf or master.cf.  </p>
+
+<li> <p> <a href="#turnoff">How to turn off</a> Postfix
+backwards-compatibility warnings. </p>
+
+</ul>
+
+<h2> <a name="overview"> Overview </a> </h2>
+
+<p>  With backwards compatibility turned on, Postfix logs a message
+whenever a backwards-compatible default setting may be required for
+continuity of service.  Based on this logging the system administrator
+can decide if any backwards-compatible settings need to be made
+permanent in main.cf or master.cf, before <a href="#turnoff">turning
+off the backwards-compatibility safety net</a> as described at the
+end of this document.  </p>
+
+<p> The following messages may be logged: </p>
 
 <ul>
 
@@ -56,27 +77,9 @@ setting permanent in main.cf or master.cf, as detailed in the
 sections that follow. </p>
 
 <p> When no more backwards-compatible settings need to be made
-permanent, the administrator should turn off backwards compatibility
-by updating the compatibility_level setting in main.cf. </p>
-
-<blockquote>
-<pre>
-# <b>postconf compatibility_level=<i>N</i></b>
-# <b>postfix reload</b>
-</pre>
-</blockquote>
-
-<p> For <i>N</i> specify the number that is logged in your postfix(1)
-warning message: </p>
-
-<blockquote>
-<pre>
-warning: To disable backwards compatibility use "postconf compatibility_level=<i>N</i>" and "postfix reload"
-</pre>
-</blockquote>
-
-<p> Sites that don't care about backwards compatibility may set
-"compatibility_level = 9999" at their own risk. </p>
+permanent, the system administrator should <a href="#turnoff">turn
+off the backwards-compatibility safety net</a> as described at the
+end of this document.  </p>
 
 <h2> <a name="append_dot_mydomain"> Using backwards-compatible default
 setting append_dot_mydomain=yes</a> </h2>
@@ -295,6 +298,30 @@ in main.cf:
 </pre>
 </blockquote>
 
+<h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2>
+
+<p> Backwards compatibility is turned off by updating the
+compatibility_level setting in main.cf. </p>
+
+<blockquote>
+<pre>
+# <b>postconf compatibility_level=<i>N</i></b>
+# <b>postfix reload</b>
+</pre>
+</blockquote>
+
+<p> For <i>N</i> specify the number that is logged in your postfix(1)
+warning message: </p>
+
+<blockquote>
+<pre>
+warning: To disable backwards compatibility use "postconf compatibility_level=<i>N</i>" and "postfix reload"
+</pre>
+</blockquote>
+
+<p> Sites that don't care about backwards compatibility may set
+"compatibility_level = 9999" at their own risk. </p>
+
 </body>
 
 </html>
index 500f4dc99355e9e891caae46f11ad21cb3d2a1f8..0fb0a9e85163abda4b21db61778f8816fe1e0815 100644 (file)
@@ -313,6 +313,15 @@ private databases are maintained by Postfix daemons. The database
 name as used in "hash:table" is the database file name without the
 ".db" suffix.  </dd>
 
+<dt> <b></b>inline (read-only) </dt>
+
+<dd> A non-shared, in-memory lookup table. Example: "inline:{
+<i>key=value</i>, { <i>key = text with whitespace or comma</i> }}".
+Key-value pairs are separated by whitespace or comma; whitespace
+after "{" and before "}" is ignored. Inline tables eliminate the
+need to create a database file for just a few fixed elements. See
+also the static: map type. </dd>
+
 <dt> <b>internal</b> </dt>
 
 <dd> A non-shared, in-memory hash table. Its content are lost when
@@ -425,7 +434,9 @@ server. See socketmap_table(5) for details.  </dd>
 
 <dd> A table that always returns its name as the lookup result.
 For example, "static:foobar" always returns the string "foobar" as
-lookup result. </dd>
+lookup result. Specify "static:{ <i>text with whitespace</i> }"
+when the result contains whitespace; this form ignores whitespace
+after "{" and before "}". See also the inline: map type.  </dd>
 
 <dt> <b>tcp</b> </dt>
 
index 15f87f854b44330125700da6e8f9028777dde8db..6476d1444d8c2ba837040bc6ae307db5dbcd3c25 100644 (file)
@@ -6048,7 +6048,9 @@ no DNS A
 record or 2) a malformed MX record such as a record with
 a zero-length MX hostname (Postfix version 2.3 and later). <br> The
 unknown_address_reject_code parameter specifies the numerical
-response code for rejected requests (default: 450).  The response
+response code for rejected requests (default: 450). The nullmx_reject_code
+parameter specifies the response code for domains with a nullmx
+DNS record (default: 556, Postfix 2.12 and later).  The response
 is always 450 in case of a temporary DNS error. <br> The
 unknown_address_tempfail_action parameter specifies the action
 after a temporary DNS error (default: defer_if_permit).  </dd>
@@ -6517,7 +6519,9 @@ no DNS A
 record, or 2) a malformed MX record such as a record with
 a zero-length MX hostname (Postfix version 2.3 and later). <br> The
 unknown_address_reject_code parameter specifies the numerical
-response code for rejected requests (default: 450).  The response
+response code for rejected requests (default: 450). The nullmx_reject_code
+parameter specifies the response code for domains with a nullmx
+DNS record (default 556, Postfix 2.12 and later).  The response
 is always 450 in case of a temporary DNS error. <br> The
 unknown_address_tempfail_action parameter specifies the action
 after a temporary DNS error (default: defer_if_permit). </dd>
@@ -6775,8 +6779,10 @@ The default time unit is s (seconds).
 <p>
 The numerical Postfix SMTP server response code when a sender or
 recipient address is rejected by the reject_unknown_sender_domain
-or reject_unknown_recipient_domain restriction.  The response is
-always 450 in case of a temporary DNS error.
+or reject_unknown_recipient_domain restriction. The nullmx_reject_code
+is used for domains with a nullmx DNS record (Postfix 2.12 and
+later).  The response is always 450 in case of a temporary DNS
+error.
 </p>
 
 <p>
@@ -10262,7 +10268,7 @@ sub-second delay values.  Specify a number in the range 0..6.  </p>
 
 <p> Large delay values are rounded off to an integral number seconds;
 delay values below the delay_logging_resolution_limit are logged
-as "0", and small delay values are logged with at most two-digit
+as "0", and delay values under 100s are logged with at most two-digit
 precision.  </p>
 
 <p> The format of the "delays=a/b/c/d" logging is as follows: </p>
@@ -16272,3 +16278,13 @@ Names are matched in a case-insensitive manner.  The list of supported
 header names is limited only by available memory.  </p>
 
 <p> This feature is available in Postfix 2.12 and later. </p>
+
+%PARAM nullmx_reject_code 556
+
+<p> The numerical reply code when the Postfix SMTP server rejects
+a sender or recipient address because its domain has a nullmx DNS
+record (an MX record with an empty hostname). This is one of the
+possible replies from reject_unknown_sender_domain and
+reject_unknown_recipient_domain. </p>
+
+<p> This feature is available in Postfix 2.12 and later. </p>
index 1f67499b3da8f44831aeac1a4b7656dd4f1a28ff..70ff71c09ee340fd5083db11143ff10758be84b7 100644 (file)
@@ -26,7 +26,7 @@ Makefile: Makefile.in
 test:  $(TESTPROG)
 
 tests: test dns_rr_to_pa_test dns_rr_to_sa_test dns_sa_to_rr_test \
-       dns_rr_eq_sa_test
+       dns_rr_eq_sa_test nullmx_test nxdomain_test mxonly_test
 
 root_tests:
 
@@ -89,6 +89,27 @@ dns_rr_eq_sa_test: dns_rr_eq_sa dns_rr_eq_sa.in dns_rr_eq_sa.ref
        diff dns_rr_eq_sa.ref dns_rr_eq_sa.tmp
        rm -f dns_rr_eq_sa.tmp
 
+nullmx_test: test_dns_lookup nullmx_test.ref
+       (set -e; \
+       $(SHLIB_ENV) ./test_dns_lookup mx,a nullmx.porcupine.org; \
+       ) >nullmx_test.tmp 2>&1 || exit 0
+       diff nullmx_test.ref nullmx_test.tmp
+       rm -f nullmx_test.tmp
+
+nxdomain_test: test_dns_lookup nxdomain_test.ref
+       (set -e; \
+       $(SHLIB_ENV) ./test_dns_lookup mx,a nxdomain.porcupine.org; \
+       ) >nxdomain_test.tmp 2>&1 || exit 0
+       diff nxdomain_test.ref nxdomain_test.tmp
+       rm -f nxdomain_test.tmp
+
+mxonly_test: test_dns_lookup mxonly_test.ref
+       (set -e; \
+       $(SHLIB_ENV) ./test_dns_lookup mx,a porcupine.org | sort; \
+       ) >mxonly_test.tmp 2>&1 || exit 0
+       diff mxonly_test.ref mxonly_test.tmp
+       rm -f mxonly_test.tmp
+
 printfck: $(OBJS) $(PROG)
        rm -rf printfck
        mkdir printfck
index 0d11e35ed114785f8bb01c993d181f3450a7c81c..e3335eb219019c3bbd5740f84cd81b92c820545c 100644 (file)
@@ -228,12 +228,14 @@ extern int dns_lookup_rv(const char *, unsigned, DNS_RR **, VSTRING *,
   */
 #define DNS_REQ_FLAG_STOP_OK   (1<<0)
 #define DNS_REQ_FLAG_STOP_INVAL        (1<<1)
+#define DNS_REQ_FLAG_STOP_UNAVAIL (1<<2)
 #define DNS_REQ_FLAG_NONE      (0)
 
  /*
   * Status codes. Failures must have negative codes so they will not collide
   * with valid counts of answer records etc.
   */
+#define DNS_UNAVAIL    (-6)            /* query ok, service unavailable */
 #define DNS_INVAL      (-5)            /* query ok, malformed reply */
 #define DNS_FAIL       (-4)            /* query failed, don't retry */
 #define DNS_NOTFOUND   (-3)            /* query ok, data not found */
index 854cdb49b56b77fce067d846e7a611200414b48c..9b85fc143aa732a7e61eabf756358e9ca6d504b4 100644 (file)
 /* .IP DNS_REQ_FLAG_STOP_INVAL
 /*     Invoke dns_lookup() for the resource types in the order as
 /*     specified, and return when dns_lookup() returns DNS_INVAL.
+/* .IP DNS_REQ_FLAG_STOP_UNAVAIL
+/*     Invoke dns_lookup() for the resource types in the order as
+/*     specified, and return when dns_lookup() returns DNS_UNAVAIL.
 /* .IP DNS_REQ_FLAG_STOP_OK
 /*     Invoke dns_lookup() for the resource types in the order as
 /*     specified, and return when dns_lookup() returns DNS_OK.
 /*     The DNS query succeeded.
 /* .IP DNS_NOTFOUND
 /*     The DNS query succeeded; the requested information was not found.
+/* .IP DNS_UNAVAIL
+/*     The DNS query succeeded; the requested service is unavailable.
+/*     This is returned when the list argument is not a null
+/*     pointer, and an MX lookup result contains a null server
+/*     name (so-called "nullmx" record).
 /* .IP DNS_INVAL
 /*     The DNS query succeeded; the result failed the valid_hostname() test.
 /*
@@ -456,6 +464,9 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
        GETSHORT(pref, pos);
        if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
            return (DNS_RETRY);
+       /* Don't even think of returning an invalid hostname to the caller. */
+       if (*temp == 0)
+           return (DNS_UNAVAIL);       /* XXX TODO: return descriptive text here */
        if (!valid_rr_name(temp, "resource data", fixed->type, reply))
            return (DNS_INVAL);
        data_len = strlen(temp) + 1;
@@ -615,6 +626,8 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
                    resource_found++;
                    rr->dnssec_valid = *maybe_secure ? reply->dnssec_ad : 0;
                    *rrlist = dns_rr_append(*rrlist, rr);
+               } else if (status == DNS_UNAVAIL) {
+                   CORRUPT(status);            /* XXX TODO: use better name here */
                } else if (not_found_status != DNS_RETRY)
                    not_found_status = status;
            } else
@@ -707,7 +720,15 @@ int     dns_lookup_r(const char *name, unsigned type, unsigned flags,
                vstring_sprintf(why, "Name service error for name=%s type=%s: "
                                "Malformed or unexpected name server reply",
                                name, dns_strtype(type));
-           /* FALLTHROUGH */
+           return (status);
+       case DNS_UNAVAIL:
+           if (why)
+               vstring_sprintf(why, type == T_MX ?     /* XXX TODO: move this */
+                               "Domain %s does not accept mail (null %s)" : 
+                               "Domain %s does not provide %s service",
+                               name, dns_strtype(type));
+           h_errno = NO_DATA;
+           return (status);
        case DNS_OK:
            return (status);
        case DNS_RECURSE:
@@ -763,6 +784,9 @@ int     dns_lookup_rl(const char *name, unsigned flags, DNS_RR **rrlist,
        } else if (status == DNS_INVAL) {
            if (lflags & DNS_REQ_FLAG_STOP_INVAL)
                break;
+       } else if (status == DNS_UNAVAIL) {
+           if (lflags & DNS_REQ_FLAG_STOP_UNAVAIL)
+               break;
        } else if (status == DNS_RETRY) {
            soft_err = 1;
        }
@@ -801,6 +825,9 @@ int     dns_lookup_rv(const char *name, unsigned flags, DNS_RR **rrlist,
        } else if (status == DNS_INVAL) {
            if (lflags & DNS_REQ_FLAG_STOP_INVAL)
                break;
+       } else if (status == DNS_UNAVAIL) {
+           if (lflags & DNS_REQ_FLAG_STOP_UNAVAIL)
+               break;
        } else if (status == DNS_RETRY) {
            soft_err = 1;
        }
diff --git a/postfix/src/dns/mxonly_test.ref b/postfix/src/dns/mxonly_test.ref
new file mode 100644 (file)
index 0000000..c7c309c
--- /dev/null
@@ -0,0 +1,11 @@
+./test_dns_lookup: lookup porcupine.org type MX flags 2097152
+./test_dns_lookup: dns_query: porcupine.org (MX): OK
+./test_dns_lookup: dns_get_answer: type MX for porcupine.org
+./test_dns_lookup: dns_get_answer: type MX for porcupine.org
+./test_dns_lookup: dns_get_answer: type MX for porcupine.org
+./test_dns_lookup: lookup porcupine.org type A flags 2097152
+./test_dns_lookup: dns_query: porcupine.org (A): Host found but no data record of requested type
+porcupine.org: ad: 0, ttl:      3600 pref: 10 MX: spike.porcupine.org
+porcupine.org: ad: 0, ttl:      3600 pref: 20 MX: fist.porcupine.org
+porcupine.org: ad: 0, ttl:      3600 pref: 30 MX: m1.porcupine.org
+porcupine.org: fqdn: porcupine.org
diff --git a/postfix/src/dns/nullmx_test.ref b/postfix/src/dns/nullmx_test.ref
new file mode 100644 (file)
index 0000000..6451d78
--- /dev/null
@@ -0,0 +1,8 @@
+./test_dns_lookup: lookup nullmx.porcupine.org type MX flags 2097152
+./test_dns_lookup: dns_query: nullmx.porcupine.org (MX): OK
+./test_dns_lookup: dns_get_answer: type MX for nullmx.porcupine.org
+./test_dns_lookup: lookup nullmx.porcupine.org type A flags 2097152
+./test_dns_lookup: dns_query: nullmx.porcupine.org (A): OK
+./test_dns_lookup: dns_get_answer: type A for nullmx.porcupine.org
+nullmx.porcupine.org: fqdn: nullmx.porcupine.org
+nullmx.porcupine.org: ad: 0, ttl:      3600 A: 168.100.189.13
diff --git a/postfix/src/dns/nxdomain_test.ref b/postfix/src/dns/nxdomain_test.ref
new file mode 100644 (file)
index 0000000..3bf8aa1
--- /dev/null
@@ -0,0 +1,5 @@
+./test_dns_lookup: lookup nxdomain.porcupine.org type MX flags 2097152
+./test_dns_lookup: dns_query: nxdomain.porcupine.org (MX): Host not found
+./test_dns_lookup: lookup nxdomain.porcupine.org type A flags 2097152
+./test_dns_lookup: dns_query: nxdomain.porcupine.org (A): Host not found
+./test_dns_lookup: fatal: Host or domain name not found. Name service error for name=nxdomain.porcupine.org type=A: Host not found (rcode=3)
index 8da9033bae8ad55abae58a6b11665eae1b32c84a..3226f133797a82afda52feff2cc67ece712c9402 100644 (file)
@@ -118,7 +118,7 @@ int     main(int argc, char **argv)
     argv_free(types_argv);
     name = argv[2];
     msg_verbose = 1;
-    switch (dns_lookup_rv(name, RES_DEBUG | RES_USE_DNSSEC, &rr, fqdn, why,
+    switch (dns_lookup_rv(name, RES_USE_DNSSEC, &rr, fqdn, why,
                          &rcode, DNS_REQ_FLAG_NONE, types)) {
     default:
        msg_fatal("%s (rcode=%d)", vstring_str(why), rcode);
index b423e8eb7c0b59313549a07de9b5dfe632235400..d7f5a3582c93086e7a29cfc86cb793785d7f7098 100644 (file)
@@ -429,6 +429,7 @@ void    _hbc_checks_free(HBC_CHECKS *hbc, ssize_t len)
 #include <vstream.h>
 #include <msg_vstream.h>
 #include <rec_streamlf.h>
+#include <mail_params.h>
 
 typedef struct {
     HBC_CHECKS *header_checks;
@@ -556,6 +557,7 @@ static void err_print(void *unused_context, int err_flag,
 int     var_header_limit = 2000;
 int     var_mime_maxdepth = 20;
 int     var_mime_bound_len = 2000;
+char   *var_drop_hdrs = DEF_DROP_HDRS;
 
 int     main(int argc, char **argv)
 {
index a7b0fdb563e1740c37a706c41dc4dfef8d98ae05..276a3d3c53230457a6e9783fe4901fd6a3e3efc6 100644 (file)
@@ -2145,6 +2145,10 @@ extern int var_non_fqdn_code;
 #define DEF_UNK_ADDR_CODE      450
 extern int var_unk_addr_code;
 
+#define VAR_NULLMX_RCODE       "nullmx_reject_code"
+#define DEF_NULLMX_RCODE       556
+extern int var_nullmx_rcode;
+
 #define VAR_UNK_ADDR_TF_ACT    "unknown_address_tempfail_action"
 #define DEF_UNK_ADDR_TF_ACT    "$" VAR_REJECT_TMPF_ACT
 extern char *var_unk_addr_tf_act;
index d2c90f8312f0ec66f2f5bc047ebcd47f89636885..68fc4c7363876a5a05ef6636368a731f732d7a05 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      "20141119"
+#define MAIL_RELEASE_DATE      "20141126"
 #define MAIL_VERSION_NUMBER    "2.12"
 
 #ifdef SNAPSHOT
index f8be02cb853b535d9aa0d6ba6e00ff09aff72a53..5ddf63273e2d9ca8fda1fa3668b1b5be87446644 100644 (file)
@@ -1229,6 +1229,7 @@ static void err_print(void *unused_context, int err_flag,
 int     var_header_limit = 2000;
 int     var_mime_maxdepth = 20;
 int     var_mime_bound_len = 2000;
+char   *var_drop_hdrs = DEF_DROP_HDRS;
 
 int     main(int unused_argc, char **argv)
 {
index d0b6e9f78aea902292f0616b6b9d88cac2fae7cf..10147e10102a095849e2e7ee7aa578ff04e4a5b8 100644 (file)
 /* .IP \fBhash\fR
 /*     An indexed file type based on hashing.  Available on systems
 /*     with support for Berkeley DB databases.
+/* .IP "\fBinline\fR (read-only)"
+/*     A non-shared, in-memory lookup table. Example: "\fBinline:{
+/*     \fIkey\fB=\fIvalue\fB, { \fIkey\fB = \fItext with whitespace
+/*     or comma\fB }}\fR". Key-value pairs are separated by
+/*     whitespace or comma; whitespace after "{" and before "}"
+/*     is ignored. Inline tables eliminate the need to create a
+/*     database file for just a few fixed elements.  See also the
+/*     \fIstatic:\fR map type.
 /* .IP \fBinternal\fR
 /*     A non-shared, in-memory hash table. Its content are lost
 /*     when a process terminates.
 /* .IP "\fBstatic\fR (read-only)"
 /*     A table that always returns its name as lookup result. For
 /*     example, \fBstatic:foobar\fR always returns the string
-/*     \fBfoobar\fR as lookup result.
+/*     \fBfoobar\fR as lookup result. Specify "\fBstatic:{ \fItext
+/*     with whitespace\fB }\fR" when the result contains whitespace;
+/*     this form ignores whitespace after "{" and before "}". See
+/*     also the \fIinline:\fR map.
 /* .IP "\fBtcp\fR (read-only)"
 /*     TCP/IP client. The protocol is described in \fBtcp_table\fR(5).
 /* .IP "\fBtexthash\fR (read-only)"
index f02acf590e512f7db5bcdb3876ea44971ce27fc9..13e14dab72bb7a31221413413543c370b6363c77 100644 (file)
@@ -1105,6 +1105,9 @@ static DNS_RR *domain_addr(STATE *state, char *domain)
     case DNS_INVAL:
        dsb_status(state->why, "5.4.4");
        break;
+    case DNS_UNAVAIL:
+       dsb_status(state->why, "5.1.0");
+       break;
     case DNS_FAIL:
        dsb_status(state->why, "5.4.3");
        break;
index 2294f1e6a741b1e12bbec0bf471fa013e26a2419..42fb5068ef45256c8470958cc15a053127446a0f 100644 (file)
@@ -435,6 +435,9 @@ DNS_RR *smtp_domain_addr(const char *name, DNS_RR **mxrr, int misc_flags,
        if (var_ign_mx_lookup_err)
            addr_list = smtp_host_addr(aname, misc_flags, why);
        break;
+    case DNS_UNAVAIL:
+       dsb_status(why, "5.1.0");
+       break;
     case DNS_FAIL:
        dsb_status(why, "5.4.3");
        if (var_ign_mx_lookup_err)
index 7ce7377b150de73e78a03fe2992714fd688791c1..bc9e728509e8f9db91086773c11e8061ee7159a3 100644 (file)
@@ -75,7 +75,7 @@ tidy: clean
 tests: smtpd_check_test smtpd_check_test2 smtpd_acl_test smtpd_exp_test \
        smtpd_token_test smtpd_check_test4 smtpd_check_dsn_test \
        smtpd_check_backup_test smtpd_dnswl_test smtpd_error_test \
-       smtpd_server_test
+       smtpd_server_test smtpd_nullmx_test
 
 root_tests:
 
@@ -121,6 +121,12 @@ smtpd_server_test: smtpd_check smtpd_server.in smtpd_server.ref
        diff smtpd_server.ref smtpd_server.tmp
        rm -f smtpd_server.tmp smtpd_check_access.*
 
+smtpd_nullmx_test: smtpd_check smtpd_nullmx.in smtpd_nullmx.ref
+       $(SHLIB_ENV) ../postmap/postmap hash:smtpd_check_access
+       $(SHLIB_ENV) ./smtpd_check <smtpd_nullmx.in >smtpd_nullmx.tmp 2>&1
+       diff smtpd_nullmx.ref smtpd_nullmx.tmp
+       rm -f smtpd_nullmx.tmp smtpd_check_access.*
+
 smtpd_check_dsn_test: smtpd_check smtpd_check_dsn.in smtpd_check_dsn.ref smtpd_check_access
        $(SHLIB_ENV) ../postmap/postmap hash:smtpd_check_access
        $(SHLIB_ENV) ./smtpd_check <smtpd_check_dsn.in >smtpd_check.tmp 2>&1
index c4b34aedce7bc49f6954926477bdc44f6eaf2a59..968656a620eae40faca4f442b5979b2c7fda6ad1 100644 (file)
 /*     The Postfix SMTP server's action when reject_unknown_sender_domain
 /*     or reject_unknown_recipient_domain fail due to a temporary error
 /*     condition.
+/* .PP
+/*     Available in Postfix version 2.12 and later:
+/* .IP "\fBnullmx_reject_code (556)\fR"
+/*     The numerical reply code when the Postfix SMTP server rejects
+/*     a sender or recipient address because its domain has a nullmx DNS
+/*     record (an MX record with an empty hostname).
 /* MISCELLANEOUS CONTROLS
 /* .ad
 /* .fi
@@ -1318,6 +1324,7 @@ char   *var_smtpd_tls_eckey_file;
 
 bool    var_smtpd_peername_lookup;
 int     var_plaintext_code;
+int     var_nullmx_rcode;
 bool    var_smtpd_delay_open;
 char   *var_smtpd_milters;
 int     var_milt_conn_time;
@@ -5520,6 +5527,7 @@ int     main(int argc, char **argv)
        VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code, 0, 0,
        VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code, 0, 0,
        VAR_PLAINTEXT_CODE, DEF_PLAINTEXT_CODE, &var_plaintext_code, 0, 0,
+       VAR_NULLMX_RCODE, DEF_NULLMX_RCODE, &var_nullmx_rcode, 0, 0,
        VAR_SMTPD_CRATE_LIMIT, DEF_SMTPD_CRATE_LIMIT, &var_smtpd_crate_limit, 0, 0,
        VAR_SMTPD_CCONN_LIMIT, DEF_SMTPD_CCONN_LIMIT, &var_smtpd_cconn_limit, 0, 0,
        VAR_SMTPD_CMAIL_LIMIT, DEF_SMTPD_CMAIL_LIMIT, &var_smtpd_cmail_limit, 0, 0,
index cfe6d014bf869a8967730ce012ae5d25b14cbef2..66e8c1dee820a3a76c9aa846aba4a1709131e9d0 100644 (file)
@@ -1377,6 +1377,7 @@ static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
     if (dummy)
        dns_rr_free(dummy);
     if (dns_status != DNS_OK) {                        /* incl. DNS_INVAL */
+       /* We don't care about DNS_UNAVAIL. */
        if (dns_status != DNS_RETRY)
            return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
                                       var_unk_name_code, "4.7.1",
@@ -1418,7 +1419,8 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, const char *name,
     }
 #endif
 
-#define MAILHOST_LOOKUP_FLAGS  (DNS_REQ_FLAG_STOP_OK | DNS_REQ_FLAG_STOP_INVAL)
+#define MAILHOST_LOOKUP_FLAGS \
+    (DNS_REQ_FLAG_STOP_OK | DNS_REQ_FLAG_STOP_INVAL | DNS_REQ_FLAG_STOP_UNAVAIL)
 
     dns_status = dns_lookup_l(name, 0, &dummy, (VSTRING *) 0,
                              (VSTRING *) 0, MAILHOST_LOOKUP_FLAGS,
@@ -1426,6 +1428,14 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, const char *name,
     if (dummy)
        dns_rr_free(dummy);
     if (dns_status != DNS_OK) {                        /* incl. DNS_INVAL */
+       if (dns_status == DNS_UNAVAIL)
+           return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
+                                      var_nullmx_rcode,
+                              strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
+                                      "4.7.0" : "4.1.0",
+                                      "<%s>: %s rejected: "
+                                      "Domain %s does not accept mail",
+                                      reply_name, reply_class, name));
        if (dns_status != DNS_RETRY)
            return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
                                       var_unk_addr_code,
@@ -1669,6 +1679,7 @@ static int all_auth_mx_addr(SMTPD_STATE *state, char *host,
      */
     dns_status = dns_lookup_v(host, 0, &addr_list, (VSTRING *) 0, (VSTRING *) 0,
                      DNS_REQ_FLAG_NONE, inet_proto_info()->dns_atype_list);
+    /* DNS_UNAVAIL is not applicable here. */
     if (dns_status != DNS_OK) {                        /* incl. DNS_INVAL */
        DEFER_IF_REJECT3(state, MAIL_ERROR_POLICY,
                         450, "4.4.4",
@@ -1911,6 +1922,7 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient,
                SMTPD_CHECK_OK : SMTPD_CHECK_DUNNO);
 #endif
     if (dns_status != DNS_OK) {                        /* incl. DNS_INVAL */
+       /* We don't care about DNS_UNAVAIL. */
        if (dns_status == DNS_RETRY)
            DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
                             450, "4.4.4",
@@ -2914,6 +2926,8 @@ static int check_server_access(SMTPD_STATE *state, const char *table,
     } else {
        dns_status = dns_lookup(domain, type, 0, &server_list,
                                (VSTRING *) 0, (VSTRING *) 0);
+       if (dns_status == DNS_UNAVAIL)
+           return (SMTPD_CHECK_DUNNO);
        if (dns_status == DNS_NOTFOUND /* Not: h_errno == NO_DATA */ ) {
            if (type == T_MX) {
                server_list = dns_rr_create(domain, domain, type, C_IN, 0, 0,
@@ -5379,6 +5393,7 @@ char   *var_relay_ccerts = "";
 #endif
 char   *var_mynetworks = "";
 char   *var_notify_classes = "";
+char   *var_smtpd_policy_def_action = "";
 
  /*
   * String-valued configuration parameters.
@@ -5539,11 +5554,17 @@ int     var_verify_poll_delay;
 int     var_smtpd_policy_tmout;
 int     var_smtpd_policy_idle;
 int     var_smtpd_policy_ttl;
+int     var_smtpd_policy_req_limit;
+int     var_smtpd_policy_try_limit;
+int     var_smtpd_policy_try_delay;
 int     var_smtpd_rej_unl_from;
 int     var_smtpd_rej_unl_rcpt;
 int     var_plaintext_code;
 bool    var_smtpd_peername_lookup;
 bool    var_smtpd_client_port_log;
+int     var_nullmx_rcode;
+
+#define int_table test_int_table
 
 static const INT_TABLE int_table[] = {
     "msg_verbose", 0, &msg_verbose,
@@ -5576,6 +5597,7 @@ static const INT_TABLE int_table[] = {
     VAR_PLAINTEXT_CODE, DEF_PLAINTEXT_CODE, &var_plaintext_code,
     VAR_SMTPD_PEERNAME_LOOKUP, DEF_SMTPD_PEERNAME_LOOKUP, &var_smtpd_peername_lookup,
     VAR_SMTPD_CLIENT_PORT_LOG, DEF_SMTPD_CLIENT_PORT_LOG, &var_smtpd_client_port_log,
+    VAR_NULLMX_RCODE, DEF_NULLMX_RCODE, &var_nullmx_rcode,
     0,
 };
 
@@ -5908,6 +5930,7 @@ int     main(int argc, char **argv)
            if (strcasecmp(args->argv[0], VAR_MYDEST) == 0) {
                UPDATE_STRING(var_mydest, args->argv[1]);
                resolve_local_init();
+               smtpd_resolve_init(100);
                resp = 0;
                break;
            }
@@ -5922,6 +5945,7 @@ int     main(int argc, char **argv)
            if (strcasecmp(args->argv[0], VAR_VIRT_ALIAS_DOMS) == 0) {
                UPDATE_STRING(var_virt_alias_doms, args->argv[1]);
                UPDATE_LIST(virt_alias_doms, var_virt_alias_doms);
+               smtpd_resolve_init(100);
                resp = 0;
                break;
            }
@@ -5936,6 +5960,7 @@ int     main(int argc, char **argv)
            if (strcasecmp(args->argv[0], VAR_VIRT_MAILBOX_DOMS) == 0) {
                UPDATE_STRING(var_virt_mailbox_doms, args->argv[1]);
                UPDATE_LIST(virt_mailbox_doms, var_virt_mailbox_doms);
+               smtpd_resolve_init(100);
                resp = 0;
                break;
            }
@@ -5973,11 +5998,12 @@ int     main(int argc, char **argv)
            }
            if (strcasecmp(args->argv[0], VAR_MYNETWORKS) == 0) {
                /* NOT: UPDATE_STRING */
-               namadr_list_free(mynetworks);
-               mynetworks =
+               namadr_list_free(mynetworks_curr);
+               mynetworks_curr =
                    namadr_list_init(MATCH_FLAG_RETURN
                                     | match_parent_style(VAR_MYNETWORKS),
                                     args->argv[1]);
+               smtpd_resolve_init(100);
                resp = 0;
                break;
            }
@@ -5987,6 +6013,7 @@ int     main(int argc, char **argv)
                relay_domains =
                    domain_list_init(match_parent_style(VAR_RELAY_DOMAINS),
                                     args->argv[1]);
+               smtpd_resolve_init(100);
                resp = 0;
                break;
            }
index b85997b6c5b65df9631b5199ad3237c08b93bbbd..1a8090f3241a5389b741508906c7e8c001960cda 100644 (file)
@@ -55,8 +55,8 @@ OK
 ./smtpd_check: <queue id>: reject: HELO from foo[123.123.123.123]: 450 4.7.1 <foo>: Helo command rejected: Host not found; proto=SMTP helo=<foo>
 450 4.7.1 <foo>: Helo command rejected: Host not found
 >>> helo spike.porcupine.org
-./smtpd_check: <queue id>: reject: HELO from foo[123.123.123.123]: 554 5.7.1 <spike.porcupine.org>: Helo command rejected: name server spike.porcupine.org; proto=SMTP helo=<spike.porcupine.org>
-554 5.7.1 <spike.porcupine.org>: Helo command rejected: name server spike.porcupine.org
+./smtpd_check: <queue id>: reject: HELO from foo[123.123.123.123]: 554 5.7.1 <spike.porcupine.org>: Helo command rejected: ns or mx server spike.porcupine.org; proto=SMTP helo=<spike.porcupine.org>
+554 5.7.1 <spike.porcupine.org>: Helo command rejected: ns or mx server spike.porcupine.org
 >>> helo_restrictions permit_mynetworks,reject_unknown_client,reject_invalid_hostname,hash:./smtpd_check_access
 OK
 >>> helo random.bad.domain
index 663f180908b860a24523959a3d5b3cbb508fa649..88554d27f3a1759ae7c629f107cecef99e10a8ec 100644 (file)
@@ -61,7 +61,7 @@ dunnotext@dunno.domain        dunno text
 64.94.110.11           reject Verisign wild-card
 topica.com             reject
 10.10.10.10            reject mail server 10.10.10.10
-spike.porcupine.org    reject name server spike.porcupine.org
+spike.porcupine.org    reject ns or mx server spike.porcupine.org
 241                    reject class E subnet
 4.1.1_dsn reject 4.1.1 reject
 4.1.2_dsn reject 4.1.2 reject
diff --git a/postfix/src/smtpd/smtpd_nullmx.in b/postfix/src/smtpd/smtpd_nullmx.in
new file mode 100644 (file)
index 0000000..9db8276
--- /dev/null
@@ -0,0 +1,58 @@
+#
+# Initialize.
+#
+#! ../bin/postmap smtpd_check_access
+#msg_verbose 1
+#smtpd_delay_reject 0
+#mynetworks 127.0.0.0/8,168.100.189.0/28
+#relay_domains porcupine.org
+#maps_rbl_domains dnsbltest.porcupine.org
+#rbl_reply_maps hash:smtpd_check_access
+#helo foobar
+#
+# reject_unknown_helo_hostname
+#
+smtpd_delay_reject 0
+helo_restrictions reject_unknown_helo_hostname
+client spike.porcupine.org 168.100.189.2
+mail sname@sdomain
+rcpt rname@rdomain
+helo nxdomain.porcupine.org
+helo nullmx.porcupine.org
+helo spike.porcupine.org
+#
+# reject_unknown_sender_domain
+#
+smtpd_delay_reject 0
+sender_restrictions reject_unknown_sender_domain
+client spike.porcupine.org 168.100.189.2
+helo spike.porcupine.org
+rcpt rname@rdomain
+mail sname@nxdomain.porcupine.org
+mail sname@nullmx.porcupine.org
+mail sname@spike.porcupine.org
+#
+# reject_unknown_recipient_domain
+#
+smtpd_delay_reject 0
+sender_restrictions permit
+recipient_restrictions reject_unknown_recipient_domain
+relay_restrictions reject_unauth_destination
+client spike.porcupine.org 168.100.189.2
+helo spike.porcupine.org
+mail sname@sdomain
+relay_domains nxdomain.porcupine.org
+rcpt rname@nxdomain.porcupine.org
+relay_domains nullmx.porcupine.org
+rcpt rname@nullmx.porcupine.org
+relay_domains spike.porcupine.org
+rcpt rname@spike.porcupine.org
+#
+# check_mx_access
+#
+smtpd_delay_reject 0
+sender_restrictions check_sender_mx_access,hash:smtpd_check_access
+client spike.porcupine.org 168.100.189.2
+mail sname@nxdomain.porcupine.org
+mail sname@nullmx.porcupine.org
+mail sname@spike.porcupine.org
diff --git a/postfix/src/smtpd/smtpd_nullmx.ref b/postfix/src/smtpd/smtpd_nullmx.ref
new file mode 100644 (file)
index 0000000..281e2e6
--- /dev/null
@@ -0,0 +1,100 @@
+>>> #
+>>> # Initialize.
+>>> #
+>>> #! ../bin/postmap smtpd_check_access
+>>> #msg_verbose 1
+>>> #smtpd_delay_reject 0
+>>> #mynetworks 127.0.0.0/8,168.100.189.0/28
+>>> #relay_domains porcupine.org
+>>> #maps_rbl_domains dnsbltest.porcupine.org
+>>> #rbl_reply_maps hash:smtpd_check_access
+>>> #helo foobar
+>>> #
+>>> # reject_unknown_helo_hostname
+>>> #
+>>> smtpd_delay_reject 0
+OK
+>>> helo_restrictions reject_unknown_helo_hostname
+OK
+>>> client spike.porcupine.org 168.100.189.2
+OK
+>>> mail sname@sdomain
+OK
+>>> rcpt rname@rdomain
+OK
+>>> helo nxdomain.porcupine.org
+./smtpd_check: <queue id>: reject: HELO from spike.porcupine.org[168.100.189.2]: 450 4.7.1 <nxdomain.porcupine.org>: Helo command rejected: Host not found; from=<sname@sdomain> proto=SMTP helo=<nxdomain.porcupine.org>
+450 4.7.1 <nxdomain.porcupine.org>: Helo command rejected: Host not found
+>>> helo nullmx.porcupine.org
+OK
+>>> helo spike.porcupine.org
+OK
+>>> #
+>>> # reject_unknown_sender_domain
+>>> #
+>>> smtpd_delay_reject 0
+OK
+>>> sender_restrictions reject_unknown_sender_domain
+OK
+>>> client spike.porcupine.org 168.100.189.2
+OK
+>>> helo spike.porcupine.org
+OK
+>>> rcpt rname@rdomain
+OK
+>>> mail sname@nxdomain.porcupine.org
+./smtpd_check: <queue id>: reject: MAIL from spike.porcupine.org[168.100.189.2]: 450 4.1.8 <sname@nxdomain.porcupine.org>: Sender address rejected: Domain not found; from=<sname@nxdomain.porcupine.org> proto=SMTP helo=<spike.porcupine.org>
+450 4.1.8 <sname@nxdomain.porcupine.org>: Sender address rejected: Domain not found
+>>> mail sname@nullmx.porcupine.org
+./smtpd_check: <queue id>: reject: MAIL from spike.porcupine.org[168.100.189.2]: 556 5.7.0 <sname@nullmx.porcupine.org>: Sender address rejected: Domain nullmx.porcupine.org does not accept mail; from=<sname@nullmx.porcupine.org> proto=SMTP helo=<spike.porcupine.org>
+556 5.7.0 <sname@nullmx.porcupine.org>: Sender address rejected: Domain nullmx.porcupine.org does not accept mail
+>>> mail sname@spike.porcupine.org
+OK
+>>> #
+>>> # reject_unknown_recipient_domain
+>>> #
+>>> smtpd_delay_reject 0
+OK
+>>> sender_restrictions permit
+OK
+>>> recipient_restrictions reject_unknown_recipient_domain
+OK
+>>> relay_restrictions reject_unauth_destination
+OK
+>>> client spike.porcupine.org 168.100.189.2
+OK
+>>> helo spike.porcupine.org
+OK
+>>> mail sname@sdomain
+OK
+>>> relay_domains nxdomain.porcupine.org
+OK
+>>> rcpt rname@nxdomain.porcupine.org
+./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.189.2]: 450 4.1.2 <rname@nxdomain.porcupine.org>: Recipient address rejected: Domain not found; from=<sname@sdomain> to=<rname@nxdomain.porcupine.org> proto=SMTP helo=<spike.porcupine.org>
+450 4.1.2 <rname@nxdomain.porcupine.org>: Recipient address rejected: Domain not found
+>>> relay_domains nullmx.porcupine.org
+OK
+>>> rcpt rname@nullmx.porcupine.org
+./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.189.2]: 556 5.1.0 <rname@nullmx.porcupine.org>: Recipient address rejected: Domain nullmx.porcupine.org does not accept mail; from=<sname@sdomain> to=<rname@nullmx.porcupine.org> proto=SMTP helo=<spike.porcupine.org>
+556 5.1.0 <rname@nullmx.porcupine.org>: Recipient address rejected: Domain nullmx.porcupine.org does not accept mail
+>>> relay_domains spike.porcupine.org
+OK
+>>> rcpt rname@spike.porcupine.org
+OK
+>>> #
+>>> # check_mx_access
+>>> #
+>>> smtpd_delay_reject 0
+OK
+>>> sender_restrictions check_sender_mx_access,hash:smtpd_check_access
+OK
+>>> client spike.porcupine.org 168.100.189.2
+OK
+>>> mail sname@nxdomain.porcupine.org
+./smtpd_check: warning: Unable to look up MX host nxdomain.porcupine.org for Sender address sname@nxdomain.porcupine.org: hostname nor servname provided, or not known
+OK
+>>> mail sname@nullmx.porcupine.org
+OK
+>>> mail sname@spike.porcupine.org
+./smtpd_check: <queue id>: reject: MAIL from spike.porcupine.org[168.100.189.2]: 554 5.7.1 <sname@spike.porcupine.org>: Sender address rejected: ns or mx server spike.porcupine.org; from=<sname@spike.porcupine.org> proto=SMTP helo=<spike.porcupine.org>
+554 5.7.1 <sname@spike.porcupine.org>: Sender address rejected: ns or mx server spike.porcupine.org
index 2166ebb34b4e7032147bea7961d74b4e2301277f..fc0758bd14279a5cf5f15c1b477c9827bb039542 100644 (file)
@@ -17,7 +17,8 @@
 /*     are always resolved in local rewriting context.
 /*
 /*     smtpd_resolve_init() initializes the cache and must
-/*     called once before the cache can be used.
+/*     called before the cache can be used. This function may also
+/*     be called to flush the cache after an address class update.
 /*
 /*     smtpd_resolve_addr() resolves one address or returns
 /*     a known result from cache.
@@ -121,7 +122,7 @@ void    smtpd_resolve_init(int cache_size)
      * Sanity check.
      */
     if (smtpd_resolve_cache)
-       msg_panic("smtpd_resolve_init: multiple initialization");
+       ctable_free(smtpd_resolve_cache);
 
     /*
      * Initialize the resolved address cache. Note: the cache persists across
index fee9ad29e2d1897b8dd6fa37b2c2a6d7deaf1ac9..6d8a511f9d33e31bfba6d927c424f26c1c758c5c 100644 (file)
@@ -75,8 +75,8 @@ OK
 554 5.7.1 <foo@ns1.topica.com>: Recipient address rejected: Access denied
 >>> #rcpt foo@verisign-wildcard.com
 >>> rcpt foo@1.2.3.porcupine.org
-./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.189.2]: 554 5.7.1 <foo@1.2.3.porcupine.org>: Recipient address rejected: name server spike.porcupine.org; from=<foo@ns1.topica.com> to=<foo@1.2.3.porcupine.org> proto=SMTP helo=<example.tld>
-554 5.7.1 <foo@1.2.3.porcupine.org>: Recipient address rejected: name server spike.porcupine.org
+./smtpd_check: <queue id>: reject: RCPT from spike.porcupine.org[168.100.189.2]: 554 5.7.1 <foo@1.2.3.porcupine.org>: Recipient address rejected: ns or mx server spike.porcupine.org; from=<foo@ns1.topica.com> to=<foo@1.2.3.porcupine.org> proto=SMTP helo=<example.tld>
+554 5.7.1 <foo@1.2.3.porcupine.org>: Recipient address rejected: ns or mx server spike.porcupine.org
 >>> #
 >>> # Check A access
 >>> #
index a77c9460361201796d64d2e27608adbe175148eb..3fea180779d99594462fef4643e124f6491dfc99 100644 (file)
@@ -39,7 +39,7 @@ SRCS  = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
        dict_sockmap.c line_number.c recv_pass_attr.c pass_accept.c \
        poll_fd.c timecmp.c slmdb.c dict_pipe.c dict_random.c \
        valid_utf8_hostname.c midna.c argv_splitq.c balpar.c dict_union.c \
-       extpar.c
+       extpar.c dict_inline.c
 OBJS   = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
        attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@@ -80,7 +80,7 @@ OBJS  = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
        dict_sockmap.o line_number.o recv_pass_attr.o pass_accept.o \
        poll_fd.o timecmp.o $(NON_PLUGIN_MAP_OBJ) dict_pipe.o dict_random.o \
        valid_utf8_hostname.o midna.o argv_splitq.o balpar.o dict_union.o \
-       extpar.o
+       extpar.o dict_inline.o
 # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
 # When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
 # otherwise it sets the PLUGIN_* macros.
@@ -109,7 +109,7 @@ HDRS        = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
        edit_file.h dict_cache.h dict_thash.h ip_match.h nbbio.h base32_code.h \
        dict_fail.h warn_stat.h dict_sockmap.h line_number.h timecmp.h \
        slmdb.h compat_va_copy.h dict_pipe.h dict_random.h \
-       valid_utf8_hostname.h midna.h dict_union.h
+       valid_utf8_hostname.h midna.h dict_union.h dict_inline.h
 TESTSRC        = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
        stream_test.c dup2_pass_on_exec.c
 DEFS   = -I. -D$(SYSTYPE)
@@ -514,7 +514,8 @@ tests: valid_hostname_test mac_expand_test dict_test unescape_test \
        attr_scan64_test attr_scan0_test dict_pcre_test host_port_test \
        dict_cidr_test attr_scan_plain_test htable_test hex_code_test \
        myaddrinfo_test format_tv_test ip_match_test name_mask_tests \
-       base32_code_test dict_thash_test surrogate_test timecmp_test
+       base32_code_test dict_thash_test surrogate_test timecmp_test \
+       dict_static_test dict_inline_test
 
 root_tests:
 
@@ -724,6 +725,31 @@ surrogate_test: dict_open surrogate.ref
        diff surrogate.ref surrogate.tmp
        rm -f surrogate.tmp
 
+dict_static_test: dict_open dict_static.ref
+       (set -e; \
+       (echo get foo; echo get bar) | $(SHLIB_ENV) \
+           ./dict_open static:fooxx read; \
+       $(SHLIB_ENV) ./dict_open static:'{ foo xx ' read </dev/null; \
+       $(SHLIB_ENV) ./dict_open static:'{ foo xx }x' read </dev/null; \
+       (echo get foo; echo get bar) | $(SHLIB_ENV) \
+           ./dict_open static:'{ foo xx }' read; \
+       ) >dict_static.tmp 2>&1
+       diff dict_static.ref dict_static.tmp
+       rm -f dict_static.tmp
+
+dict_inline_test: dict_open dict_inline.ref
+       (set -e; \
+       $(SHLIB_ENV) ./dict_open inline:'{ }' read </dev/null; \
+       $(SHLIB_ENV) ./dict_open inline:'{ foo = xx }' read </dev/null; \
+       $(SHLIB_ENV) ./dict_open inline:'{ foo=xx }x' read </dev/null; \
+       $(SHLIB_ENV) ./dict_open inline:'{ foo=xx x' read </dev/null; \
+       $(SHLIB_ENV) ./dict_open inline:'{ foo=xx {x=y}x}' read </dev/null; \
+       (echo get foo; echo get bar; echo get baz) | $(SHLIB_ENV) \
+           ./dict_open inline:'{ foo=xx, { bar = lotsa stuff }}' read; \
+       ) >dict_inline.tmp 2>&1
+       diff dict_inline.ref dict_inline.tmp
+       rm -f dict_inline.tmp
+
 depend: $(MAKES)
        (sed '1,/^# do not edit/!d' Makefile.in; \
        set -e; for i in [a-z][a-z0-9]*.c; do \
@@ -1060,6 +1086,19 @@ dict_ht.o: sys_defs.h
 dict_ht.o: vbuf.h
 dict_ht.o: vstream.h
 dict_ht.o: vstring.h
+dict_inline.o: argv.h
+dict_inline.o: dict.h
+dict_inline.o: dict_inline.c
+dict_inline.o: dict_inline.h
+dict_inline.o: htable.h
+dict_inline.o: msg.h
+dict_inline.o: myflock.h
+dict_inline.o: mymalloc.h
+dict_inline.o: stringops.h
+dict_inline.o: sys_defs.h
+dict_inline.o: vbuf.h
+dict_inline.o: vstream.h
+dict_inline.o: vstring.h
 dict_lmdb.o: argv.h
 dict_lmdb.o: dict.h
 dict_lmdb.o: dict_lmdb.c
@@ -1233,6 +1272,7 @@ dict_static.o: dict_static.h
 dict_static.o: msg.h
 dict_static.o: myflock.h
 dict_static.o: mymalloc.h
+dict_static.o: stringops.h
 dict_static.o: sys_defs.h
 dict_static.o: vbuf.h
 dict_static.o: vstream.h
@@ -1561,6 +1601,8 @@ load_file.o: vbuf.h
 load_file.o: vstream.h
 load_file.o: warn_stat.h
 load_lib.o: load_lib.c
+load_lib.o: load_lib.h
+load_lib.o: msg.h
 load_lib.o: sys_defs.h
 lowercase.o: lowercase.c
 lowercase.o: stringops.h
diff --git a/postfix/src/util/dict_inline.c b/postfix/src/util/dict_inline.c
new file mode 100644 (file)
index 0000000..8a97f7e
--- /dev/null
@@ -0,0 +1,143 @@
+/*++
+/* NAME
+/*     dict_inline 3
+/* SUMMARY
+/*     dictionary manager interface for inline table
+/* SYNOPSIS
+/*     #include <dict_inline.h>
+/*
+/*     DICT    *dict_inline_open(name, open_flags, dict_flags)
+/*     const char *name;
+/*     int     open_flags;
+/*     int     dict_flags;
+/* DESCRIPTION
+/*     dict_inline_open() opens a read-only, in-memory table.
+/*     Example: "\fBinline:{\fIkey_1=value_1, ..., key_n=value_n\fR}".
+/*     The longer form with { key = value } allows values that
+/*     contain whitespace or comma.
+/* SEE ALSO
+/*     dict(3) generic dictionary manager
+/* LICENSE
+/* .ad
+/* .fi
+/*     The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/*     Wietse Venema
+/*     IBM T.J. Watson Research
+/*     P.O. Box 704
+/*     Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include <sys_defs.h>
+
+/* Utility library. */
+
+#include <msg.h>
+#include <mymalloc.h>
+#include <htable.h>
+#include <stringops.h>
+#include <dict.h>
+#include <dict_inline.h>
+
+/* Application-specific. */
+
+typedef struct {
+    DICT    dict;                      /* generic members */
+    HTABLE *table;                     /* lookup table */
+} DICT_INLINE;
+
+/* dict_inline_lookup - search inline table */
+
+static const char *dict_inline_lookup(DICT *dict, const char *query)
+{
+    DICT_INLINE *dict_inline = (DICT_INLINE *) dict;
+
+    DICT_ERR_VAL_RETURN(dict, DICT_ERR_NONE,
+                       htable_find(dict_inline->table, query));
+}
+
+/* dict_inline_close - disassociate from inline table */
+
+static void dict_inline_close(DICT *dict)
+{
+    DICT_INLINE *dict_inline = (DICT_INLINE *) dict;
+
+    htable_free(dict_inline->table, myfree);
+    dict_free(dict);
+}
+
+/* dict_inline_open - open inline table */
+
+DICT   *dict_inline_open(const char *name, int open_flags, int dict_flags)
+{
+    DICT_INLINE *dict_inline;
+    char   *cp, *saved_name = 0;
+    size_t  len;
+    HTABLE *table = 0;
+    char   *nameval, *vname, *value;
+    const char *err = 0;
+
+    /*
+     * Clarity first. Let the optimizer worry about redundant code.
+     */
+#define DICT_INLINE_RETURN(x) do { \
+           if (saved_name != 0) \
+               myfree(saved_name); \
+           if (table != 0) \
+               htable_free(table, myfree); \
+           return (x); \
+       } while (0)
+
+    /*
+     * Sanity checks.
+     */
+    if (open_flags != O_RDONLY)
+       DICT_INLINE_RETURN(dict_surrogate(DICT_TYPE_INLINE, name,
+                                         open_flags, dict_flags,
+                                 "%s:%s map requires O_RDONLY access mode",
+                                         DICT_TYPE_INLINE, name));
+
+    /*
+     * Parse the table into its constituent name=value pairs.
+     */
+    if ((len = balpar(name, CHARS_BRACE)) == 0 || name[len] != 0
+       || *(cp = saved_name = mystrndup(name + 1, len - 2)) == 0)
+       DICT_INLINE_RETURN(dict_surrogate(DICT_TYPE_INLINE, name,
+                                         open_flags, dict_flags,
+                                         "bad syntax: \"%s:%s\"; "
+                                         "need \"%s:{name=value...}\"",
+                                         DICT_TYPE_INLINE, name,
+                                         DICT_TYPE_INLINE));
+
+    table = htable_create(5);
+    while ((nameval = mystrtokq(&cp, CHARS_COMMA_SP, CHARS_BRACE)) != 0) {
+       if ((nameval[0] != CHARS_BRACE[0]
+          || (err = extpar(&nameval, CHARS_BRACE, EXTPAR_FLAG_STRIP)) == 0)
+           && (err = split_nameval(nameval, &vname, &value)) != 0)
+           break;
+       (void) htable_enter(table, vname, mystrdup(value));
+    }
+    if (err != 0 || table->used == 0)
+       DICT_INLINE_RETURN(dict_surrogate(DICT_TYPE_INLINE, name,
+                                         open_flags, dict_flags,
+                                         "%s: \"%s:%s\"; "
+                                         "need \"%s:{name=value...}\"",
+                                         err != 0 ? err : "empty table",
+                                         DICT_TYPE_INLINE, name,
+                                         DICT_TYPE_INLINE));
+
+    /*
+     * Bundle up the result.
+     */
+    dict_inline = (DICT_INLINE *)
+       dict_alloc(DICT_TYPE_INLINE, name, sizeof(*dict_inline));
+    dict_inline->dict.lookup = dict_inline_lookup;
+    dict_inline->dict.close = dict_inline_close;
+    dict_inline->dict.flags = dict_flags | DICT_FLAG_FIXED;
+    dict_inline->dict.owner.status = DICT_OWNER_TRUSTED;
+    dict_inline->table = table;
+    table = 0;
+    DICT_INLINE_RETURN(DICT_DEBUG (&dict_inline->dict));
+}
diff --git a/postfix/src/util/dict_inline.h b/postfix/src/util/dict_inline.h
new file mode 100644 (file)
index 0000000..9879acf
--- /dev/null
@@ -0,0 +1,37 @@
+#ifndef _DICT_INLINE_H_INCLUDED_
+#define _DICT_INLINE_H_INCLUDED_
+
+/*++
+/* NAME
+/*     dict_inline 3h
+/* SUMMARY
+/*     dictionary manager interface for inline tables
+/* SYNOPSIS
+/*     #include <dict_inline.h>
+/* DESCRIPTION
+/* .nf
+
+ /*
+  * Utility library.
+  */
+#include <dict.h>
+
+ /*
+  * External interface.
+  */
+#define DICT_TYPE_INLINE       "inline"
+
+extern DICT *dict_inline_open(const char *, int, int);
+
+/* 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
diff --git a/postfix/src/util/dict_inline.ref b/postfix/src/util/dict_inline.ref
new file mode 100644 (file)
index 0000000..0014d93
--- /dev/null
@@ -0,0 +1,17 @@
+./dict_open: error: empty table: "inline:{ }"; need "inline:{name=value...}"
+owner=trusted (uid=-1)
+./dict_open: error: missing '=' after attribute name: "inline:{ foo = xx }"; need "inline:{name=value...}"
+owner=trusted (uid=-1)
+./dict_open: error: bad syntax: "inline:{ foo=xx }x"; need "inline:{name=value...}"
+owner=trusted (uid=-1)
+./dict_open: error: bad syntax: "inline:{ foo=xx x"; need "inline:{name=value...}"
+owner=trusted (uid=-1)
+./dict_open: error: syntax error after '}' in "{x=y}x": "inline:{ foo=xx {x=y}x}"; need "inline:{name=value...}"
+owner=trusted (uid=-1)
+owner=trusted (uid=-1)
+> get foo
+foo=xx
+> get bar
+bar=lotsa stuff
+> get baz
+baz: not found
index cd89f86a2182fb577d6257e1d5dabd4cb4a78b18..0b5f62f91b7b5fdf5bc9d5bdee65d8090efe4b55 100644 (file)
 #include <dict_pipe.h>
 #include <dict_random.h>
 #include <dict_union.h>
+#include <dict_inline.h>
 #include <stringops.h>
 #include <split_at.h>
 #include <htable.h>
@@ -346,6 +347,7 @@ static const DICT_OPEN_INFO dict_open_info[] = {
     DICT_TYPE_PIPE, dict_pipe_open,
     DICT_TYPE_RANDOM, dict_random_open,
     DICT_TYPE_UNION, dict_union_open,
+    DICT_TYPE_INLINE, dict_inline_open,
 #ifndef USE_DYNAMIC_MAPS
 #ifdef HAS_PCRE
     DICT_TYPE_PCRE, dict_pcre_open,
index f20dc6ccf0c342800c66d7c1a7b93ed80f213d2c..445f3cb37d1947551b9d679e74ba17b788742f1b 100644 (file)
@@ -37,6 +37,7 @@
 
 #include "mymalloc.h"
 #include "msg.h"
+#include "stringops.h"
 #include "dict.h"
 #include "dict_static.h"
 
@@ -56,14 +57,42 @@ static void dict_static_close(DICT *dict)
 
 /* dict_static_open - make association with static variable */
 
-DICT   *dict_static_open(const char *name, int unused_flags, int dict_flags)
+DICT   *dict_static_open(const char *name, int open_flags, int dict_flags)
 {
     DICT   *dict;
+    const char *err;
+    char   *cp, *saved_name = 0;
 
+    /*
+     * Let the optimizer worry about eliminating redundant code.
+     */
+#define DICT_STATIC_OPEN_RETURN(d) do { \
+        DICT *__d = (d); \
+        if (saved_name != 0) \
+            myfree(saved_name); \
+        return (__d); \
+    } while (0)
+
+    /*
+     * Optionally strip surrounding braces and whitespace.
+     */
+    if (name[0] == CHARS_BRACE[0]) {
+       saved_name = cp = mystrdup(name);
+       if ((err = extpar(&cp, CHARS_BRACE, EXTPAR_FLAG_STRIP)) != 0)
+           DICT_STATIC_OPEN_RETURN(dict_surrogate(DICT_TYPE_STATIC, name,
+                                                  open_flags, dict_flags,
+                                                  "bad %s:name syntax: %s",
+                                                  DICT_TYPE_STATIC, err));
+       name = cp;
+    }
+
+    /*
+     * Bundle up the request.
+     */
     dict = dict_alloc(DICT_TYPE_STATIC, name, sizeof(*dict));
     dict->lookup = dict_static_lookup;
     dict->close = dict_static_close;
     dict->flags = dict_flags | DICT_FLAG_FIXED;
     dict->owner.status = DICT_OWNER_TRUSTED;
-    return (DICT_DEBUG (dict));
+    DICT_STATIC_OPEN_RETURN(DICT_DEBUG (dict));
 }
diff --git a/postfix/src/util/dict_static.ref b/postfix/src/util/dict_static.ref
new file mode 100644 (file)
index 0000000..0c3de56
--- /dev/null
@@ -0,0 +1,14 @@
+owner=trusted (uid=-1)
+> get foo
+foo=fooxx
+> get bar
+bar=fooxx
+./dict_open: error: bad static:name syntax: missing '}' in "{ foo xx "
+owner=trusted (uid=-1)
+./dict_open: error: bad static:name syntax: syntax error after '}' in "{ foo xx }x"
+owner=trusted (uid=-1)
+owner=trusted (uid=-1)
+> get foo
+foo=foo xx
+> get bar
+bar=foo xx