mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-22 01:49:47 +00:00
postfix-3.11-20250713
This commit is contained in:
parent
fcc88c9a9c
commit
e3501bc815
@ -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é.
|
||||
|
@ -0,0 +1,459 @@
|
||||
PPoossttffiixx BBaacckkwwaarrddss--CCoommppaattiibbiilliittyy SSaaffeettyy NNeett
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
PPuurrppoossee ooff tthhiiss ddooccuummeenntt
|
||||
|
||||
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.
|
||||
|
||||
OOvveerrvviieeww
|
||||
|
||||
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.
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg aappppeenndd__ddoott__mmyyddoommaaiinn==yyeess
|
||||
|
||||
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 "ppoossttffiixx rreellooaadd".
|
||||
|
||||
* 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:
|
||||
|
||||
# ppoossttccoonnff aappppeenndd__ddoott__mmyyddoommaaiinn==yyeess
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg cchhrroooott==yy
|
||||
|
||||
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:
|
||||
|
||||
# ppoossttccoonnff --FF ssmmttpp//iinneett//cchhrroooott==yy
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg ssmmttppdd__rreellaayy__rreessttrriiccttiioonnss == ((eemmppttyy))
|
||||
|
||||
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:
|
||||
|
||||
# ppoossttccoonnff ssmmttppdd__rreellaayy__rreessttrriiccttiioonnss==
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg ssmmttppuuttff88__eennaabbllee==nnoo
|
||||
|
||||
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:
|
||||
|
||||
# ppoossttccoonnff ssmmttppuuttff88__eennaabbllee==nnoo
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg mmyynneettwwoorrkkss__ssttyyllee==ssuubbnneett
|
||||
|
||||
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:
|
||||
|
||||
# ppoossttccoonnff mmyynneettwwoorrkkss__ssttyyllee==ssuubbnneett
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg rreellaayy__ddoommaaiinnss==$$mmyyddeessttiinnaattiioonn
|
||||
|
||||
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:
|
||||
|
||||
# ppoossttccoonnff ''rreellaayy__ddoommaaiinnss==$$mmyyddeessttiinnaattiioonn''
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
Note: quotes are required as indicated above.
|
||||
|
||||
Instead of $mydestination, it may be better to specify an explicit list of
|
||||
domain names.
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg ssmmttppdd__ttllss__ffiinnggeerrpprriinntt__ddiiggeesstt==mmdd55
|
||||
|
||||
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.
|
||||
|
||||
# ppoossttccoonnff ssmmttppdd__ttllss__ffiinnggeerrpprriinntt__ddiiggeesstt==mmdd55
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg ssmmttpp__ttllss__ffiinnggeerrpprriinntt__ddiiggeesstt==mmdd55
|
||||
|
||||
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.
|
||||
|
||||
# ppoossttccoonnff ''ssmmttpp__ttllss__ffiinnggeerrpprriinntt__ddiiggeesstt == mmdd55'' \\
|
||||
''llmmttpp__ttllss__ffiinnggeerrpprriinntt__ddiiggeesstt == mmdd55''
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg
|
||||
ssmmttppdd__rreellaayy__bbeeffoorree__rreecciippiieenntt__rreessttrriiccttiioonnss==nnoo
|
||||
|
||||
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:
|
||||
|
||||
# ppoossttccoonnff ssmmttppdd__rreellaayy__bbeeffoorree__rreecciippiieenntt__rreessttrriiccttiioonnss==nnoo
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg rreessppeeccttffuull__llooggggiinngg==nnoo
|
||||
|
||||
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.
|
||||
|
||||
# ppoossttccoonnff ""rreessppeeccttffuull__llooggggiinngg == nnoo""
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg
|
||||
ssmmttpp__ttllssrrpptt__sskkiipp__rreeuusseedd__hhaannddsshhaakkeess==yyeess
|
||||
|
||||
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:
|
||||
|
||||
# ppoossttccoonnff ssmmttpp__ttllssrrpptt__sskkiipp__rreeuusseedd__hhaannddsshhaakkeess==yyeess
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
UUssiinngg bbaacckkwwaarrddss--ccoommppaattiibbllee ddeeffaauulltt sseettttiinngg xxxxxx__sseeccuurriittyy__lleevveell==((eemmppttyy))
|
||||
|
||||
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:
|
||||
|
||||
# ppoossttccoonnff xxxxxx__sseeccuurriittyy__lleevveell==
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
where xxx is taken from the above compatibility message.
|
||||
|
||||
TTuurrnniinngg ooffff tthhee bbaacckkwwaarrddss--ccoommppaattiibbiilliittyy ssaaffeettyy nneett
|
||||
|
||||
Backwards compatibility is turned off by updating the compatibility_level
|
||||
setting in main.cf.
|
||||
|
||||
# ppoossttccoonnff ccoommppaattiibbiilliittyy__lleevveell==NN
|
||||
# ppoossttffiixx rreellooaadd
|
||||
|
||||
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.
|
||||
|
@ -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>
|
||||
|
@ -4236,15 +4236,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><a href="postconf.5.html#maillog_file">maillog_file</a></b>" work during daemon
|
||||
process initialization. </dd>
|
||||
|
||||
<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>POSTLOG_HOSTNAME</b></dt>
|
||||
<dt><b>XDG_RUNTIME_DIR</b></dt>
|
||||
|
||||
<dd>Needed to make "<b><a href="postconf.5.html#maillog_file">maillog_file</a></b>" work during daemon
|
||||
process initialization. </dd>
|
||||
<dd>Needed for debugging Postfix daemons with an XDG-style debugger.
|
||||
</dd>
|
||||
|
||||
</dl>
|
||||
|
||||
@ -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
|
||||
|
@ -2633,13 +2633,16 @@ Needed for debugging Postfix daemons with an X\-windows debugger.
|
||||
.IP "\fBMAIL_CONFIG\fR"
|
||||
Needed to make "\fBpostfix \-c\fR" work.
|
||||
.br
|
||||
.IP "\fBPOSTLOG_HOSTNAME\fR"
|
||||
Needed to make "\fBmaillog_file\fR" work during daemon
|
||||
process initialization.
|
||||
.br
|
||||
.IP "\fBPOSTLOG_SERVICE\fR"
|
||||
Needed to make "\fBmaillog_file\fR" work during daemon
|
||||
process initialization.
|
||||
.br
|
||||
.IP "\fBPOSTLOG_HOSTNAME\fR"
|
||||
Needed to make "\fBmaillog_file\fR" work during daemon
|
||||
process initialization.
|
||||
.IP "\fBXDG_RUNTIME_DIR\fR"
|
||||
Needed for debugging Postfix daemons with an XDG\-style debugger.
|
||||
.br
|
||||
.br
|
||||
.PP
|
||||
@ -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
|
||||
|
@ -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
|
||||
|
@ -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>
|
||||
|
@ -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
|
||||
|
@ -1683,3 +1683,4 @@ typofix
|
||||
LD
|
||||
PRELOAD
|
||||
rhansen
|
||||
XDG
|
||||
|
@ -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
|
||||
|
@ -106,3 +106,7 @@ Kozmenko
|
||||
Oleksandr
|
||||
Bataille
|
||||
balancers
|
||||
Unbroke
|
||||
XDG
|
||||
ENOTSOCK
|
||||
FustÃ
|
||||
|
@ -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",
|
||||
|
@ -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"
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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,
|
||||
|
@ -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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
@ -187,14 +185,6 @@
|
||||
/* 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);
|
||||
|
@ -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.
|
||||
*/
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user