]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-3.11-20250713
authorWietse Z Venema <wietse@porcupine.org>
Sun, 13 Jul 2025 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <ietf-dane@dukhovni.org>
Mon, 14 Jul 2025 04:29:23 +0000 (14:29 +1000)
24 files changed:
postfix/HISTORY
postfix/README_FILES/COMPATIBILITY_README
postfix/html/COMPATIBILITY_README.html
postfix/html/postconf.5.html
postfix/man/man5/postconf.5
postfix/mantools/check-spell-proto-html
postfix/proto/COMPATIBILITY_README.html
postfix/proto/postconf.proto
postfix/proto/stop
postfix/proto/stop.double-history
postfix/proto/stop.spell-history
postfix/src/global/dict_proxy.c
postfix/src/global/mail_params.h
postfix/src/global/mail_proto.h
postfix/src/global/mail_version.h
postfix/src/master/event_server.c
postfix/src/master/multi_server.c
postfix/src/postalias/postalias.c
postfix/src/postmap/postmap.c
postfix/src/proxymap/proxymap.c
postfix/src/util/dict.c
postfix/src/util/dict.h
postfix/src/util/dict_alloc.c
postfix/src/util/dict_test.c

index 0f2e25b15df3d5f6c697357a849b437aedd5f8a9..8a2ba1794aac652dec8064fb981dad5f69dbf1ac 100644 (file)
@@ -29345,3 +29345,53 @@ Apologies for any names omitted.
        Cleanup: simplified the rule parser in global/server_acl.c.
 
        Unbroke dict_debug Valgrind checks. File: util/dict_debug_test.sh.
+
+20250710
+
+       Bugfix (defect introduced: postfix-2.2, date 20050203):
+       after detecting a lookup table change, and after starting
+       a new postscreen process, the old postscreen process logged
+       an ENOTSOCK error while attempting to accept a connection
+       on a socket that it was no longer listening on. This error
+       was introduced first in the multi_server skeleton code, and
+       was five years later duplicated in the event_server skeleton
+       that was created for postscreen. Problem reported by Florian
+       Piekert. Files: master/multi_server.c, master/event_server.c.
+
+20250713
+
+       Cleanup: allow "postmap -s" and "postalias -s" with proxied
+       tables. The proxymap protocol already supported this. Files:
+       postmap/postmap.c, postalias/postalias.c.
+
+       Cleanup: simplified the proxymap protocol and the proxymap
+       table sharing strategy. Share only table instances that
+       have identical client-side dictionary flags when opening a
+       table (instead of sharing tables that have a common subset
+       of flags). With each client request, propagate all client-side
+       dictionary flags to the server, and upon request completion,
+       propagate all resulting server-side dictionary flags to the
+       client. Files: dict.h, dict_proxy.c, proxymap/proxymap.c,
+       global/mail_proto.h.
+
+       Cleanup; stop hard-coding "dict->flags = DICT_FLAG_FIXED"
+       in dict_alloc.c. All tables already overwrote that information.
+
+       Debugging: the default import_environment now also imports
+       XDG_RUNTIME_DIR to support GUI debugging a Postfix daemon
+       process on some platforms (it already imported XAUTHORITY
+       and DISPLAY for X-based debuggers). These environment
+       variables are set only when Postfix is started 'by hand'.
+       File: global/mail_params.h.
+
+       Graceful degradation: when a proxymap or proxywrite server
+       denies access to a table, do not terminate the program.
+       Instead, return a surrogate object that fails all requests
+       with an informative message. File: global/dict_proxy.c.
+
+       Workaround: added an example to the smtp_reply_filter
+       documentation that works around Microsoft SASL server
+       implementations that send a non-empty initial GSSAPI
+       challenge. File: proto/postconf.proto.
+
+       Typo in COMPATIBILITY_README.html. Emmanuel Fusté.
index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..8c3a0b71b4dd2c182cda530f8bad114ffb13df36 100644 (file)
@@ -0,0 +1,459 @@
+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\bfe\bet\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 3.0 introduces a safety net that runs Postfix programs with backwards-
+compatible default settings after an upgrade. The safety net will log a warning
+whenever a "new" default setting could have an negative effect on your mail
+flow.
+
+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
+
+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.
+
+Logged with compatibility_level < 1:
+
+  * Using backwards-compatible default setting append_dot_mydomain=yes
+
+  * Using backwards-compatible default setting chroot=y
+
+  * Using backwards-compatible default setting "smtpd_relay_restrictions =
+    (empty)"
+
+  * Using backwards-compatible default setting smtputf8_enable=no
+
+Logged with compatibility_level < 2:
+
+  * Using backwards-compatible default setting mynetworks_style=subnet
+
+  * Using backwards-compatible default setting relay_domains=$mydestination
+
+Logged with compatibility_level < 3.6:
+
+  * Using backwards-compatible default setting smtpd_tls_fingerprint_digest=md5
+
+  * Using backwards-compatible default setting smtp_tls_fingerprint_digest=md5
+
+  * Using backwards-compatible default setting lmtp_tls_fingerprint_digest=md5
+
+  * Using backwards-compatible default setting
+    smtpd_relay_before_recipient_restrictions=no
+
+  * Using backwards-compatible default setting respectful_logging=no
+
+Logged with compatibility_level < 3.11:
+
+  * using backwards-compatible default setting
+    smtp_tlsrpt_skip_reused_handshakes=yes
+
+  * using backwards-compatible default setting xxx_security_level=(empty)
+
+If such a message is logged in the context of a legitimate request, the system
+administrator should make the backwards-compatible setting permanent in main.cf
+or master.cf, as detailed in the sections that follow.
+
+When no more backwards-compatible settings need to be made permanent, the
+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
+
+The append_dot_mydomain default value has changed from "yes" to "no". This
+could result in unexpected non-delivery of email after Postfix is updated from
+an older version. The backwards-compatibility safety net is designed to prevent
+such surprises.
+
+As long as the append_dot_mydomain parameter is left unspecified at its
+implicit default value, and the compatibility_level setting is less than 1,
+Postfix may log one of the following messages:
+
+  * Messages about missing "localhost" in mydestination or other address class:
+
+        postfix/trivial-rewrite[14777]: using backwards-compatible
+            default setting append_dot_mydomain=yes to rewrite
+            "localhost" to "localhost.example.com"; please add
+            "localhost" to mydestination or other address class
+
+    If Postfix logs the above message, add "localhost" to mydestination (or
+    virtual_alias_domains, virtual_mailbox_domains, or relay_domains) and
+    execute the command "p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd".
+
+  * Messages about incomplete domains in email addresses:
+
+        postfix/trivial-rewrite[25835]: using backwards-compatible
+            default setting append_dot_mydomain=yes to rewrite "foo" to
+            "foo.example.com"
+
+    If Postfix logs the above message for domains different from "localhost",
+    and the sender cannot be changed to use complete domain names in email
+    addresses, then the system administrator should make the backwards-
+    compatible setting "append_dot_mydomain = yes" permanent in main.cf:
+
+        # p\bpo\bos\bst\btc\bco\bon\bnf\bf 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
+        # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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 c\bch\bhr\bro\boo\bot\bt=\b=y\by
+
+The master.cf chroot default value has changed from "y" (yes) to "n" (no). The
+new default avoids the need for copies of system files under the Postfix queue
+directory. However, sites with strict security requirements may want to keep
+the chroot feature enabled after updating Postfix from an older version. The
+backwards-compatibility safety net is designed allow the administrator to
+choose if they want to keep the old behavior.
+
+As long as a master.cf chroot field is left unspecified at its implicit default
+value, and the compatibility_level setting is less than 1, Postfix may log the
+following message while it reads the master.cf file:
+
+    postfix/master[27664]: /etc/postfix/master.cf: line 72: using
+        backwards-compatible default setting chroot=y
+
+If this service should remain chrooted, then the system administrator should
+make the backwards-compatible setting "chroot = y" permanent in master.cf. For
+example, to update the chroot setting for the "smtp inet" service:
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf -\b-F\bF s\bsm\bmt\btp\bp/\b/i\bin\bne\bet\bt/\b/c\bch\bhr\bro\boo\bot\bt=\b=y\by
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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 s\bsm\bmt\btp\bpd\bd_\b_r\bre\bel\bla\bay\by_\b_r\bre\bes\bst\btr\bri\bic\bct\bti\bio\bon\bns\bs =\b= (\b(e\bem\bmp\bpt\bty\by)\b)
+
+The smtpd_relay_restrictions feature was introduced with Postfix version 2.10,
+as a safety mechanism for configuration errors in smtpd_recipient_restrictions
+that could make Postfix an open relay.
+
+The smtpd_relay_restrictions implicit default setting forbids mail to remote
+destinations from clients that don't match permit_mynetworks or
+permit_sasl_authenticated. This could result in unexpected 'Relay access
+denied' errors after Postfix is updated from an older Postfix version. The
+backwards-compatibility safety net is designed to prevent such surprises.
+
+When the compatibility_level less than 1, and the smtpd_relay_restrictions
+parameter is left unspecified at its implicit default setting, Postfix may log
+the following message:
+
+    postfix/smtpd[38463]: using backwards-compatible default setting
+        "smtpd_relay_restrictions = (empty)" to avoid "Relay access
+        denied" error for recipient "user@example.com" from client
+        "host.example.net[10.0.0.2]"
+
+If this request should not be blocked, then the system administrator should
+make the backwards-compatible setting "smtpd_relay_restrictions=" (i.e. empty)
+permanent in main.cf:
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf s\bsm\bmt\btp\bpd\bd_\b_r\bre\bel\bla\bay\by_\b_r\bre\bes\bst\btr\bri\bic\bct\bti\bio\bon\bns\bs=\b=
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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 s\bsm\bmt\btp\bpu\but\btf\bf8\b8_\b_e\ben\bna\bab\bbl\ble\be=\b=n\bno\bo
+
+The smtputf8_enable default value has changed from "no" to "yes". With the new
+"yes" setting, the Postfix SMTP server rejects non-ASCII addresses from clients
+that don't request SMTPUTF8 support, after Postfix is updated from an older
+version. The backwards-compatibility safety net is designed to prevent such
+surprises.
+
+As long as the smtputf8_enable parameter is left unspecified at its implicit
+default value, and the compatibility_level setting is less than 1, Postfix logs
+a warning each time an SMTP command uses a non-ASCII address localpart without
+requesting SMTPUTF8 support:
+
+    postfix/smtpd[27560]: using backwards-compatible default setting
+        smtputf8_enable=no to accept non-ASCII sender address
+        "??@example.org" from localhost[127.0.0.1]
+
+    postfix/smtpd[27560]: using backwards-compatible default setting
+        smtputf8_enable=no to accept non-ASCII recipient address
+        "??@example.com" from localhost[127.0.0.1]
+
+If the address should not be rejected, and the client cannot be updated to use
+SMTPUTF8, then the system administrator should make the backwards-compatible
+setting "smtputf8_enable = no" permanent in main.cf:
+
+    # 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
+
+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 m\bmy\byn\bne\bet\btw\bwo\bor\brk\bks\bs_\b_s\bst\bty\byl\ble\be=\b=s\bsu\bub\bbn\bne\bet\bt
+
+The mynetworks_style default value has changed from "subnet" to "host". This
+parameter is used to implement the "permit_mynetworks" feature. The change
+could cause unexpected 'access denied' errors after Postfix is updated from an
+older version. The backwards-compatibility safety net is designed to prevent
+such surprises.
+
+As long as the mynetworks and mynetworks_style parameters are left unspecified
+at their implicit default values, and the compatibility_level setting is less
+than 2, the Postfix SMTP server may log one of the following messages:
+
+    postfix/smtpd[17375]: using backwards-compatible default setting
+        mynetworks_style=subnet to permit request from client
+        "foo.example.com[10.1.1.1]"
+
+    postfix/postscreen[24982]: using backwards-compatible default
+        setting mynetworks_style=subnet to permit request from client
+        "10.1.1.1"
+
+If the client request should not be rejected, then the system administrator
+should make the backwards-compatible setting "mynetworks_style = subnet"
+permanent in main.cf:
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf m\bmy\byn\bne\bet\btw\bwo\bor\brk\bks\bs_\b_s\bst\bty\byl\ble\be=\b=s\bsu\bub\bbn\bne\bet\bt
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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 r\bre\bel\bla\bay\by_\b_d\bdo\bom\bma\bai\bin\bns\bs=\b=$\b$m\bmy\byd\bde\bes\bst\bti\bin\bna\bat\bti\bio\bon\bn
+
+The relay_domains default value has changed from "$mydestination" to the empty
+value. This could result in unexpected 'Relay access denied' errors or ETRN
+errors after Postfix is updated from an older version. The backwards-
+compatibility safety net is designed to prevent such surprises.
+
+As long as the relay_domains parameter is left unspecified at its implicit
+default value, and the compatibility_level setting is less than 2, Postfix may
+log one of the following messages.
+
+  * Messages about accepting mail for a remote domain:
+
+        postfix/smtpd[19052]: using backwards-compatible default setting
+            relay_domains=$mydestination to accept mail for domain
+            "foo.example.com"
+
+        postfix/smtpd[19052]: using backwards-compatible default setting
+            relay_domains=$mydestination to accept mail for address
+            "user@foo.example.com"
+
+  * Messages about providing ETRN service for a remote domain:
+
+        postfix/smtpd[19138]: using backwards-compatible default setting
+            relay_domains=$mydestination to flush mail for domain
+            "bar.example.com"
+
+        postfix/smtp[13945]: using backwards-compatible default setting
+            relay_domains=$mydestination to update fast-flush logfile for
+            domain "bar.example.com"
+
+If Postfix should continue to accept mail for that domain or continue to
+provide ETRN service for that domain, then the system administrator should make
+the backwards-compatible setting "relay_domains = $mydestination" permanent in
+main.cf:
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf '\b'r\bre\bel\bla\bay\by_\b_d\bdo\bom\bma\bai\bin\bns\bs=\b=$\b$m\bmy\byd\bde\bes\bst\bti\bin\bna\bat\bti\bio\bon\bn'\b'
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+Note: quotes are required as indicated above.
+
+Instead of $mydestination, it may be better to specify an explicit list of
+domain names.
+
+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 s\bsm\bmt\btp\bpd\bd_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_d\bdi\big\bge\bes\bst\bt=\b=m\bmd\bd5\b5
+
+The smtpd_tls_fingerprint_digest default value has changed from "md5" to
+"sha256". With the new "sha256" setting, the Postfix SMTP server avoids using
+the deprecated "md5" algorithm and computes a more secure digest of the client
+certificate.
+
+If you're using the default "md5" setting, or even an explicit "sha1" (also
+deprecated) setting, you should consider switching to "sha256". This will
+require updating any associated lookup table keys with the "sha256" digests of
+the expected client certificate or public key.
+
+As long as the smtpd_tls_fingerprint_digest parameter is left unspecified at
+its implicit default value, and the compatibility_level setting is less than
+3.6, Postfix logs a warning each time a client certificate or public key
+fingerprint is (potentially) used for access control:
+
+    postfix/smtpd[27560]: using backwards-compatible default setting
+        smtpd_tls_fingerprint_digest=md5 to compute certificate fingerprints
+
+Since any client certificate fingerprints are passed in policy service lookups,
+and Postfix doesn't know whether the fingerprint will be used, the warning may
+also be logged when policy lookups are performed for connections that used a
+client certificate, even if the policy service does not in fact examine the
+client certificate. To reduce the noise somewhat, such warnings are issued at
+most once per smtpd(8) process instance.
+
+If you prefer to stick with "md5", you can suppress the warnings by making that
+setting explicit. After addressing any other compatibility warnings, you can
+update your compatibility level.
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf s\bsm\bmt\btp\bpd\bd_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_d\bdi\big\bge\bes\bst\bt=\b=m\bmd\bd5\b5
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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 s\bsm\bmt\btp\bp_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_d\bdi\big\bge\bes\bst\bt=\b=m\bmd\bd5\b5
+
+The smtp_tls_fingerprint_digest and lmtp_tls_fingerprint_digest default values
+have changed from "md5" to "sha256". With the new "sha256" setting, the Postfix
+SMTP and LMTP client avoids using the deprecated "md5" algorithm and computes a
+more secure digest of the server certificate.
+
+If you're using the default "md5" setting, or even an explicit "sha1" (also
+deprecated) setting, you should consider switching to "sha256". This will
+require updating any "fingerprint" security level policies in the TLS policy
+table to specify matching "sha256" digests of the expected server certificates
+or public keys.
+
+As long as the smtp_tls_fingerprint_digest (or LMTP equivalent) parameter is
+left unspecified at its implicit default value, and the compatibility_level
+setting is less than 3.6, Postfix logs a warning each time the "fingerprint"
+security level is used to specify matching "md5" digests of trusted server
+certificates or public keys:
+
+    postfix/smtp[27560]: using backwards-compatible default setting
+        smtp_tls_fingerprint_digest=md5 to compute certificate fingerprints
+
+If you prefer to stick with "md5", you can suppress the warnings by making that
+setting explicit. After addressing any other compatibility warnings, you can
+update your compatibility level.
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf '\b's\bsm\bmt\btp\bp_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_d\bdi\big\bge\bes\bst\bt =\b= m\bmd\bd5\b5'\b' \\b\
+        '\b'l\blm\bmt\btp\bp_\b_t\btl\bls\bs_\b_f\bfi\bin\bng\bge\ber\brp\bpr\bri\bin\bnt\bt_\b_d\bdi\big\bge\bes\bst\bt =\b= m\bmd\bd5\b5'\b'
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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
+s\bsm\bmt\btp\bpd\bd_\b_r\bre\bel\bla\bay\by_\b_b\bbe\bef\bfo\bor\bre\be_\b_r\bre\bec\bci\bip\bpi\bie\ben\bnt\bt_\b_r\bre\bes\bst\btr\bri\bic\bct\bti\bio\bon\bns\bs=\b=n\bno\bo
+
+The smtpd_relay_before_recipient_restrictions feature was introduced in Postfix
+version 3.6, to evaluate smtpd_relay_restrictions before
+smtpd_recipient_restrictions. Historically, smtpd_relay_restrictions was
+evaluated after smtpd_recipient_restrictions, contradicting documented
+behavior.
+
+    Background: smtpd_relay_restrictions is primarily designed to enforce a
+    mail relaying policy, while smtpd_recipient_restrictions is primarily
+    designed to enforce spam blocking policy. Both are evaluated while replying
+    to the RCPT TO command, and both support the same features.
+
+To maintain compatibility with earlier versions, Postfix will keep evaluating
+smtpd_recipient_restrictions before smtpd_relay_restrictions, as long as the
+compatibility_level is less than 3.6, and the
+smtpd_relay_before_recipient_restrictions parameter is left unspecified at its
+implicit default setting. As a reminder, Postfix may log the following message:
+
+    postfix/smtpd[54696]: using backwards-compatible default setting
+        smtpd_relay_before_recipient_restrictions=no to reject recipient
+        "user@example.com" from client "host.example.net[10.0.0.2]"
+
+If Postfix should keep evaluating smtpd_recipient_restrictions before
+smtpd_relay_restrictions, then the system administrator should make the
+backwards-compatible setting "smtpd_relay_before_recipient_restrictions=no"
+permanent in main.cf:
+
+    #  p\bpo\bos\bst\btc\bco\bon\bnf\bf s\bsm\bmt\btp\bpd\bd_\b_r\bre\bel\bla\bay\by_\b_b\bbe\bef\bfo\bor\bre\be_\b_r\bre\bec\bci\bip\bpi\bie\ben\bnt\bt_\b_r\bre\bes\bst\btr\bri\bic\bct\bti\bio\bon\bns\bs=\b=n\bno\bo
+    #  p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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 r\bre\bes\bsp\bpe\bec\bct\btf\bfu\bul\bl_\b_l\blo\bog\bgg\bgi\bin\bng\bg=\b=n\bno\bo
+
+Postfix version 3.6 deprecates configuration parameter names and logging that
+suggest white is better than black. Instead it prefers 'allowlist, 'denylist',
+and variations of those words. While the renamed configuration parameters have
+backwards-compatible default values, the changes in logging could affect
+logfile analysis tools.
+
+To avoid breaking existing logfile analysis tools, Postfix will keep logging
+the deprecated form, as long as the respectful_logging parameter is left
+unspecified at its implicit default value, and the compatibility_level setting
+is less than 3.6. As a reminder, Postfix may log the following when a remote
+SMTP client is allowlisted or denylisted:
+
+    postfix/postscreen[22642]: Using backwards-compatible default setting
+        respectful_logging=no for client [address]:port
+
+If Postfix should keep logging the deprecated form, then the system
+administrator should make the backwards-compatible setting "respectful_logging
+= no" permanent in main.cf.
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf "\b"r\bre\bes\bsp\bpe\bec\bct\btf\bfu\bul\bl_\b_l\blo\bog\bgg\bgi\bin\bng\bg =\b= n\bno\bo"\b"
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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
+s\bsm\bmt\btp\bp_\b_t\btl\bls\bsr\brp\bpt\bt_\b_s\bsk\bki\bip\bp_\b_r\bre\beu\bus\bse\bed\bd_\b_h\bha\ban\bnd\bds\bsh\bha\bak\bke\bes\bs=\b=y\bye\bes\bs
+
+Postfix version 3.11 changes the default value for
+smtp_tlsrpt_skip_reused_handshakes from "yes" to "no". The backwards-
+compatibility safety net is designed to prevent an unexpected change in
+reporting behavior when Postfix is updated from an older version.
+
+As long as the smtp_tlsrpt_skip_reused_handshakes parameter is left unspecified
+at its implicit default value, and the compatibility_level setting is less than
+3.11, Postfix will log a reminder that it is using the backwards-compatible
+default:
+
+    postfix/smtp[388157] using backwards-compatible default setting
+        smtp_tlsrpt_skip_reused_handshakes=yes
+
+To keep the old default setting, the system administrator should make the
+backwards-compatible setting "smtp_tlsrpt_skip_reused_handshakes = yes"
+permanent in main.cf:
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf s\bsm\bmt\btp\bp_\b_t\btl\bls\bsr\brp\bpt\bt_\b_s\bsk\bki\bip\bp_\b_r\bre\beu\bus\bse\bed\bd_\b_h\bha\ban\bnd\bds\bsh\bha\bak\bke\bes\bs=\b=y\bye\bes\bs
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+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 x\bxx\bxx\bx_\b_s\bse\bec\bcu\bur\bri\bit\bty\by_\b_l\ble\bev\bve\bel\bl=\b=(\b(e\bem\bmp\bpt\bty\by)\b)
+
+Postfix version 3.11 changes the default value for client TLS security levels
+from "empty" to "may". The backwards-compatibility safety net is designed to
+prevent an unexpected change in mail sending behavior when Postfix is updated
+from an older version.
+
+There is no equivalent change for Postfix server TLS security levels, because
+changing the level alone is not sufficient. Server-side TLS requires that at
+least one private key and one public-key certificate chain are configured.
+
+As long as a TLS security level parameter is left unspecified at its implicit
+default value, and the compatibility_level setting is less than 3.11, Postfix
+will log one of the following reminders that it is using the backwards-
+compatible default:
+
+    postfix/smtp[...] using backwards-compatible default setting
+        smtp_tls_security_level=(empty)
+
+    postfix/tlsproxy[...] using backwards-compatible default setting
+        tlsproxy_client_security_level=(empty)
+
+To keep the old default setting, the system administrator should make the
+backwards-compatible empty setting permanent in main.cf:
+
+    # p\bpo\bos\bst\btc\bco\bon\bnf\bf x\bxx\bxx\bx_\b_s\bse\bec\bcu\bur\bri\bit\bty\by_\b_l\ble\bev\bve\bel\bl=\b=
+    # p\bpo\bos\bst\btf\bfi\bix\bx r\bre\bel\blo\boa\bad\bd
+
+where xxx is taken from the above compatibility message.
+
+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.
+
+Starting with Postfix version 3.6, the compatibility level in the above warning
+message is the Postfix version that introduced the last incompatible change.
+The level is formatted as major.minor.patch, where patch is usually omitted and
+defaults to zero. Earlier compatibility levels are 0, 1 and 2.
+
+NOTE: Postfix 3.6 also introduces support for the "<level", "<=level", and
+other operators to compare compatibility levels. With the standard operators
+"<", "<=", etc., compatibility level "3.10" would be smaller than "3.9" which
+is undesirable.
+
index a814a761558740b38ed3f1a9d8afc6a111dda2e6..39dcad68177b0e163260e2ea355c03ea04db4713 100644 (file)
@@ -614,7 +614,7 @@ make the backwards-compatible setting "<a href="postconf.5.html#smtp_tlsrpt_skip
 default setting <i>xxx</i>_security_level=(empty)</a> </h2>
 
 <p> Postfix version 3.11 changes the default value for client TLS
-security levels from "empty" to "yes". The backwards-compatibility
+security levels from "empty" to "may". The backwards-compatibility
 safety net is designed to prevent an unexpected change in mail
 sending behavior when Postfix is updated from an older version.
 </p>
index 8332ff686fcc3addaf0f455c7276935696058c49..9b03afe72b2f08805f77709a364faf8e32891ae6 100644 (file)
@@ -4236,16 +4236,21 @@ environment.  Examples of relevant environment variables: </p>
 
 <dd>Needed to make "<b>postfix -c</b>" work. </dd>
 
-<dt><b>POSTLOG_SERVICE</b></dt>
+<dt><b>POSTLOG_HOSTNAME</b></dt>
 
 <dd>Needed to make "<b><a href="postconf.5.html#maillog_file">maillog_file</a></b>" work during daemon
 process initialization. </dd>
 
-<dt><b>POSTLOG_HOSTNAME</b></dt>
+<dt><b>POSTLOG_SERVICE</b></dt>
 
 <dd>Needed to make "<b><a href="postconf.5.html#maillog_file">maillog_file</a></b>" work during daemon
 process initialization. </dd>
 
+<dt><b>XDG_RUNTIME_DIR</b></dt>
+
+<dd>Needed for debugging Postfix daemons with an XDG-style debugger.
+</dd>
+
 </dl>
 
 <p> Specify a list of names and/or name=value pairs, separated by
@@ -12497,6 +12502,12 @@ line. </p>
 
 <pre>
 /etc/postfix/reply_filter:
+    # Some Microsoft servers violate <a href="https://tools.ietf.org/html/rfc2554">RFC 2554</a> section 4, causing Postfix
+    # to complain with "non-empty initial GSSAPI challenge from server"
+    /^334\s+GSSAPI\s+supported/ 334
+</pre>
+
+<pre>
     # Transform garbage into "250-filler..." so that it looks like
     # one line from a multi-line reply. It does not matter what we
     # substitute here as long it has the right syntax.  The Postfix
index 8baada96943a20aa2b8f69be0b0c5f0987e6d434..8c2039ecb6ec60819afe52fc406dbc83bdbc92dd 100644 (file)
@@ -2633,14 +2633,17 @@ Needed for debugging Postfix daemons with an X\-windows debugger.
 .IP "\fBMAIL_CONFIG\fR"
 Needed to make "\fBpostfix \-c\fR" work.
 .br
-.IP "\fBPOSTLOG_SERVICE\fR"
+.IP "\fBPOSTLOG_HOSTNAME\fR"
 Needed to make "\fBmaillog_file\fR" work during daemon
 process initialization.
 .br
-.IP "\fBPOSTLOG_HOSTNAME\fR"
+.IP "\fBPOSTLOG_SERVICE\fR"
 Needed to make "\fBmaillog_file\fR" work during daemon
 process initialization.
 .br
+.IP "\fBXDG_RUNTIME_DIR\fR"
+Needed for debugging Postfix daemons with an XDG\-style debugger.
+.br
 .br
 .PP
 Specify a list of names and/or name=value pairs, separated by
@@ -7892,6 +7895,14 @@ Examples:
 .nf
 .na
 /etc/postfix/reply_filter:
+    # Some Microsoft servers violate RFC 2554 section 4, causing Postfix
+    # to complain with "non\-empty initial GSSAPI challenge from server"
+    /^334\es+GSSAPI\es+supported/ 334
+.fi
+.ad
+.PP
+.nf
+.na
     # Transform garbage into "250\-filler..." so that it looks like
     # one line from a multi\-line reply. It does not matter what we
     # substitute here as long it has the right syntax.  The Postfix
index b81ce1f977b6dda79d40931f3d576cb18dba5115..ffd427f9613176c0a975c9f54093b6bcc7b97579 100755 (executable)
@@ -4,4 +4,4 @@
 
 LANG=C; export LANG
 
-mantools/dehtml proto/*html proto/*.proto | spell | grep -F -vxf proto/stop | grep -F -vxf proto/stop.spell-proto-html
+mantools/dehtml proto/*html proto/*.proto | tr '+' ' ' | spell | grep -F -vxf proto/stop | grep -F -vxf proto/stop.spell-proto-html
index 000f06269255ae728814459ba0a36e86b3e39ca5..20d72b423e7ce5e27c4e758fa5be39bcdc78af45 100644 (file)
@@ -614,7 +614,7 @@ make the backwards-compatible setting "smtp_tlsrpt_skip_reused_handshakes
 default setting <i>xxx</i>_security_level=(empty)</a> </h2>
 
 <p> Postfix version 3.11 changes the default value for client TLS
-security levels from "empty" to "yes". The backwards-compatibility
+security levels from "empty" to "may". The backwards-compatibility
 safety net is designed to prevent an unexpected change in mail
 sending behavior when Postfix is updated from an older version.
 </p>
index e6aa3680b3519abd65a87f50cbf729504cf62e16..0a4a9255e183169691216e800fa49460df17a565 100644 (file)
@@ -1984,15 +1984,20 @@ environment.  Examples of relevant environment variables: </p>
 
 <dd>Needed to make "<b>postfix -c</b>" work. </dd>
 
+<dt><b>POSTLOG_HOSTNAME</b></dt>
+
+<dd>Needed to make "<b>maillog_file</b>" work during daemon  
+process initialization. </dd>
+
 <dt><b>POSTLOG_SERVICE</b></dt>
 
 <dd>Needed to make "<b>maillog_file</b>" work during daemon 
 process initialization. </dd>
 
-<dt><b>POSTLOG_HOSTNAME</b></dt>
+<dt><b>XDG_RUNTIME_DIR</b></dt>
 
-<dd>Needed to make "<b>maillog_file</b>" work during daemon  
-process initialization. </dd>
+<dd>Needed for debugging Postfix daemons with an XDG-style debugger.
+</dd>
 
 </dl>
 
@@ -15098,6 +15103,12 @@ line. </p>
 
 <pre>
 /etc/postfix/reply_filter:
+    # Some Microsoft servers violate RFC 2554 section 4, causing Postfix
+    # to complain with "non-empty initial GSSAPI challenge from server"
+    /^334\s+GSSAPI\s+supported/ 334
+</pre>
+
+<pre>
     # Transform garbage into "250-filler..." so that it looks like
     # one line from a multi-line reply. It does not matter what we
     # substitute here as long it has the right syntax.  The Postfix
index c09b1c34eecfeef71ab381c59e80965f3a390720..5a7a3b12adf0a3d10c35b9f85f2297ad8145a764 100644 (file)
@@ -1683,3 +1683,4 @@ typofix
 LD
 PRELOAD
 rhansen
+XDG
index cf5da64051c77af0a13a2c47a24d17e5201d019d..6fb0842b727b9b9328bea5dfdd133a98b033da7a 100644 (file)
@@ -179,3 +179,5 @@ proto  proto COMPATIBILITY_README html
  postconf Makefile in postconf postconf c 
  dict_open Files util dict hc proxymap proxymap c 
  proxymap proxymap c 
+ postmap postmap c postalias postalias c 
+ client Files dict h dict_proxy c proxymap proxymap c 
index da067ab974517b75105dc61bace894f6d157a845..42b996fabad0935d6cbc7cb499e14e11ad95b35e 100644 (file)
@@ -106,3 +106,7 @@ Kozmenko
 Oleksandr
 Bataille
 balancers
+Unbroke
+XDG
+ENOTSOCK
+FustÃ
index 0157d01a2ba48dd2beb329ce51a34b1112eec90e..a0ce1b2e0070a8e04c6725ac38db21a386a6a1f4 100644 (file)
@@ -113,6 +113,7 @@ static int dict_proxy_sequence(DICT *dict, int function,
     VSTREAM *stream;
     int     status;
     int     count = 0;
+    int     inst_flags;
     int     request_flags;
 
     /*
@@ -126,8 +127,8 @@ static int dict_proxy_sequence(DICT *dict, int function,
     VSTRING_TERMINATE(dict_proxy->reskey);
     VSTRING_RESET(dict_proxy->result);
     VSTRING_TERMINATE(dict_proxy->result);
-    request_flags = dict_proxy->inst_flags
-       | (dict->flags & DICT_FLAG_RQST_MASK);
+    inst_flags = dict_proxy->inst_flags;
+    request_flags = dict->flags;
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
        errno = 0;
@@ -136,15 +137,17 @@ static int dict_proxy_sequence(DICT *dict, int function,
            || attr_print(stream, ATTR_FLAG_NONE,
                          SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_SEQUENCE),
                          SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
+                         SEND_ATTR_INT(MAIL_ATTR_INST_FLAGS, inst_flags),
                          SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
                          SEND_ATTR_INT(MAIL_ATTR_FUNC, function),
                          ATTR_TYPE_END) != 0
            || vstream_fflush(stream)
            || attr_scan(stream, ATTR_FLAG_STRICT,
                         RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
+                        RECV_ATTR_INT(MAIL_ATTR_FLAGS, &dict->flags),
                         RECV_ATTR_STR(MAIL_ATTR_KEY, dict_proxy->reskey),
                         RECV_ATTR_STR(MAIL_ATTR_VALUE, dict_proxy->result),
-                        ATTR_TYPE_END) != 3) {
+                        ATTR_TYPE_END) != 4) {
            if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
                msg_warn("%s: service %s: %m", myname, dict_proxy->service);
        } else {
@@ -194,6 +197,7 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
     VSTREAM *stream;
     int     status;
     int     count = 0;
+    int     inst_flags;
     int     request_flags;
 
     /*
@@ -205,8 +209,8 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
      */
     VSTRING_RESET(dict_proxy->result);
     VSTRING_TERMINATE(dict_proxy->result);
-    request_flags = dict_proxy->inst_flags
-       | (dict->flags & DICT_FLAG_RQST_MASK);
+    inst_flags = dict_proxy->inst_flags;
+    request_flags = dict->flags;
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
        errno = 0;
@@ -215,14 +219,16 @@ static const char *dict_proxy_lookup(DICT *dict, const char *key)
            || attr_print(stream, ATTR_FLAG_NONE,
                          SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_LOOKUP),
                          SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
+                         SEND_ATTR_INT(MAIL_ATTR_INST_FLAGS, inst_flags),
                          SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
                          SEND_ATTR_STR(MAIL_ATTR_KEY, key),
                          ATTR_TYPE_END) != 0
            || vstream_fflush(stream)
            || attr_scan(stream, ATTR_FLAG_STRICT,
                         RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
+                        RECV_ATTR_INT(MAIL_ATTR_FLAGS, &dict->flags),
                         RECV_ATTR_STR(MAIL_ATTR_VALUE, dict_proxy->result),
-                        ATTR_TYPE_END) != 2) {
+                        ATTR_TYPE_END) != 3) {
            if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
                msg_warn("%s: service %s: %m", myname, dict_proxy->service);
        } else {
@@ -267,6 +273,7 @@ static int dict_proxy_update(DICT *dict, const char *key, const char *value)
     VSTREAM *stream;
     int     status;
     int     count = 0;
+    int     inst_flags;
     int     request_flags;
 
     /*
@@ -276,8 +283,8 @@ static int dict_proxy_update(DICT *dict, const char *key, const char *value)
      * associated with a specific connection. Each lookup needs to specify
      * the table and the flags that were specified to dict_proxy_open().
      */
-    request_flags = dict_proxy->inst_flags
-       | (dict->flags & DICT_FLAG_RQST_MASK);
+    inst_flags = dict_proxy->inst_flags;
+    request_flags = dict->flags;
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
        errno = 0;
@@ -286,6 +293,7 @@ static int dict_proxy_update(DICT *dict, const char *key, const char *value)
            || attr_print(stream, ATTR_FLAG_NONE,
                          SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_UPDATE),
                          SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
+                         SEND_ATTR_INT(MAIL_ATTR_INST_FLAGS, inst_flags),
                          SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
                          SEND_ATTR_STR(MAIL_ATTR_KEY, key),
                          SEND_ATTR_STR(MAIL_ATTR_VALUE, value),
@@ -293,7 +301,8 @@ static int dict_proxy_update(DICT *dict, const char *key, const char *value)
            || vstream_fflush(stream)
            || attr_scan(stream, ATTR_FLAG_STRICT,
                         RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
-                        ATTR_TYPE_END) != 1) {
+                        RECV_ATTR_INT(MAIL_ATTR_FLAGS, &dict->flags),
+                        ATTR_TYPE_END) != 2) {
            if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno != ENOENT))
                msg_warn("%s: service %s: %m", myname, dict_proxy->service);
        } else {
@@ -337,6 +346,7 @@ static int dict_proxy_delete(DICT *dict, const char *key)
     VSTREAM *stream;
     int     status;
     int     count = 0;
+    int     inst_flags;
     int     request_flags;
 
     /*
@@ -346,8 +356,8 @@ static int dict_proxy_delete(DICT *dict, const char *key)
      * associated with a specific connection. Each lookup needs to specify
      * the table and the flags that were specified to dict_proxy_open().
      */
-    request_flags = dict_proxy->inst_flags
-       | (dict->flags & DICT_FLAG_RQST_MASK);
+    inst_flags = dict_proxy->inst_flags;
+    request_flags = dict->flags;
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
        errno = 0;
@@ -356,13 +366,15 @@ static int dict_proxy_delete(DICT *dict, const char *key)
            || attr_print(stream, ATTR_FLAG_NONE,
                          SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_DELETE),
                          SEND_ATTR_STR(MAIL_ATTR_TABLE, dict->name),
+                         SEND_ATTR_INT(MAIL_ATTR_INST_FLAGS, inst_flags),
                          SEND_ATTR_INT(MAIL_ATTR_FLAGS, request_flags),
                          SEND_ATTR_STR(MAIL_ATTR_KEY, key),
                          ATTR_TYPE_END) != 0
            || vstream_fflush(stream)
            || attr_scan(stream, ATTR_FLAG_STRICT,
                         RECV_ATTR_INT(MAIL_ATTR_STATUS, &status),
-                        ATTR_TYPE_END) != 1) {
+                        RECV_ATTR_INT(MAIL_ATTR_FLAGS, &dict->flags),
+                        ATTR_TYPE_END) != 2) {
            if (msg_verbose || count > 1 || (errno && errno != EPIPE && errno !=
                                             ENOENT))
                msg_warn("%s: service %s: %m", myname, dict_proxy->service);
@@ -478,16 +490,20 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_flags)
     dict_proxy->dict.delete = dict_proxy_delete;
     dict_proxy->dict.sequence = dict_proxy_sequence;
     dict_proxy->dict.close = dict_proxy_close;
-    dict_proxy->inst_flags = (dict_flags & DICT_FLAG_INST_MASK);
+    dict_proxy->inst_flags = dict_flags;
     dict_proxy->reskey = vstring_alloc(10);
     dict_proxy->result = vstring_alloc(10);
     dict_proxy->clnt = *pstream;
     dict_proxy->service = service;
 
+#define DICT_PROXY_ERR_RETURN(d) do { \
+       DICT *_d = (d); \
+       dict_proxy_close(&dict_proxy->dict); \
+       return (_d); \
+    } while (0)
+
     /*
      * Establish initial contact and get the map type specific flags.
-     * 
-     * XXX Should retrieve flags from local instance.
      */
     for (;;) {
        stream = clnt_stream_access(dict_proxy->clnt);
@@ -496,7 +512,7 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_flags)
            || attr_print(stream, ATTR_FLAG_NONE,
                          SEND_ATTR_STR(MAIL_ATTR_REQ, PROXY_REQ_OPEN),
                      SEND_ATTR_STR(MAIL_ATTR_TABLE, dict_proxy->dict.name),
-                    SEND_ATTR_INT(MAIL_ATTR_FLAGS, dict_proxy->inst_flags),
+                SEND_ATTR_INT(MAIL_ATTR_INST_FLAGS, dict_proxy->inst_flags),
                          ATTR_TYPE_END) != 0
            || vstream_fflush(stream)
            || attr_scan(stream, ATTR_FLAG_STRICT,
@@ -512,14 +528,17 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_flags)
                         dict_flags_str(server_flags));
            switch (status) {
            case PROXY_STAT_BAD:
-               msg_fatal("%s open failed for table \"%s\": invalid request",
-                         dict_proxy->service, dict_proxy->dict.name);
+               DICT_PROXY_ERR_RETURN(dict_surrogate(DICT_TYPE_PROXY,
+                             dict_proxy->dict.name, open_flags, dict_flags,
+                        "%s open failed for table \"%s\": invalid request",
+                              dict_proxy->service, dict_proxy->dict.name));
            case PROXY_STAT_DENY:
-               msg_fatal("%s service is not configured for table \"%s\"",
-                         dict_proxy->service, dict_proxy->dict.name);
+               DICT_PROXY_ERR_RETURN(dict_surrogate(DICT_TYPE_PROXY,
+                             dict_proxy->dict.name, open_flags, dict_flags,
+                           "%s service is not configured for table \"%s\"",
+                              dict_proxy->service, dict_proxy->dict.name));
            case PROXY_STAT_OK:
-               dict_proxy->dict.flags = (dict_flags & ~DICT_FLAG_IMPL_MASK)
-                   | (server_flags & DICT_FLAG_IMPL_MASK);
+               dict_proxy->dict.flags = server_flags;
                return (&dict_proxy->dict);
            default:
                msg_warn("%s open failed for table \"%s\": unexpected status %d",
index 690256a603a757bde293e8d3283e1773584658cd..cf7d791ead22e7dd81288d95f68acc9adb94d796 100644 (file)
@@ -2663,7 +2663,8 @@ extern int var_fflush_refresh;
 #define VAR_IMPORT_ENVIRON             "import_environment"
 #define DEF_IMPORT_ENVIRON             "MAIL_CONFIG MAIL_DEBUG MAIL_LOGTAG " \
                                        "TZ XAUTHORITY DISPLAY LANG=C " \
-                                       "POSTLOG_SERVICE POSTLOG_HOSTNAME"
+                                       "POSTLOG_SERVICE POSTLOG_HOSTNAME" \
+                                       "XDG_RUNTIME_DIR"
 extern char *var_import_environ;
 
 #define VAR_EXPORT_ENVIRON             "export_environment"
index 798de6694a5fb73dba601eabc526cf0028c350a5..d784ce42dc46556d0519d6ffc20f62e58975842d 100644 (file)
@@ -210,6 +210,8 @@ extern char *mail_pathname(const char *, const char *);
 #define MAIL_ATTR_COMPAT_LEVEL "compatibility_level"
 #define MAIL_ATTR_MAIL_VERSION "mail_version"
 
+#define MAIL_ATTR_INST_FLAGS   "instance_flags"
+
  /*
   * Suffixes for sender_name, sender_domain etc.
   */
index f19314a407d5cb7aa34135c474d0e861748285e6..a1d0ccefdc3d15ffa088d76d364b3f953c34f59f 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      "20250709"
+#define MAIL_RELEASE_DATE      "20250713"
 #define MAIL_VERSION_NUMBER    "3.11"
 
 #ifdef SNAPSHOT
index 9802bdf2f02d368b5112b70a515f854d8ea82b0d..30e80ba5e01b859df9f07bf2a96da0c66070d267 100644 (file)
@@ -273,6 +273,7 @@ static unsigned event_server_generation;
 static void (*event_server_pre_disconn) (VSTREAM *, char *, char **);
 static void (*event_server_slow_exit) (char *, char **);
 static int event_server_watchdog = 1000;
+static int event_server_drain_was_called = 0;
 
 /* event_server_exit - normal termination */
 
@@ -327,6 +328,9 @@ int     event_server_drain(void)
     const char *myname = "event_server_drain";
     int     fd;
 
+    if (event_server_drain_was_called)
+       return;
+
     switch (fork()) {
        /* Try again later. */
     case -1:
@@ -343,6 +347,7 @@ int     event_server_drain(void)
                msg_warn("%s: dup2(%d, %d): %m", myname, STDIN_FILENO, fd);
        }
        var_use_limit = 1;
+       event_server_drain_was_called = 1;
        return (0);
        /* Let the master start a new process. */
     default:
@@ -445,6 +450,9 @@ static void event_server_accept_local(int unused_event, void *context)
     int     time_left = -1;
     int     fd;
 
+    if (event_server_drain_was_called)
+       return;
+
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection (the number of processes competing for clients is
@@ -457,6 +465,8 @@ static void event_server_accept_local(int unused_event, void *context)
 
     if (event_server_pre_accept)
        event_server_pre_accept(event_server_name, event_server_argv);
+    if (event_server_drain_was_called)
+       return;
     fd = LOCAL_ACCEPT(listen_fd);
     if (event_server_lock != 0
        && myflock(vstream_fileno(event_server_lock), INTERNAL_LOCK,
@@ -483,6 +493,9 @@ static void event_server_accept_pass(int unused_event, void *context)
     int     fd;
     HTABLE *attr = 0;
 
+    if (event_server_drain_was_called)
+       return;
+
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection (the number of processes competing for clients is
@@ -495,6 +508,8 @@ static void event_server_accept_pass(int unused_event, void *context)
 
     if (event_server_pre_accept)
        event_server_pre_accept(event_server_name, event_server_argv);
+    if (event_server_drain_was_called)
+       return;
     fd = pass_accept_attr(listen_fd, &attr);
     if (event_server_lock != 0
        && myflock(vstream_fileno(event_server_lock), INTERNAL_LOCK,
@@ -520,6 +535,9 @@ static void event_server_accept_inet(int unused_event, void *context)
     int     time_left = -1;
     int     fd;
 
+    if (event_server_drain_was_called)
+       return;
+
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection (the number of processes competing for clients is
@@ -532,6 +550,8 @@ static void event_server_accept_inet(int unused_event, void *context)
 
     if (event_server_pre_accept)
        event_server_pre_accept(event_server_name, event_server_argv);
+    if (event_server_drain_was_called)
+       return;
     fd = inet_accept(listen_fd);
     if (event_server_lock != 0
        && myflock(vstream_fileno(event_server_lock), INTERNAL_LOCK,
index 6150f229aeb537442d50fba8ea6970aa41b4b580..51004d6d029e07b48ee19a301af36f0c7cc916ff 100644 (file)
@@ -260,6 +260,7 @@ static VSTREAM *multi_server_lock;
 static int multi_server_in_flow_delay;
 static unsigned multi_server_generation;
 static void (*multi_server_pre_disconn) (VSTREAM *, char *, char **);
+static int multi_server_drain_was_called = 0;
 
 /* multi_server_exit - normal termination */
 
@@ -295,6 +296,9 @@ int     multi_server_drain(void)
     const char *myname = "multi_server_drain";
     int     fd;
 
+    if (multi_server_drain_was_called)
+       return;
+
     switch (fork()) {
        /* Try again later. */
     case -1:
@@ -311,6 +315,7 @@ int     multi_server_drain(void)
                msg_warn("%s: dup2(%d, %d): %m", myname, STDIN_FILENO, fd);
        }
        var_use_limit = 1;
+       multi_server_drain_was_called = 1;
        return (0);
        /* Let the master start a new process. */
     default:
@@ -429,6 +434,9 @@ static void multi_server_accept_local(int unused_event, void *context)
     int     time_left = -1;
     int     fd;
 
+    if (multi_server_drain_was_called)
+       return;
+
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection (the number of processes competing for clients is
@@ -441,6 +449,8 @@ static void multi_server_accept_local(int unused_event, void *context)
 
     if (multi_server_pre_accept)
        multi_server_pre_accept(multi_server_name, multi_server_argv);
+    if (multi_server_drain_was_called)
+       return;
     fd = LOCAL_ACCEPT(listen_fd);
     if (multi_server_lock != 0
        && myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
@@ -467,6 +477,9 @@ static void multi_server_accept_pass(int unused_event, void *context)
     int     fd;
     HTABLE *attr = 0;
 
+    if (multi_server_drain_was_called)
+       return;
+
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection (the number of processes competing for clients is
@@ -479,6 +492,8 @@ static void multi_server_accept_pass(int unused_event, void *context)
 
     if (multi_server_pre_accept)
        multi_server_pre_accept(multi_server_name, multi_server_argv);
+    if (multi_server_drain_was_called)
+       return;
     fd = pass_accept_attr(listen_fd, &attr);
     if (multi_server_lock != 0
        && myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
@@ -504,6 +519,9 @@ static void multi_server_accept_inet(int unused_event, void *context)
     int     time_left = -1;
     int     fd;
 
+    if (multi_server_drain_was_called)
+       return;
+
     /*
      * Be prepared for accept() to fail because some other process already
      * got the connection (the number of processes competing for clients is
@@ -516,6 +534,8 @@ static void multi_server_accept_inet(int unused_event, void *context)
 
     if (multi_server_pre_accept)
        multi_server_pre_accept(multi_server_name, multi_server_argv);
+    if (multi_server_drain_was_called)
+       return;
     fd = inet_accept(listen_fd);
     if (multi_server_lock != 0
        && myflock(vstream_fileno(multi_server_lock), INTERNAL_LOCK,
index c17b6a1d609b5fce7f156a7a2ae173db3241785e..9e77a6b207144fc830592746d314ff76f695a633 100644 (file)
@@ -690,8 +690,6 @@ static void postalias_seq(const char *map_type, const char *map_name,
     const char *value;
     int     func;
 
-    if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
-       msg_fatal("can't sequence maps via the proxy service");
     dict = dict_open3(map_type, map_name, O_RDONLY, dict_flags);
     for (func = DICT_SEQ_FUN_FIRST; /* void */ ; func = DICT_SEQ_FUN_NEXT) {
        if (dict_seq(dict, func, &key, &value) != 0)
index 9e8c7838186d16610b6e9c328831741e2c01e20c..8f4a83c37db0433c6788e4d53445b855d93a1472 100644 (file)
@@ -899,8 +899,6 @@ static void postmap_seq(const char *map_type, const char *map_name,
     const char *value;
     int     func;
 
-    if (strcmp(map_type, DICT_TYPE_PROXY) == 0)
-       msg_fatal("can't sequence maps via the proxy service");
     dict = dict_open3(map_type, map_name, O_RDONLY, dict_flags);
     for (func = DICT_SEQ_FUN_FIRST; /* void */ ; func = DICT_SEQ_FUN_NEXT) {
        if (dict_seq(dict, func, &key, &value) != 0)
index 3a00c33c1f21de0ccb9419280dc30b77f6300ccf..270e491a0ead1838323043c4224fd5c8bd3f83ce 100644 (file)
@@ -320,7 +320,7 @@ static char *get_nested_dict_name(char *type_name)
 
 /* proxy_map_find - look up or open table */
 
-static DICT *proxy_map_find(const char *map_type_name, int request_flags,
+static DICT *proxy_map_find(const char *map_type_name, int inst_flags,
                                    int *statp)
 {
     DICT   *dict;
@@ -354,26 +354,12 @@ static DICT *proxy_map_find(const char *map_type_name, int request_flags,
 
     /*
      * Open one instance of a map for each combination of name+flags.
-     * 
-     * Assume that a map instance can be shared among clients with different
-     * paranoia flag settings and with different map lookup flag settings.
-     * 
-     * XXX The open() flags are passed implicitly, via the selection of the
-     * service name. For a more sophisticated interface, appropriate subsets
-     * of open() flags should be received directly from the client.
      */
-    vstring_sprintf(map_type_name_flags, "%s:%s", map_type_name,
-                   dict_flags_str(request_flags & DICT_FLAG_INST_MASK));
-    if (msg_verbose)
-       msg_info("proxy_map_find: %s", STR(map_type_name_flags));
-    if ((dict = dict_handle(STR(map_type_name_flags))) == 0) {
-       dict = dict_open(map_type_name, proxy_writer ?
-                        WRITE_OPEN_FLAGS : READ_OPEN_FLAGS,
-                        request_flags);
-       if (dict == 0)
-           msg_panic("proxy_map_find: dict_open null result");
-       dict_register(STR(map_type_name_flags), dict);
-    }
+    dict = dict_open(map_type_name, proxy_writer ?
+                    WRITE_OPEN_FLAGS : READ_OPEN_FLAGS,
+                    inst_flags);
+    if (dict == 0)
+       msg_panic("proxy_map_find: dict_open null result");
     dict->error = 0;
     return (dict);
 }
@@ -382,6 +368,7 @@ static DICT *proxy_map_find(const char *map_type_name, int request_flags,
 
 static void proxymap_sequence_service(VSTREAM *client_stream)
 {
+    int     inst_flags;
     int     request_flags;
     DICT   *dict;
     int     request_func;
@@ -395,19 +382,19 @@ static void proxymap_sequence_service(VSTREAM *client_stream)
      */
     if (attr_scan(client_stream, ATTR_FLAG_STRICT,
                  RECV_ATTR_STR(MAIL_ATTR_TABLE, request_map),
+                 RECV_ATTR_INT(MAIL_ATTR_INST_FLAGS, &inst_flags),
                  RECV_ATTR_INT(MAIL_ATTR_FLAGS, &request_flags),
                  RECV_ATTR_INT(MAIL_ATTR_FUNC, &request_func),
-                 ATTR_TYPE_END) != 3
+                 ATTR_TYPE_END) != 4
        || (request_func != DICT_SEQ_FUN_FIRST
            && request_func != DICT_SEQ_FUN_NEXT)) {
        reply_status = PROXY_STAT_BAD;
        reply_key = reply_value = "";
-    } else if ((dict = proxy_map_find(STR(request_map), request_flags,
+    } else if ((dict = proxy_map_find(STR(request_map), inst_flags,
                                      &reply_status)) == 0) {
        reply_key = reply_value = "";
     } else {
-       dict->flags = ((dict->flags & ~DICT_FLAG_RQST_MASK)
-                      | (request_flags & DICT_FLAG_RQST_MASK));
+       dict->flags = request_flags;
        dict_status = dict_seq(dict, request_func, &reply_key, &reply_value);
        if (dict_status == 0) {
            reply_status = PROXY_STAT_OK;
@@ -426,6 +413,7 @@ static void proxymap_sequence_service(VSTREAM *client_stream)
      */
     attr_print(client_stream, ATTR_FLAG_NONE,
               SEND_ATTR_INT(MAIL_ATTR_STATUS, reply_status),
+              SEND_ATTR_INT(MAIL_ATTR_FLAGS, dict->flags),
               SEND_ATTR_STR(MAIL_ATTR_KEY, reply_key),
               SEND_ATTR_STR(MAIL_ATTR_VALUE, reply_value),
               ATTR_TYPE_END);
@@ -435,6 +423,7 @@ static void proxymap_sequence_service(VSTREAM *client_stream)
 
 static void proxymap_lookup_service(VSTREAM *client_stream)
 {
+    int     inst_flags;
     int     request_flags;
     DICT   *dict;
     const char *reply_value;
@@ -445,16 +434,16 @@ static void proxymap_lookup_service(VSTREAM *client_stream)
      */
     if (attr_scan(client_stream, ATTR_FLAG_STRICT,
                  RECV_ATTR_STR(MAIL_ATTR_TABLE, request_map),
+                 RECV_ATTR_INT(MAIL_ATTR_INST_FLAGS, &inst_flags),
                  RECV_ATTR_INT(MAIL_ATTR_FLAGS, &request_flags),
                  RECV_ATTR_STR(MAIL_ATTR_KEY, request_key),
-                 ATTR_TYPE_END) != 3) {
+                 ATTR_TYPE_END) != 4) {
        reply_status = PROXY_STAT_BAD;
        reply_value = "";
-    } else if ((dict = proxy_map_find(STR(request_map), request_flags,
+    } else if ((dict = proxy_map_find(STR(request_map), inst_flags,
                                      &reply_status)) == 0) {
        reply_value = "";
-    } else if (dict->flags = ((dict->flags & ~DICT_FLAG_RQST_MASK)
-                             | (request_flags & DICT_FLAG_RQST_MASK)),
+    } else if (dict->flags = request_flags,
               (reply_value = dict_get(dict, STR(request_key))) != 0) {
        reply_status = PROXY_STAT_OK;
     } else if (dict->error == 0) {
@@ -471,6 +460,7 @@ static void proxymap_lookup_service(VSTREAM *client_stream)
      */
     attr_print(client_stream, ATTR_FLAG_NONE,
               SEND_ATTR_INT(MAIL_ATTR_STATUS, reply_status),
+              SEND_ATTR_INT(MAIL_ATTR_FLAGS, dict->flags),
               SEND_ATTR_STR(MAIL_ATTR_VALUE, reply_value),
               ATTR_TYPE_END);
 }
@@ -479,6 +469,7 @@ static void proxymap_lookup_service(VSTREAM *client_stream)
 
 static void proxymap_update_service(VSTREAM *client_stream)
 {
+    int     inst_flags;
     int     request_flags;
     DICT   *dict;
     int     dict_status;
@@ -495,21 +486,22 @@ static void proxymap_update_service(VSTREAM *client_stream)
      */
     if (attr_scan(client_stream, ATTR_FLAG_STRICT,
                  RECV_ATTR_STR(MAIL_ATTR_TABLE, request_map),
+                 RECV_ATTR_INT(MAIL_ATTR_INST_FLAGS, &inst_flags),
                  RECV_ATTR_INT(MAIL_ATTR_FLAGS, &request_flags),
                  RECV_ATTR_STR(MAIL_ATTR_KEY, request_key),
                  RECV_ATTR_STR(MAIL_ATTR_VALUE, request_value),
-                 ATTR_TYPE_END) != 4) {
+                 ATTR_TYPE_END) != 5) {
        reply_status = PROXY_STAT_BAD;
     } else if (proxy_writer == 0) {
        msg_warn("refusing %s update request on non-%s service",
                 STR(request_map), MAIL_SERVICE_PROXYWRITE);
        reply_status = PROXY_STAT_DENY;
-    } else if ((dict = proxy_map_find(STR(request_map), request_flags,
+    } else if ((dict = proxy_map_find(STR(request_map), inst_flags,
                                      &reply_status)) == 0) {
         /* void */ ;
     } else {
-       dict->flags = ((dict->flags & ~DICT_FLAG_RQST_MASK)
-                      | (request_flags & DICT_FLAG_RQST_MASK)
+       /* Sync the table now. Don't abort on duplicate update. */
+       dict->flags = (request_flags
                       | DICT_FLAG_SYNC_UPDATE | DICT_FLAG_DUP_REPLACE);
        dict_status = dict_put(dict, STR(request_key), STR(request_value));
        if (dict_status == 0) {
@@ -527,6 +519,7 @@ static void proxymap_update_service(VSTREAM *client_stream)
      */
     attr_print(client_stream, ATTR_FLAG_NONE,
               SEND_ATTR_INT(MAIL_ATTR_STATUS, reply_status),
+              SEND_ATTR_INT(MAIL_ATTR_FLAGS, dict->flags),
               ATTR_TYPE_END);
 }
 
@@ -534,6 +527,7 @@ static void proxymap_update_service(VSTREAM *client_stream)
 
 static void proxymap_delete_service(VSTREAM *client_stream)
 {
+    int     inst_flags;
     int     request_flags;
     DICT   *dict;
     int     dict_status;
@@ -547,20 +541,21 @@ static void proxymap_delete_service(VSTREAM *client_stream)
      */
     if (attr_scan(client_stream, ATTR_FLAG_STRICT,
                  RECV_ATTR_STR(MAIL_ATTR_TABLE, request_map),
+                 RECV_ATTR_INT(MAIL_ATTR_INST_FLAGS, &inst_flags),
                  RECV_ATTR_INT(MAIL_ATTR_FLAGS, &request_flags),
                  RECV_ATTR_STR(MAIL_ATTR_KEY, request_key),
-                 ATTR_TYPE_END) != 3) {
+                 ATTR_TYPE_END) != 4) {
        reply_status = PROXY_STAT_BAD;
     } else if (proxy_writer == 0) {
        msg_warn("refusing %s delete request on non-%s service",
                 STR(request_map), MAIL_SERVICE_PROXYWRITE);
        reply_status = PROXY_STAT_DENY;
-    } else if ((dict = proxy_map_find(STR(request_map), request_flags,
+    } else if ((dict = proxy_map_find(STR(request_map), inst_flags,
                                      &reply_status)) == 0) {
         /* void */ ;
     } else {
-       dict->flags = ((dict->flags & ~DICT_FLAG_RQST_MASK)
-                      | (request_flags & DICT_FLAG_RQST_MASK)
+       /* Sync the table now. There is no close() request. */
+       dict->flags = (request_flags
                       | DICT_FLAG_SYNC_UPDATE);
        dict_status = dict_del(dict, STR(request_key));
        if (dict_status == 0) {
@@ -578,6 +573,7 @@ static void proxymap_delete_service(VSTREAM *client_stream)
      */
     attr_print(client_stream, ATTR_FLAG_NONE,
               SEND_ATTR_INT(MAIL_ATTR_STATUS, reply_status),
+              SEND_ATTR_INT(MAIL_ATTR_FLAGS, dict->flags),
               ATTR_TYPE_END);
 }
 
@@ -585,7 +581,7 @@ static void proxymap_delete_service(VSTREAM *client_stream)
 
 static void proxymap_open_service(VSTREAM *client_stream)
 {
-    int     request_flags;
+    int     inst_flags;
     DICT   *dict;
     int     reply_status;
     int     reply_flags;
@@ -595,11 +591,11 @@ static void proxymap_open_service(VSTREAM *client_stream)
      */
     if (attr_scan(client_stream, ATTR_FLAG_STRICT,
                  RECV_ATTR_STR(MAIL_ATTR_TABLE, request_map),
-                 RECV_ATTR_INT(MAIL_ATTR_FLAGS, &request_flags),
+                 RECV_ATTR_INT(MAIL_ATTR_INST_FLAGS, &inst_flags),
                  ATTR_TYPE_END) != 2) {
        reply_status = PROXY_STAT_BAD;
        reply_flags = 0;
-    } else if ((dict = proxy_map_find(STR(request_map), request_flags,
+    } else if ((dict = proxy_map_find(STR(request_map), inst_flags,
                                      &reply_status)) == 0) {
        reply_flags = 0;
     } else {
@@ -843,14 +839,6 @@ int     main(int argc, char **argv)
      */
     MAIL_VERSION_STAMP_ALLOCATE;
 
-    /*
-     * Workaround for programs that make explicit dict_register() calls with
-     * a table that is already registered under a different name. This is
-     * safe only in programs that do not unregister or close a table that is
-     * registered with multiple names.
-     */
-    dict_allow_multiple_dict_register_names = 1;
-
     /*
      * XXX When invoked with the master.cf service name "proxywrite", the
      * proxymap daemon will allow update requests. To update a table that is
index 87dee602f4cf94957eab9ff5eefabcf920ff001d..943772325656dd9ed3264e65bcfa4797272e6d8a 100644 (file)
@@ -82,8 +82,6 @@
 /*     const char *name,
 /*     int     open_flags,
 /*     int     dict_flags)
-/*
-/*     int     dict_allow_multiple_dict_register_names;
 /* DESCRIPTION
 /*     This module maintains a collection of name-value dictionaries.
 /*     Each dictionary has its own name and has its own methods to read
 /*     This encourages consistent sharing of dictionary instances that
 /*     have the exact same type:name and (initial) flags. The result
 /*     value is the string value of the \fIout\fR VSTRING buffer.
-/*
-/*     dict_allow_multiple_dict_register_names enables a temporary
-/*     workaround for programs that make explicit dict_register()
-/*     calls with a table that is already registered under a different
-/*     name. Setting this to non-zero allows a dictionary to be
-/*     registered under multiple names. This workaround is safe only
-/*     in programs that do not unregister or close a table that is
-/*     registered with multiple names.
 /* TRUST AND PROVENANCE
 /* .ad
 /* .fi
@@ -339,14 +329,6 @@ typedef struct {
        dict = node->dict; \
 } while (0)
 
- /*
-  * Workaround for programs that make explicit dict_register() calls with
-  * tables that are already registered under a different name. This is safe
-  * only in programs that do not unregister or close a table that is
-  * registered with multiple names.
-  */
-int     dict_allow_multiple_dict_register_names = 0;
-
 #define STR(x) vstring_str(x)
 
 /* dict_register_close - trigger dictionary cleanup */
@@ -367,8 +349,7 @@ void    dict_register(const char *dict_name, DICT *dict_info)
     /*
      * Enforce referential integrity.
      */
-    if (dict_allow_multiple_dict_register_names == 0
-       && dict_info->reg_name && strcmp(dict_name, dict_info->reg_name) != 0)
+    if (dict_info->reg_name && strcmp(dict_name, dict_info->reg_name) != 0)
        msg_panic("%s: '%s:%s' is already registered under '%s' and cannot "
                  "also be registered under '%s'", myname, dict_info->type,
                  dict_info->name, dict_info->reg_name, dict_name);
index 595f18ed005dae26d459da44f468188179e6ff41..36def9b3c7758612d7d7207f12ddf8217c100d43 100644 (file)
@@ -141,32 +141,12 @@ extern void dict_free(DICT *);
   * The subsets of flags that control how a map is used. These are relevant
   * mainly for proxymap support. Note: some categories overlap.
   * 
-  * DICT_FLAG_IMPL_MASK - flags that are set by the map implementation itself.
-  * 
   * DICT_FLAG_PARANOID - requestor flags that forbid the use of insecure map
   * types for security-sensitive operations. These flags are checked by the
   * map implementation itself upon open, lookup etc. requests.
-  * 
-  * DICT_FLAG_RQST_MASK - all requestor flags, including paranoid flags, that
-  * the requestor may change between open, lookup etc. requests. These
-  * specify requestor properties, not map properties.
-  * 
-  * DICT_FLAG_INST_MASK - none of the above flags. The requestor may not change
-  * these flags between open, lookup, etc. requests (although a map may make
-  * changes to its copy of some of these flags). The proxymap server opens
-  * only one map instance for all client requests with the same values of
-  * these flags, and the proxymap client uses its own saved copy of these
-  * flags. DICT_FLAG_SRC_RHS_IS_FILE is an example of such a flag.
   */
 #define DICT_FLAG_PARANOID \
        (DICT_FLAG_NO_REGSUB | DICT_FLAG_NO_PROXY | DICT_FLAG_NO_UNAUTH)
-#define DICT_FLAG_IMPL_MASK    (DICT_FLAG_FIXED | DICT_FLAG_PATTERN | \
-                               DICT_FLAG_MULTI_WRITER)
-#define DICT_FLAG_RQST_MASK    (DICT_FLAG_FOLD_ANY | DICT_FLAG_LOCK | \
-                               DICT_FLAG_DUP_REPLACE | DICT_FLAG_DUP_WARN | \
-                               DICT_FLAG_DUP_IGNORE | DICT_FLAG_SYNC_UPDATE | \
-                               DICT_FLAG_PARANOID | DICT_FLAG_UTF8_MASK)
-#define DICT_FLAG_INST_MASK    ~(DICT_FLAG_IMPL_MASK | DICT_FLAG_RQST_MASK)
 
  /*
   * Feature tests.
@@ -286,14 +266,6 @@ extern DICT *PRINTFLIKE(5, 6) dict_surrogate(const char *, const char *, int, in
 extern char *dict_make_registered_name(VSTRING *, const char *, int, int);
 extern char *dict_make_registered_name4(VSTRING *, const char *, const char *, int, int);
 
- /*
-  * Workaround for programs that make explicit dict_register() calls with a
-  * table that is already registered under a different name. This is safe
-  * only in programs that do not unregister or close a table that is
-  * registered with multiple names.
-  */
-extern int dict_allow_multiple_dict_register_names;
-
  /*
   * This name is reserved for matchlist error handling.
   */
index d780ecf970e50584efee066693ecc4d164d356ee..bea8e7d7e52fbcf0f2b2a1915816865d4be76780 100644 (file)
@@ -147,7 +147,7 @@ DICT   *dict_alloc(const char *dict_type, const char *dict_name, ssize_t size)
 
     dict->type = mystrdup(dict_type);
     dict->name = mystrdup(dict_name);
-    dict->flags = DICT_FLAG_FIXED;
+    dict->flags = 0;
     dict->lookup = dict_default_lookup;
     dict->update = dict_default_update;
     dict->delete = dict_default_delete;
index bd2cadd4dfdea6509854c5b30fe15cad413ee8f0..26fcd097580db741391028c1762340b1591a23ad 100644 (file)
@@ -146,14 +146,8 @@ void    dict_test(int argc, char **argv)
            vstream_printf("dict flags %s\n",
                           dict_flags_str(dict->flags));
        } else if (strcmp(cmd, "masks") == 0 && !key && !value) {
-           vstream_printf("DICT_FLAG_IMPL_MASK %s\n",
-                          dict_flags_str(DICT_FLAG_IMPL_MASK));
            vstream_printf("DICT_FLAG_PARANOID %s\n",
                           dict_flags_str(DICT_FLAG_PARANOID));
-           vstream_printf("DICT_FLAG_RQST_MASK %s\n",
-                          dict_flags_str(DICT_FLAG_RQST_MASK));
-           vstream_printf("DICT_FLAG_INST_MASK %s\n",
-                          dict_flags_str(DICT_FLAG_INST_MASK));
        } else {
            vstream_printf("usage: %s\n", USAGE);
        }