2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-22 09:57:34 +00:00

postfix-3.11-20250606

This commit is contained in:
Wietse Z Venema 2025-06-06 00:00:00 -05:00 committed by Viktor Dukhovni
parent 6a87331d09
commit 32475272ff
62 changed files with 1509 additions and 332 deletions

1
postfix/.indent.pro vendored
View File

@ -248,6 +248,7 @@
-TNBBIO -TNBBIO
-TNVTABLE_INFO -TNVTABLE_INFO
-TOPTIONS -TOPTIONS
-TOSSL_DGST
-TPCF_DBMS_INFO -TPCF_DBMS_INFO
-TPCF_DEPR_PARAM_INFO -TPCF_DEPR_PARAM_INFO
-TPCF_EVAL_CTX -TPCF_EVAL_CTX

View File

@ -29031,7 +29031,7 @@ Apologies for any names omitted.
causing information to become garbled. Fix by Michael causing information to become garbled. Fix by Michael
Tokarev. File: postconf/postconf_edit.c. Tokarev. File: postconf/postconf_edit.c.
20259317 20250317
Documentation: added text to clarify the difference between Documentation: added text to clarify the difference between
SMTP connection reuse and TLS session resumption, and that SMTP connection reuse and TLS session resumption, and that
@ -29095,10 +29095,102 @@ Apologies for any names omitted.
20250418 20250418
Code health: added unit tests for connection address and Code health: added 16 unit tests for connection address and
port information received through haproxy or postscreen, port information received through haproxy or postscreen,
and improved error handling. Files: smtpd/smtpd_peer.c, and improved error handling. Files: smtpd/smtpd_peer.c,
smtpd/smtpd_haproxy.c, smtpd/smtpd_peer_test.c. smtpd/smtpd_haproxy.c, smtpd/smtpd_peer_test.c.
Unit tests for 'direct' connections are deferred pending Unit tests for 'direct' connections are deferred pending
support to mock or intercept system library function calls. support to mock or intercept system library function calls.
20250419
Documentation: Postfix LMDB locking protocol description.
File: proto/lmdb_table.
20250504
Logging: the memcache client truncated a memcached server
error message too aggressively. File: global/dict_memcache.c.
Code health: the dict_cache module did not expose a database
error to the caller. Files: util/dict_cache.[hc].
Code health: the verify(8) daemon now replies with 'address
verification status unavailable' when cache lookup fails
due to a database error, instead of replying with 'address
verification in progress'. File: verify/verify.c.
Code health: the verify(8) daemon no longer schedules an
address verification probe after a cache lookup for that
address failed due to a database error. File: verify/verify.c.
20250523
Documentation: load balancer workaround for Postfix <= 3.9.
Files: proto/mysql_table, proto/pgsql_table.
20250425
Documentation: TLSRPT_README typofix by Paul Menzel. File:
proto/TLSRPT_README.html.
20250509
Documentation: in "enable_idna2003_compatibility" descriptions,
confused zeta with final sigma. Geert Hendrickx. Files:
proto/SMTPUTF8_README, proto/postconf.proto.
Feature: specify "key_digest = name-of-openssl-digest" to
run memcache lookup keys through the named OpenSSL digest
and convert the result to lowercase hexadecimal characters,
after processing the key_format feature. This prevents a
database access error when keys may exceed the memcache
server's key length limit (usually, 250 bytes). Files:
20250523
Workaround: tweaked the timeout setting in postconf.proto
javascript. File: proto/postconf.html.prolog
20250525
Code health: don't allow the postmap or postalias "-i"
option together with one of the (-d, -q, or -s) options on
the command line. Files: postmap/postmap.c, postalias/postalias.c,
postmap/mode_conflict_test.*, postalias/mode_conflict_test.*.
Testing: some postalias and postmap tests depended on the
installed main.cf file. Files: postalias/Makefile.in,
postmap/Makefile.in.
Testing: 'nosleep' preload module to eliminate the delay
after logging a fatal error and before terminating a program.
Files: testing/Makefile.in, testing/nosleep.c,
postalias/Makefile.in, postmap/Makefile.in
20250526
Bugfix (defect introduced: Postfix 0.7.0, date 19990118):
postmap and postalias supported "-i" incremental updates
only for databases that support "bulk" create. With other
databases, the "-i" option was rejected with a misleading
error message "no 'map create' support". File: util/mkmap_open.c.
Usability: improved error message when a CDB table refuses
a delete or incremental update request (it complained about
some obscure POSIX open() flags). File: util/dict_cdb.c.
Cleanup: remove unnecessary newline characters in debug
logging. File: util/dict_db.c.
Debugging: added debug logging to the myflock() function.
File: util/myflock.c.
20250601
Changed the default smtp_tlsrpt_skip_reused_handshakes
setting from "yes" to "no". The new default is enabled with
compatibility level >= 3.11. Files: smtp/smtp_tlsrpt.c,
global/mail_params.[hc], proto/COMPATIBILITY_README.html.
proto/memcache_table, global/dict_memcache.c, util/hex_code.[hc].

View File

@ -12,7 +12,7 @@ DIRS = src/util src/global src/dns src/tls src/xsasl src/master src/milter \
src/postsuper src/qmqpd src/spawn src/flush src/verify \ src/postsuper src/qmqpd src/spawn src/flush src/verify \
src/virtual src/proxymap src/anvil src/scache src/discard src/tlsmgr \ src/virtual src/proxymap src/anvil src/scache src/discard src/tlsmgr \
src/postmulti src/postscreen src/dnsblog src/tlsproxy \ src/postmulti src/postscreen src/dnsblog src/tlsproxy \
src/posttls-finger src/postlogd src/posttls-finger src/postlogd src/testing
MANDIRS = proto man html MANDIRS = proto man html
LIBEXEC = libexec/post-install libexec/postfix-script libexec/postfix-wrapper \ LIBEXEC = libexec/post-install libexec/postfix-script libexec/postfix-wrapper \
libexec/postmulti-script libexec/postfix-tls-script libexec/postmulti-script libexec/postfix-tls-script

View File

@ -57,6 +57,11 @@ Logged with compatibility_level < 3.6:
* Using backwards-compatible default setting respectful_logging=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
If such a message is logged in the context of a legitimate request, the system 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 administrator should make the backwards-compatible setting permanent in main.cf
or master.cf, as detailed in the sections that follow. or master.cf, as detailed in the sections that follow.
@ -72,9 +77,9 @@ 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 an older version. The backwards-compatibility safety net is designed to prevent
such surprises. such surprises.
As long as the append_dot_mydomain parameter is left at its implicit default As long as the append_dot_mydomain parameter is left unspecified at its
value, and the compatibility_level setting is less than 1, Postfix may log one implicit default value, and the compatibility_level setting is less than 1,
of the following messages: Postfix may log one of the following messages:
* Messages about missing "localhost" in mydestination or other address class: * Messages about missing "localhost" in mydestination or other address class:
@ -110,9 +115,9 @@ the chroot feature enabled after updating Postfix from an older version. The
backwards-compatibility safety net is designed allow the administrator to backwards-compatibility safety net is designed allow the administrator to
choose if they want to keep the old behavior. choose if they want to keep the old behavior.
As long as a master.cf chroot field is left at its implicit default value, and As long as a master.cf chroot field is left unspecified at its implicit default
the compatibility_level setting is less than 1, Postfix may log the following value, and the compatibility_level setting is less than 1, Postfix may log the
message while it reads the master.cf file: following message while it reads the master.cf file:
postfix/master[27664]: /etc/postfix/master.cf: line 72: using postfix/master[27664]: /etc/postfix/master.cf: line 72: using
backwards-compatible default setting chroot=y backwards-compatible default setting chroot=y
@ -137,8 +142,8 @@ denied' errors after Postfix is updated from an older Postfix version. The
backwards-compatibility safety net is designed to prevent such surprises. backwards-compatibility safety net is designed to prevent such surprises.
When the compatibility_level less than 1, and the smtpd_relay_restrictions When the compatibility_level less than 1, and the smtpd_relay_restrictions
parameter is left at its implicit default setting, Postfix may log the parameter is left unspecified at its implicit default setting, Postfix may log
following message: the following message:
postfix/smtpd[38463]: using backwards-compatible default setting postfix/smtpd[38463]: using backwards-compatible default setting
"smtpd_relay_restrictions = (empty)" to avoid "Relay access "smtpd_relay_restrictions = (empty)" to avoid "Relay access
@ -160,10 +165,10 @@ that don't request SMTPUTF8 support, after Postfix is updated from an older
version. The backwards-compatibility safety net is designed to prevent such version. The backwards-compatibility safety net is designed to prevent such
surprises. surprises.
As long as the smtputf8_enable parameter is left at its implicit default value, As long as the smtputf8_enable parameter is left unspecified at its implicit
and the compatibility_level setting is less than 1, Postfix logs a warning each default value, and the compatibility_level setting is less than 1, Postfix logs
time an SMTP command uses a non-ASCII address localpart without requesting a warning each time an SMTP command uses a non-ASCII address localpart without
SMTPUTF8 support: requesting SMTPUTF8 support:
postfix/smtpd[27560]: using backwards-compatible default setting postfix/smtpd[27560]: using backwards-compatible default setting
smtputf8_enable=no to accept non-ASCII sender address smtputf8_enable=no to accept non-ASCII sender address
@ -188,9 +193,9 @@ could cause unexpected 'access denied' errors after Postfix is updated from an
older version. The backwards-compatibility safety net is designed to prevent older version. The backwards-compatibility safety net is designed to prevent
such surprises. such surprises.
As long as the mynetworks and mynetworks_style parameters are left at their As long as the mynetworks and mynetworks_style parameters are left unspecified
implicit default values, and the compatibility_level setting is less than 2, at their implicit default values, and the compatibility_level setting is less
the Postfix SMTP server may log one of the following messages: than 2, the Postfix SMTP server may log one of the following messages:
postfix/smtpd[17375]: using backwards-compatible default setting postfix/smtpd[17375]: using backwards-compatible default setting
mynetworks_style=subnet to permit request from client mynetworks_style=subnet to permit request from client
@ -214,9 +219,9 @@ value. This could result in unexpected 'Relay access denied' errors or ETRN
errors after Postfix is updated from an older version. The backwards- errors after Postfix is updated from an older version. The backwards-
compatibility safety net is designed to prevent such surprises. compatibility safety net is designed to prevent such surprises.
As long as the relay_domains parameter is left at its implicit default value, As long as the relay_domains parameter is left unspecified at its implicit
and the compatibility_level setting is less than 2, Postfix may log one of the default value, and the compatibility_level setting is less than 2, Postfix may
following messages. log one of the following messages.
* Messages about accepting mail for a remote domain: * Messages about accepting mail for a remote domain:
@ -263,10 +268,10 @@ deprecated) setting, you should consider switching to "sha256". This will
require updating any associated lookup table keys with the "sha256" digests of require updating any associated lookup table keys with the "sha256" digests of
the expected client certificate or public key. the expected client certificate or public key.
As long as the smtpd_tls_fingerprint_digest parameter is left at its implicit As long as the smtpd_tls_fingerprint_digest parameter is left unspecified at
default value, and the compatibility_level setting is less than 3.6, Postfix its implicit default value, and the compatibility_level setting is less than
logs a warning each time a client certificate or public key fingerprint is 3.6, Postfix logs a warning each time a client certificate or public key
(potentially) used for access control: fingerprint is (potentially) used for access control:
postfix/smtpd[27560]: using backwards-compatible default setting postfix/smtpd[27560]: using backwards-compatible default setting
smtpd_tls_fingerprint_digest=md5 to compute certificate fingerprints smtpd_tls_fingerprint_digest=md5 to compute certificate fingerprints
@ -299,10 +304,10 @@ table to specify matching "sha256" digests of the expected server certificates
or public keys. or public keys.
As long as the smtp_tls_fingerprint_digest (or LMTP equivalent) parameter is As long as the smtp_tls_fingerprint_digest (or LMTP equivalent) parameter is
left at its implicit default value, and the compatibility_level setting is less left unspecified at its implicit default value, and the compatibility_level
than 3.6, Postfix logs a warning each time the "fingerprint" security level is setting is less than 3.6, Postfix logs a warning each time the "fingerprint"
used to specify matching "md5" digests of trusted server certificates or public security level is used to specify matching "md5" digests of trusted server
keys: certificates or public keys:
postfix/smtp[27560]: using backwards-compatible default setting postfix/smtp[27560]: using backwards-compatible default setting
smtp_tls_fingerprint_digest=md5 to compute certificate fingerprints smtp_tls_fingerprint_digest=md5 to compute certificate fingerprints
@ -332,8 +337,8 @@ behavior.
To maintain compatibility with earlier versions, Postfix will keep evaluating To maintain compatibility with earlier versions, Postfix will keep evaluating
smtpd_recipient_restrictions before smtpd_relay_restrictions, as long as the smtpd_recipient_restrictions before smtpd_relay_restrictions, as long as the
compatibility_level is less than 3.6, and the compatibility_level is less than 3.6, and the
smtpd_relay_before_recipient_restrictions parameter is left at its implicit smtpd_relay_before_recipient_restrictions parameter is left unspecified at its
default setting. As a reminder, Postfix may log the following message: implicit default setting. As a reminder, Postfix may log the following message:
postfix/smtpd[54696]: using backwards-compatible default setting postfix/smtpd[54696]: using backwards-compatible default setting
smtpd_relay_before_recipient_restrictions=no to reject recipient smtpd_relay_before_recipient_restrictions=no to reject recipient
@ -356,10 +361,10 @@ backwards-compatible default values, the changes in logging could affect
logfile analysis tools. logfile analysis tools.
To avoid breaking existing logfile analysis tools, Postfix will keep logging To avoid breaking existing logfile analysis tools, Postfix will keep logging
the deprecated form, as long as the respectful_logging parameter is left at its the deprecated form, as long as the respectful_logging parameter is left
implicit default value, and the compatibility_level setting is less than 3.6. unspecified at its implicit default value, and the compatibility_level setting
As a reminder, Postfix may log the following when a remote SMTP client is is less than 3.6. As a reminder, Postfix may log the following when a remote
allowlisted or denylisted: SMTP client is allowlisted or denylisted:
postfix/postscreen[22642]: Using backwards-compatible default setting postfix/postscreen[22642]: Using backwards-compatible default setting
respectful_logging=no for client [address]:port respectful_logging=no for client [address]:port
@ -371,6 +376,29 @@ administrator should make the backwards-compatible setting "respectful_logging
# ppoossttccoonnff ""rreessppeeccttffuull__llooggggiinngg == nnoo"" # ppoossttccoonnff ""rreessppeeccttffuull__llooggggiinngg == nnoo""
# ppoossttffiixx rreellooaadd # 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
TTuurrnniinngg ooffff tthhee bbaacckkwwaarrddss--ccoommppaattiibbiilliittyy ssaaffeettyy nneett TTuurrnniinngg ooffff tthhee bbaacckkwwaarrddss--ccoommppaattiibbiilliittyy ssaaffeettyy nneett
Backwards compatibility is turned off by updating the compatibility_level Backwards compatibility is turned off by updating the compatibility_level

View File

@ -278,8 +278,8 @@ current versions of the Firefox and Chrome web browsers. Specify
"enable_idna2003_compatibility = yes" to get the historical behavior. "enable_idna2003_compatibility = yes" to get the historical behavior.
This affects the conversion of domain names that contain for example the German This affects the conversion of domain names that contain for example the German
sz (ß) and the Greek zeta (ς). See https://unicode.org/cldr/utility/idna.jsp sz (ß) and the Greek (final) sigma (ς). See https://unicode.org/cldr/utility/
for more examples. idna.jsp for more examples.
CCrreeddiittss CCrreeddiittss

View File

@ -188,11 +188,11 @@ Notes:
Untrusted TTLLSS ccoonnnneeccttiioonn rreeuusseedd to mail.example.com[ipaddr]:25: Untrusted TTLLSS ccoonnnneeccttiioonn rreeuusseedd to mail.example.com[ipaddr]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
* By default, Postfix does not report the TLSRPT status for a TLS handshake * With TLSRPT enabled, the Postfix SMTP client reports the TLSRPT status for
that reuses a previously-negotiated TLS session (there would be no new all TLS handshakes (the default as of Postfix 3.11). Specify
information to report). Specify "smtp_tlsrpt_skip_reused_handshakes = no" "smtp_tlsrpt_skip_reused_handshakes = yes" (the default with Postfix 3.10)
to report the TLSRPT status for all TLS handshakes. This may be useful for to skip reporting TLS handshakes that reuse a previously-negotiated TLS
troubleshooting. session as there would be no new information to report.
* Postfix logging for certificate verification failures may differ between * Postfix logging for certificate verification failures may differ between
new or reused TLS sessions. new or reused TLS sessions.
@ -256,7 +256,7 @@ Options:
MMTTAA--SSTTSS SSuuppppoorrtt vviiaa ssmmttpp__ttllss__ppoolliiccyy__mmaappss MMTTAA--SSTTSS SSuuppppoorrtt vviiaa ssmmttpp__ttllss__ppoolliiccyy__mmaappss
Postfix supports MTA-STS though an smtp_tls_policy_maps policy plugin, which Postfix supports MTA-STS through an smtp_tls_policy_maps policy plugin, which
replies with a TLS security level and name=value attributes with certificate replies with a TLS security level and name=value attributes with certificate
matching requirements. Postfix 3.10 and later extend the policy plugin response matching requirements. Postfix 3.10 and later extend the policy plugin response
with additional name=value attributes that are needed for TLSRPT. with additional name=value attributes that are needed for TLSRPT.

View File

@ -102,6 +102,17 @@ default setting respectful_logging=no</a> </p>
</ul> </ul>
<p> Logged with <a href="postconf.5.html#compatibility_level">compatibility_level</a> &lt; 3.11: </p>
<ul>
<li> <p> <a href="#tlsrpt_reused"> using backwards-compatible default
setting smtp_tlsrpt_skip_reused_handshakes=yes</a> </p>
</ul>
<p>
<p> If such a message is logged in the context of a legitimate <p> If such a message is logged in the context of a legitimate
request, the system administrator should make the backwards-compatible request, the system administrator should make the backwards-compatible
setting permanent in <a href="postconf.5.html">main.cf</a> or <a href="master.5.html">master.cf</a>, as detailed in the setting permanent in <a href="postconf.5.html">main.cf</a> or <a href="master.5.html">master.cf</a>, as detailed in the
@ -120,7 +131,8 @@ to "no". This could result in unexpected non-delivery of email after
Postfix is updated from an older version. The backwards-compatibility Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p> safety net is designed to prevent such surprises. </p>
<p> As long as the <a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a> parameter is left at <p> As long as the <a href="postconf.5.html#append_dot_mydomain">append_dot_mydomain</a> parameter is left unspecified
at
its implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is its implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is
less than 1, Postfix may log one of the following messages:</p> less than 1, Postfix may log one of the following messages:</p>
@ -178,7 +190,7 @@ after updating Postfix from an older version. The backwards-compatibility
safety net is designed allow the administrator to choose if they safety net is designed allow the administrator to choose if they
want to keep the old behavior. </p> want to keep the old behavior. </p>
<p> As long as a <a href="master.5.html">master.cf</a> chroot field is left at its <p> As long as a <a href="master.5.html">master.cf</a> chroot field is left unspecified at its
implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting
is less than 1, Postfix may log the following message while it is less than 1, Postfix may log the following message while it
reads the <a href="master.5.html">master.cf</a> file: </p> reads the <a href="master.5.html">master.cf</a> file: </p>
@ -218,7 +230,8 @@ from an older Postfix version. The backwards-compatibility safety
net is designed to prevent such surprises. </p> net is designed to prevent such surprises. </p>
<p> When the <a href="postconf.5.html#compatibility_level">compatibility_level</a> less than 1, and the <p> When the <a href="postconf.5.html#compatibility_level">compatibility_level</a> less than 1, and the
<a href="postconf.5.html#smtpd_relay_restrictions">smtpd_relay_restrictions</a> parameter is left at its implicit default <a href="postconf.5.html#smtpd_relay_restrictions">smtpd_relay_restrictions</a> parameter is left unspecified at its
implicit default
setting, Postfix may log the following message: </p> setting, Postfix may log the following message: </p>
<blockquote> <blockquote>
@ -250,7 +263,8 @@ addresses from clients that don't request SMTPUTF8 support, after
Postfix is updated from an older version. The backwards-compatibility Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p> safety net is designed to prevent such surprises. </p>
<p> As long as the <a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> parameter is left at its implicit <p> As long as the <a href="postconf.5.html#smtputf8_enable">smtputf8_enable</a> parameter is left unspecified
at its implicit
default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is
less than 1, Postfix logs a warning each time an SMTP command uses a less than 1, Postfix logs a warning each time an SMTP command uses a
non-ASCII address localpart without requesting SMTPUTF8 support: </p> non-ASCII address localpart without requesting SMTPUTF8 support: </p>
@ -293,7 +307,8 @@ Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p> safety net is designed to prevent such surprises. </p>
<p> As long as the <a href="postconf.5.html#mynetworks">mynetworks</a> and <a href="postconf.5.html#mynetworks_style">mynetworks_style</a> parameters are <p> As long as the <a href="postconf.5.html#mynetworks">mynetworks</a> and <a href="postconf.5.html#mynetworks_style">mynetworks_style</a> parameters are
left at their implicit default values, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> left unspecified at their implicit default values, and the
<a href="postconf.5.html#compatibility_level">compatibility_level</a>
setting is less than 2, the Postfix SMTP server may log one of the setting is less than 2, the Postfix SMTP server may log one of the
following messages: </p> following messages: </p>
@ -333,7 +348,8 @@ denied' errors or ETRN errors after Postfix is updated from an older
version. The backwards-compatibility safety net is designed to version. The backwards-compatibility safety net is designed to
prevent such surprises. </p> prevent such surprises. </p>
<p> As long as the <a href="postconf.5.html#relay_domains">relay_domains</a> parameter is left at its implicit <p> As long as the <a href="postconf.5.html#relay_domains">relay_domains</a> parameter is left unspecified at
its implicit
default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than 2, default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than 2,
Postfix may log one of the following messages. </p> Postfix may log one of the following messages. </p>
@ -408,7 +424,8 @@ secure digest of the client certificate. </p>
with the "sha256" digests of the expected client certificate or public with the "sha256" digests of the expected client certificate or public
key. </p> key. </p>
<p> As long as the <a href="postconf.5.html#smtpd_tls_fingerprint_digest">smtpd_tls_fingerprint_digest</a> parameter is left at its <p> As long as the <a href="postconf.5.html#smtpd_tls_fingerprint_digest">smtpd_tls_fingerprint_digest</a> parameter is left
unspecified at its
implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than
3.6, Postfix logs a warning each time a client certificate or public key 3.6, Postfix logs a warning each time a client certificate or public key
fingerprint is (potentially) used for access control: </p> fingerprint is (potentially) used for access control: </p>
@ -455,7 +472,8 @@ policies in the TLS policy table to specify matching "sha256" digests of
the expected server certificates or public keys. </p> the expected server certificates or public keys. </p>
<p> As long as the <a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> (or LMTP equivalent) <p> As long as the <a href="postconf.5.html#smtp_tls_fingerprint_digest">smtp_tls_fingerprint_digest</a> (or LMTP equivalent)
parameter is left at its implicit default value, and the parameter is left unspecified at its implicit default value, and
the
<a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than 3.6, Postfix logs a warning each <a href="postconf.5.html#compatibility_level">compatibility_level</a> setting is less than 3.6, Postfix logs a warning each
time the "fingerprint" security level is used to specify matching "md5" time the "fingerprint" security level is used to specify matching "md5"
digests of trusted server certificates or public keys: </p> digests of trusted server certificates or public keys: </p>
@ -499,7 +517,8 @@ command, and both support the same features. </p> </blockquote>
keep evaluating <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> before keep evaluating <a href="postconf.5.html#smtpd_recipient_restrictions">smtpd_recipient_restrictions</a> before
<a href="postconf.5.html#smtpd_relay_restrictions">smtpd_relay_restrictions</a>, as long as the <a href="postconf.5.html#compatibility_level">compatibility_level</a> is <a href="postconf.5.html#smtpd_relay_restrictions">smtpd_relay_restrictions</a>, as long as the <a href="postconf.5.html#compatibility_level">compatibility_level</a> is
less than 3.6, and the <a href="postconf.5.html#smtpd_relay_before_recipient_restrictions">smtpd_relay_before_recipient_restrictions</a> less than 3.6, and the <a href="postconf.5.html#smtpd_relay_before_recipient_restrictions">smtpd_relay_before_recipient_restrictions</a>
parameter is left at its implicit default setting. As a reminder, parameter is left unspecified at its implicit default setting. As
a reminder,
Postfix may log the following message: </p> Postfix may log the following message: </p>
<blockquote> <blockquote>
@ -533,7 +552,8 @@ the changes in logging could affect logfile analysis tools. </p>
<p> To avoid breaking existing logfile analysis tools, Postfix will keep <p> To avoid breaking existing logfile analysis tools, Postfix will keep
logging the deprecated form, as long as the <a href="postconf.5.html#respectful_logging">respectful_logging</a> parameter logging the deprecated form, as long as the <a href="postconf.5.html#respectful_logging">respectful_logging</a> parameter
is left at its implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a> is left unspecified at its implicit default value, and the
<a href="postconf.5.html#compatibility_level">compatibility_level</a>
setting is less than 3.6. As a reminder, Postfix may log the following setting is less than 3.6. As a reminder, Postfix may log the following
when a remote SMTP client is allowlisted or denylisted: </p> when a remote SMTP client is allowlisted or denylisted: </p>
@ -555,6 +575,38 @@ system administrator should make the backwards-compatible setting
</pre> </pre>
</blockquote> </blockquote>
<h2> <a name="tlsrpt_reused"> Using backwards-compatible
default setting smtp_tlsrpt_skip_reused_handshakes=yes</a> </h2>
<p> Postfix version 3.11 changes the default value for
<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> 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. </p>
<p> As long as the <a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> parameter is
left unspecified at its implicit default value, and the <a href="postconf.5.html#compatibility_level">compatibility_level</a>
setting is less than 3.11, Postfix will log a reminder that it is
using the backwards-compatible default: </p>
<blockquote>
<pre>
postfix/smtp[388157] using backwards-compatible default setting
<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a>=yes
</pre>
</blockquote>
<p> To keep the old default setting, the system administrator should
make the backwards-compatible setting "<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a>
= yes" permanent in <a href="postconf.5.html">main.cf</a>:
<blockquote>
<pre>
# <b>postconf <a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a>=yes</b>
# <b>postfix reload</b>
</pre>
</blockquote>
<h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2> <h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2>
<p> Backwards compatibility is turned off by updating the <p> Backwards compatibility is turned off by updating the

View File

@ -375,7 +375,7 @@ Firefox and Chrome web browsers. Specify "<a href="postconf.5.html#enable_idna20
= yes" to get the historical behavior. </p> = yes" to get the historical behavior. </p>
<p> This affects the conversion of domain names that contain for <p> This affects the conversion of domain names that contain for
example the German sz (ß) and the Greek zeta (ς). See example the German sz (ß) and the Greek (final) sigma (ς). See
<a href="https://unicode.org/cldr/utility/idna.jsp">https://unicode.org/cldr/utility/idna.jsp</a> for more examples. </p> <a href="https://unicode.org/cldr/utility/idna.jsp">https://unicode.org/cldr/utility/idna.jsp</a> for more examples. </p>
<h2> <a name="credits">Credits</a> </h2> <h2> <a name="credits">Credits</a> </h2>

View File

@ -286,12 +286,12 @@ Untrusted <b>TLS connection reused</b> to mail.example.com[ipaddr]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
</pre> </pre>
<li> <p> By default, Postfix does not report the TLSRPT status for <li> <p> With TLSRPT enabled, the Postfix SMTP client reports the
a TLS handshake that reuses a previously-negotiated TLS session TLSRPT status for all TLS handshakes (the default as of Postfix
(there would be no new information to report). Specify 3.11). Specify "<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> = yes" (the
"<a href="postconf.5.html#smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> = no" to report the TLSRPT default with Postfix 3.10) to skip reporting TLS handshakes that
status for all TLS handshakes. This may be useful for troubleshooting. reuse a previously-negotiated TLS session as there would be no new
</p> information to report. </p>
<li> <p> Postfix logging for certificate verification failures may <li> <p> Postfix logging for certificate verification failures may
differ between new or reused TLS sessions. </p> differ between new or reused TLS sessions. </p>
@ -373,7 +373,7 @@ generator's sender address): </p>
<h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps <h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps
</a></h2> </a></h2>
<p> Postfix supports MTA-STS though an <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> policy <p> Postfix supports MTA-STS through an <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a> policy
plugin, which replies with a TLS security level and name=value plugin, which replies with a TLS security level and name=value
attributes with certificate matching requirements. Postfix 3.10 and attributes with certificate matching requirements. Postfix 3.10 and
later extend the policy plugin response with additional name=value later extend the policy plugin response with additional name=value

View File

@ -56,24 +56,25 @@ LMDB_TABLE(5) LMDB_TABLE(5)
<b><a name="synchronization">SYNCHRONIZATION</a></b> <b><a name="synchronization">SYNCHRONIZATION</a></b>
The Postfix LMDB adapter does not use LMDB's built-in locking scheme, The Postfix LMDB adapter does not use LMDB's built-in locking scheme,
because that would require world-writable lockfiles and would violate because that would require world-writable lockfiles and therefore vio-
the Postfix security model. Instead, Postfix uses fcntl(2) locks with late the Postfix security model. Instead, Postfix uses fcntl(2) locks
whole-file granularity. Programs that use LMDB's built-in locking pro- with whole-file granularity. Programs that use LMDB's built-in locking
tocol will corrupt a Postfix LMDB database or will read garbage. protocol will corrupt a Postfix LMDB database or will read garbage.
Every Postfix LMDB database read or write transaction must be protected Every Postfix LMDB database read or write transaction must be protected
from start to end with a shared or exclusive fcntl(2) lock. A writer from start to end with a shared or exclusive fcntl(2) lock. A process
may atomically downgrade an exclusive lock to a shared lock, but it may atomically downgrade an exclusive lock to a shared lock before
must hold an exclusive lock while opening another write transaction. opening a database read transaction, but it must hold an exclusive lock
while opening a write transaction.
Note that fcntl(2) locks do not protect transactions within the same Note that fcntl(2) locks do not protect transactions within the same
process against each other. If a program cannot avoid making simulta- process against each other. If a program cannot avoid making simulta-
neous database requests, then it must protect its transactions with neous database requests, then it must protect its transactions with
in-process locks, in addition to the per-process fcntl(2) locks. in-process locks, in addition to the per-process fcntl(2) locks.
<b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b> <b><a name="configuration_parameters">CONFIGURATION PARAMETERS</a></b>
Short-lived programs automatically pick up changes to <a href="postconf.5.html">main.cf</a>. With Short-lived programs automatically pick up changes to <a href="postconf.5.html">main.cf</a>. With
long-running daemon programs, Use the command "<b>postfix reload</b>" after a long-running daemon programs, Use the command "<b>postfix reload</b>" after a
configuration change. configuration change.
<b><a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> (16777216)</b> <b><a href="postconf.5.html#lmdb_map_size">lmdb_map_size</a> (16777216)</b>

View File

@ -99,18 +99,30 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5)
time. Smaller values are relative to the time of the update. time. Smaller values are relative to the time of the update.
<b><a name="memcache_key_parameters">MEMCACHE KEY PARAMETERS</a></b> <b><a name="memcache_key_parameters">MEMCACHE KEY PARAMETERS</a></b>
<b>key_digest (default: empty)</b>
After processing the <b>key_format</b> setting, and before sending a
request to the memcache server, run the key through the named
message digest algorithm and convert the result to lowercase
hexadecimal characters. This prevents a database access error
when keys may exceed the memcache server's key length limit
(usually, 250 bytes). Specify the name of a message digest algo-
rithm that is supported by OpenSSL, for example, <b>sha256</b>.
This feature is available in Postfix 3.11 and later, and
requires that Postfix is built with TLS support.
<b>key_format (default: %s)</b> <b>key_format (default: %s)</b>
Format of the lookup and update keys that the Postfix memcache Format of the lookup and update keys that the Postfix memcache
client sends to the memcache server. By default, these are the client sends to the memcache server. By default, these are the
same as the lookup and update keys that the memcache client same as the lookup and update keys that the memcache client
receives from Postfix applications. receives from Postfix applications.
NOTE 1: The <b>key_format</b> feature is not used for <b>backup</b> database NOTE 1: The <b>key_format</b> feature is not used for <b>backup</b> database
requests. requests.
NOTE 2: When multiple tables share the same memcache database, NOTE 2: When multiple tables share the same memcache database,
each table should prepend its own unique string to the lookup each table should prepend its own unique string to the lookup
key. Otherwise, automatic <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache key. Otherwise, automatic <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache
cleanup may not work. cleanup may not work.
Examples: Examples:
@ -126,37 +138,37 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5)
<b>%s</b> This is replaced by the memcache client input key. <b>%s</b> This is replaced by the memcache client input key.
<b>%u</b> When the input key is an address of the form user@domain, <b>%u</b> When the input key is an address of the form user@domain,
<b>%u</b> is replaced by the SQL quoted local part of the <b>%u</b> is replaced by the SQL quoted local part of the
address. Otherwise, <b>%u</b> is replaced by the entire search address. Otherwise, <b>%u</b> is replaced by the entire search
string. If the localpart is empty, a lookup is silently string. If the localpart is empty, a lookup is silently
suppressed and returns no results (an update is skipped suppressed and returns no results (an update is skipped
with a warning). with a warning).
<b>%d</b> When the input key is an address of the form user@domain, <b>%d</b> When the input key is an address of the form user@domain,
<b>%d</b> is replaced by the domain part of the address. Other- <b>%d</b> is replaced by the domain part of the address. Other-
wise, a lookup is silently suppressed and returns no wise, a lookup is silently suppressed and returns no
results (an update is skipped with a warning). results (an update is skipped with a warning).
<b>%[SUD]</b> The upper-case equivalents of the above expansions behave <b>%[SUD]</b> The upper-case equivalents of the above expansions behave
in the <b>key_format</b> parameter identically to their in the <b>key_format</b> parameter identically to their
lower-case counter-parts. lower-case counter-parts.
<b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced by the corre- <b>%[1-9]</b> The patterns %1, %2, ... %9 are replaced by the corre-
sponding most significant component of the input key's sponding most significant component of the input key's
domain. If the input key is <i>user@mail.example.com</i>, then domain. If the input key is <i>user@mail.example.com</i>, then
%1 is <b>com</b>, %2 is <b>example</b> and %3 is <b>mail</b>. If the input key %1 is <b>com</b>, %2 is <b>example</b> and %3 is <b>mail</b>. If the input key
is unqualified or does not have enough domain components is unqualified or does not have enough domain components
to satisfy all the specified patterns, a lookup is to satisfy all the specified patterns, a lookup is
silently suppressed and returns no results (an update is silently suppressed and returns no results (an update is
skipped with a warning). skipped with a warning).
<b>domain (default: no domain list)</b> <b>domain (default: no domain list)</b>
This feature can significantly reduce database server load. This feature can significantly reduce database server load.
Specify a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>" Specify a list of domain names, paths to files, or "<a href="DATABASE_README.html">type:table</a>"
databases. When specified, only fully qualified search keys databases. When specified, only fully qualified search keys
with a *non-empty* localpart and a matching domain are eligible with a *non-empty* localpart and a matching domain are eligible
for lookup or update: bare 'user' lookups, bare domain lookups for lookup or update: bare 'user' lookups, bare domain lookups
and "@domain" lookups are silently skipped (updates are skipped and "@domain" lookups are silently skipped (updates are skipped
with a warning). Example: with a warning). Example:
domain = example.com, <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/searchdomains domain = example.com, <a href="DATABASE_README.html#types">hash</a>:/etc/postfix/searchdomains
@ -169,30 +181,30 @@ MEMCACHE_TABLE(5) MEMCACHE_TABLE(5)
The maximal memcache reply line length in bytes. The maximal memcache reply line length in bytes.
<b>max_try (default: 2)</b> <b>max_try (default: 2)</b>
The number of times to try a memcache command before giving up. The number of times to try a memcache command before giving up.
The memcache client does not retry a command when the memcache The memcache client does not retry a command when the memcache
server accepts no connection. server accepts no connection.
<b>retry_pause (default: 1)</b> <b>retry_pause (default: 1)</b>
The time in seconds before retrying a failed memcache command. The time in seconds before retrying a failed memcache command.
<b>timeout (default: 2)</b> <b>timeout (default: 2)</b>
The time limit for sending a memcache command and for receiving The time limit for sending a memcache command and for receiving
a memcache reply. a memcache reply.
<b><a name="bugs">BUGS</a></b> <b><a name="bugs">BUGS</a></b>
The Postfix memcache client cannot be used for security-sensitive The Postfix memcache client cannot be used for security-sensitive
tables such as <b><a href="postconf.5.html#alias_maps">alias_maps</a></b> (these may contain "<i>|command</i> and "<i>/file/name</i>" tables such as <b><a href="postconf.5.html#alias_maps">alias_maps</a></b> (these may contain "<i>|command</i> and "<i>/file/name</i>"
destinations), or <b><a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a></b>, <b><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a></b> and <b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mail</a>-</b> destinations), or <b><a href="postconf.5.html#virtual_uid_maps">virtual_uid_maps</a></b>, <b><a href="postconf.5.html#virtual_gid_maps">virtual_gid_maps</a></b> and <b><a href="postconf.5.html#virtual_mailbox_maps">virtual_mail</a>-</b>
<b><a href="postconf.5.html#virtual_mailbox_maps">box_maps</a></b> (these specify UNIX process privileges or "<i>/file/name</i>" desti- <b><a href="postconf.5.html#virtual_mailbox_maps">box_maps</a></b> (these specify UNIX process privileges for "<i>/file/name</i>" desti-
nations). In a typical deployment a memcache database is writable by nations). In a typical deployment a memcache database is writable by
any process that can talk to the memcache server; in contrast, secu- any process that can talk to the memcache server; in contrast, secu-
rity-sensitive tables must never be writable by the unprivileged Post- rity-sensitive tables must never be writable by the unprivileged Post-
fix user. fix user.
The Postfix memcache client requires additional configuration when used The Postfix memcache client requires additional configuration when used
as <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache. For details see the <b>backup</b> and as <a href="postscreen.8.html"><b>postscreen</b>(8)</a> or <a href="verify.8.html"><b>verify</b>(8)</a> cache. For details see the <b>backup</b> and
<b>ttl</b> parameter discussions in the MEMCACHE MAIN PARAMETERS section <b>ttl</b> parameter discussions in the MEMCACHE MAIN PARAMETERS section
above. above.
<b><a name="see_also">SEE ALSO</a></b> <b><a name="see_also">SEE ALSO</a></b>

View File

@ -61,16 +61,15 @@ MYSQL_TABLE(5) MYSQL_TABLE(5)
TCP you have to specify TCP you have to specify
hosts = 127.0.0.1 hosts = 127.0.0.1
NOTE: if the <b>hosts</b> setting specifies one server, this client NOTE: if the <b>hosts</b> setting specifies only one server, this
assumes that the target is a load balancer and will reconnect client assumes that the target is a load balancer and will
immediately after a single failure, instead of failing all reconnect immediately after a single failure. With Postfix ver-
requests temporarily. With older versions of this client, spec- sions 3.9 and earlier, specify the same server twice.
ify the same server twice.
<b>user</b> <b>user</b>
<b>password</b> <b>password</b>
The user name and password to log into the mysql server. Exam- The user name and password to log into the mysql server. Exam-
ple: ple:
user = someone user = someone
password = some_password password = some_password
@ -79,15 +78,15 @@ MYSQL_TABLE(5) MYSQL_TABLE(5)
dbname = customer_database dbname = customer_database
<b>charset (default: utf8mb4)</b> <b>charset (default: utf8mb4)</b>
The default MySQL client character set; this also implies the The default MySQL client character set; this also implies the
collation order. collation order.
This parameter is available with Postfix 3.9 and later. With This parameter is available with Postfix 3.9 and later. With
earlier Postfix versions, the default was chosen by the MySQL earlier Postfix versions, the default was chosen by the MySQL
implementation (<b>utf8mb4</b> as of MySQL 8.0, <b>latin1</b> historically). implementation (<b>utf8mb4</b> as of MySQL 8.0, <b>latin1</b> historically).
<b>idle_interval (default: 60)</b> <b>idle_interval (default: 60)</b>
The number of seconds after which an idle database connection The number of seconds after which an idle database connection
will be closed. will be closed.
This feature is available in Postfix 3.9 and later. This feature is available in Postfix 3.9 and later.
@ -96,11 +95,10 @@ MYSQL_TABLE(5) MYSQL_TABLE(5)
The number of seconds that a database connection will be skipped The number of seconds that a database connection will be skipped
after an error. after an error.
NOTE: if the <b>hosts</b> setting specifies one server, this client NOTE: if the <b>hosts</b> setting specifies only one server, this
assumes that the target is a load balancer and will reconnect client assumes that the target is a load balancer and will
immediately after a single failure, instead of failing all reconnect immediately after a single failure. With Postfix ver-
requests temporarily. With older versions of this client, spec- sions 3.9 and earlier, specify the same server twice.
ify the same server twice.
This feature is available in Postfix 3.9 and later. This feature is available in Postfix 3.9 and later.

View File

@ -65,16 +65,15 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
URI, the Postfix PostgreSQL client will ignore the <b>dbname</b>, <b>user</b>, URI, the Postfix PostgreSQL client will ignore the <b>dbname</b>, <b>user</b>,
and <b>password</b> settings for that connection. and <b>password</b> settings for that connection.
NOTE: if the <b>hosts</b> setting specifies one server, this client NOTE: if the <b>hosts</b> setting specifies only one server, this
assumes that the target is a load balancer and will reconnect client assumes that the target is a load balancer and will
immediately after a single failure, instead of failing all reconnect immediately after a single failure. With Postfix ver-
requests temporarily. With older versions of this client, spec- sions 3.9 and earlier, specify the same server twice.
ify the same server twice.
<b>user</b> <b>user</b>
<b>password</b> <b>password</b>
The user name and password to log into the pgsql server. Exam- The user name and password to log into the pgsql server. Exam-
ple: ple:
user = someone user = someone
password = some_password password = some_password
@ -85,25 +84,25 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
<b>dbname</b> The database name on the servers. Example: <b>dbname</b> The database name on the servers. Example:
dbname = customer_database dbname = customer_database
The <b>dbname</b> setting is ignored for <b>hosts</b> connections that are The <b>dbname</b> setting is ignored for <b>hosts</b> connections that are
specified as an URI. specified as an URI.
The <b>dbname</b> setting is required with Postfix 3.10 and later, when The <b>dbname</b> setting is required with Postfix 3.10 and later, when
<b>hosts</b> specifies any non-URI connection; it is always required <b>hosts</b> specifies any non-URI connection; it is always required
with earlier Postfix versions. with earlier Postfix versions.
<b>encoding</b> <b>encoding</b>
The encoding used by the database client. The default setting The encoding used by the database client. The default setting
is: is:
encoding = UTF8 encoding = UTF8
Historically, the database client was hard coded to use LATIN1 Historically, the database client was hard coded to use LATIN1
in an attempt to disable multibyte character support. in an attempt to disable multibyte character support.
This feature is available in Postfix 3.8 and later. This feature is available in Postfix 3.8 and later.
<b>idle_interval (default: 60)</b> <b>idle_interval (default: 60)</b>
The number of seconds after which an idle database connection The number of seconds after which an idle database connection
will be closed. will be closed.
This feature is available in Postfix 3.9 and later. This feature is available in Postfix 3.9 and later.
@ -112,11 +111,10 @@ PGSQL_TABLE(5) PGSQL_TABLE(5)
The number of seconds that a database connection will be skipped The number of seconds that a database connection will be skipped
after an error. after an error.
NOTE: if the <b>hosts</b> setting specifies one server, this client NOTE: if the <b>hosts</b> setting specifies only one server, this
assumes that the target is a load balancer and will reconnect client assumes that the target is a load balancer and will
immediately after a single failure, instead of failing all reconnect immediately after a single failure. With Postfix ver-
requests temporarily. With older versions of this client, spec- sions 3.9 and earlier, specify the same server twice.
ify the same server twice.
This feature is available in Postfix 3.9 and later. This feature is available in Postfix 3.9 and later.

View File

@ -20,7 +20,7 @@ if (hash && isChrome) {
setTimeout(function() { setTimeout(function() {
window.location.hash = ""; window.location.hash = "";
window.location.hash = hash; window.location.hash = hash;
}, 1000); }, 1500);
} }
</script> </script>
@ -3349,7 +3349,7 @@ with older Postfix versions). </p>
when converting UTF-8 domain names to/from the ASCII form that is when converting UTF-8 domain names to/from the ASCII form that is
used for DNS lookups. Specify "yes" for compatibility with Postfix used for DNS lookups. Specify "yes" for compatibility with Postfix
&le; 3.1 (not recommended). This affects the conversion of domain &le; 3.1 (not recommended). This affects the conversion of domain
names that contain for example the German sz and the Greek zeta. names that contain for example the German sz and the Greek sigma.
See <a href="https://unicode.org/cldr/utility/idna.jsp">https://unicode.org/cldr/utility/idna.jsp</a> for more examples. See <a href="https://unicode.org/cldr/utility/idna.jsp">https://unicode.org/cldr/utility/idna.jsp</a> for more examples.
</p> </p>
@ -14870,13 +14870,11 @@ requirements for MTA-STS <a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls
</DD> </DD>
<DT><b><a name="smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a> <DT><b><a name="smtp_tlsrpt_skip_reused_handshakes">smtp_tlsrpt_skip_reused_handshakes</a>
(default: yes)</b></DT><DD> (default: Postfix &ge; 3.11: no, Postfix 3.10: yes)</b></DT><DD>
<p> Do not report the TLSRPT status for TLS protocol handshakes <p> When set to "yes", report the TLSRPT status only for "new" TLS
that reuse a previously-negotiated TLS session (there is no new sessions. When set to "no", also report the TLSRPT status for TLS
information to report). Report the TLSRPT status only for "new" TLS protocol handshakes that reuse a previously-negotiated TLS session.
sessions. Set this to "no" to log the TLSRPT status of all TLS
handshakes, for example to troubleshoot Postfix TLSRPT support.
</p> </p>
<p> Note: if an SMTP over TLS connection is reused, there is no <p> Note: if an SMTP over TLS connection is reused, there is no

View File

@ -72,16 +72,17 @@ postscreen(8) services.
.fi .fi
The Postfix LMDB adapter does not use LMDB's built\-in locking The Postfix LMDB adapter does not use LMDB's built\-in locking
scheme, because that would require world\-writable lockfiles scheme, because that would require world\-writable lockfiles
and would violate the Postfix security model. Instead, and therefore violate the Postfix security model. Instead,
Postfix uses fcntl(2) locks with whole\-file granularity. Postfix uses fcntl(2) locks with whole\-file granularity.
Programs that use LMDB's built\-in locking protocol will Programs that use LMDB's built\-in locking protocol will
corrupt a Postfix LMDB database or will read garbage. corrupt a Postfix LMDB database or will read garbage.
Every Postfix LMDB database read or write transaction must Every Postfix LMDB database read or write transaction must
be protected from start to end with a shared or exclusive be protected from start to end with a shared or exclusive
fcntl(2) lock. A writer may atomically downgrade an exclusive fcntl(2) lock. A process may atomically downgrade an exclusive
lock to a shared lock, but it must hold an exclusive lock lock to a shared lock before opening a database read transaction,
while opening another write transaction. but it must hold an exclusive lock while opening a write
transaction.
Note that fcntl(2) locks do not protect transactions within Note that fcntl(2) locks do not protect transactions within
the same process against each other. If a program cannot the same process against each other. If a program cannot

View File

@ -112,6 +112,17 @@ time. Smaller values are relative to the time of the update.
.nf .nf
.ad .ad
.fi .fi
.IP "\fBkey_digest (default: empty)\fB"
After processing the \fBkey_format\fR setting, and before sending
a request to the memcache server, run the key through the named
message digest algorithm and convert the result to lowercase
hexadecimal characters. This prevents a database access error
when keys may exceed the memcache server's key length limit
(usually, 250 bytes). Specify the name of a message digest
algorithm that is supported by OpenSSL, for example, \fBsha256\fR.
This feature is available in Postfix 3.11 and later, and requires
that Postfix is built with TLS support.
.IP "\fBkey_format (default: %s)\fB" .IP "\fBkey_format (default: %s)\fB"
Format of the lookup and update keys that the Postfix Format of the lookup and update keys that the Postfix
memcache client sends to the memcache server. memcache client sends to the memcache server.
@ -207,7 +218,7 @@ tables such as \fBalias_maps\fR (these may contain
"\fI|command\fR and "\fI/file/name\fR" destinations), or "\fI|command\fR and "\fI/file/name\fR" destinations), or
\fBvirtual_uid_maps\fR, \fBvirtual_gid_maps\fR and \fBvirtual_uid_maps\fR, \fBvirtual_gid_maps\fR and
\fBvirtual_mailbox_maps\fR (these specify UNIX process \fBvirtual_mailbox_maps\fR (these specify UNIX process
privileges or "\fI/file/name\fR" destinations). In a typical privileges for "\fI/file/name\fR" destinations). In a typical
deployment a memcache database is writable by any process deployment a memcache database is writable by any process
that can talk to the memcache server; in contrast, that can talk to the memcache server; in contrast,
security\-sensitive tables must never be writable by the security\-sensitive tables must never be writable by the

View File

@ -77,11 +77,10 @@ localhost over TCP you have to specify
hosts = 127.0.0.1 hosts = 127.0.0.1
.fi .fi
NOTE: if the \fBhosts\fR setting specifies one server, this client NOTE: if the \fBhosts\fR setting specifies only one server,
assumes that the target is a load balancer and will reconnect this client assumes that the target is a load balancer and
immediately after a single failure, instead of failing all will reconnect immediately after a single failure. With Postfix
requests temporarily. With older versions of this client, versions 3.9 and earlier, specify the same server twice.
specify the same server twice.
.IP "\fBuser\fR" .IP "\fBuser\fR"
.IP "\fBpassword\fR" .IP "\fBpassword\fR"
The user name and password to log into the mysql server. The user name and password to log into the mysql server.
@ -112,11 +111,10 @@ This feature is available in Postfix 3.9 and later.
The number of seconds that a database connection will be The number of seconds that a database connection will be
skipped after an error. skipped after an error.
NOTE: if the \fBhosts\fR setting specifies one server, this client NOTE: if the \fBhosts\fR setting specifies only one server,
assumes that the target is a load balancer and will reconnect this client assumes that the target is a load balancer and
immediately after a single failure, instead of failing all will reconnect immediately after a single failure. With Postfix
requests temporarily. With older versions of this client, versions 3.9 and earlier, specify the same server twice.
specify the same server twice.
This feature is available in Postfix 3.9 and later. This feature is available in Postfix 3.9 and later.
.IP "\fBquery\fR" .IP "\fBquery\fR"

View File

@ -81,11 +81,10 @@ NOTE: if the \fBhosts\fR setting specifies a PostgreSQL connection
URI, the Postfix PostgreSQL client will ignore the \fBdbname\fR, URI, the Postfix PostgreSQL client will ignore the \fBdbname\fR,
\fBuser\fR, and \fBpassword\fR settings for that connection. \fBuser\fR, and \fBpassword\fR settings for that connection.
NOTE: if the \fBhosts\fR setting specifies one server, this client NOTE: if the \fBhosts\fR setting specifies only one server,
assumes that the target is a load balancer and will reconnect this client assumes that the target is a load balancer and
immediately after a single failure, instead of failing all will reconnect immediately after a single failure. With Postfix
requests temporarily. With older versions of this client, versions 3.9 and earlier, specify the same server twice.
specify the same server twice.
.IP "\fBuser\fR" .IP "\fBuser\fR"
.IP "\fBpassword\fR" .IP "\fBpassword\fR"
The user name and password to log into the pgsql server. The user name and password to log into the pgsql server.
@ -129,11 +128,10 @@ This feature is available in Postfix 3.9 and later.
The number of seconds that a database connection will be The number of seconds that a database connection will be
skipped after an error. skipped after an error.
NOTE: if the \fBhosts\fR setting specifies one server, this client NOTE: if the \fBhosts\fR setting specifies only one server,
assumes that the target is a load balancer and will reconnect this client assumes that the target is a load balancer and
immediately after a single failure, instead of failing all will reconnect immediately after a single failure. With Postfix
requests temporarily. With older versions of this client, versions 3.9 and earlier, specify the same server twice.
specify the same server twice.
This feature is available in Postfix 3.9 and later. This feature is available in Postfix 3.9 and later.
.IP "\fBquery\fR" .IP "\fBquery\fR"

View File

@ -2079,7 +2079,7 @@ Enable 'transitional' compatibility between IDNA2003 and IDNA2008,
when converting UTF\-8 domain names to/from the ASCII form that is when converting UTF\-8 domain names to/from the ASCII form that is
used for DNS lookups. Specify "yes" for compatibility with Postfix used for DNS lookups. Specify "yes" for compatibility with Postfix
<= 3.1 (not recommended). This affects the conversion of domain <= 3.1 (not recommended). This affects the conversion of domain
names that contain for example the German sz and the Greek zeta. names that contain for example the German sz and the Greek sigma.
See https://unicode.org/cldr/utility/idna.jsp for more examples. See https://unicode.org/cldr/utility/idna.jsp for more examples.
.PP .PP
This feature is available in Postfix 3.2 and later. This feature is available in Postfix 3.2 and later.
@ -9921,12 +9921,10 @@ See TLSRPT_README for configuration examples and additional
requirements for MTA\-STS smtp_tls_policy_maps plugins. requirements for MTA\-STS smtp_tls_policy_maps plugins.
.PP .PP
This feature is available in Postfix >= 3.10. This feature is available in Postfix >= 3.10.
.SH smtp_tlsrpt_skip_reused_handshakes (default: yes) .SH smtp_tlsrpt_skip_reused_handshakes (default: Postfix >= 3.11: no, Postfix 3.10: yes)
Do not report the TLSRPT status for TLS protocol handshakes When set to "yes", report the TLSRPT status only for "new" TLS
that reuse a previously\-negotiated TLS session (there is no new sessions. When set to "no", also report the TLSRPT status for TLS
information to report). Report the TLSRPT status only for "new" TLS protocol handshakes that reuse a previously\-negotiated TLS session.
sessions. Set this to "no" to log the TLSRPT status of all TLS
handshakes, for example to troubleshoot Postfix TLSRPT support.
.PP .PP
Note: if an SMTP over TLS connection is reused, there is no Note: if an SMTP over TLS connection is reused, there is no
second etc. TLS handshake to report. second etc. TLS handshake to report.

View File

@ -102,6 +102,17 @@ default setting respectful_logging=no</a> </p>
</ul> </ul>
<p> Logged with compatibility_level &lt; 3.11: </p>
<ul>
<li> <p> <a href="#tlsrpt_reused"> using backwards-compatible default
setting smtp_tlsrpt_skip_reused_handshakes=yes</a> </p>
</ul>
<p>
<p> If such a message is logged in the context of a legitimate <p> If such a message is logged in the context of a legitimate
request, the system administrator should make the backwards-compatible request, the system administrator should make the backwards-compatible
setting permanent in main.cf or master.cf, as detailed in the setting permanent in main.cf or master.cf, as detailed in the
@ -120,7 +131,8 @@ to "no". This could result in unexpected non-delivery of email after
Postfix is updated from an older version. The backwards-compatibility Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p> safety net is designed to prevent such surprises. </p>
<p> As long as the append_dot_mydomain parameter is left at <p> As long as the append_dot_mydomain parameter is left unspecified
at
its implicit default value, and the compatibility_level setting is its implicit default value, and the compatibility_level setting is
less than 1, Postfix may log one of the following messages:</p> less than 1, Postfix may log one of the following messages:</p>
@ -178,7 +190,7 @@ after updating Postfix from an older version. The backwards-compatibility
safety net is designed allow the administrator to choose if they safety net is designed allow the administrator to choose if they
want to keep the old behavior. </p> want to keep the old behavior. </p>
<p> As long as a master.cf chroot field is left at its <p> As long as a master.cf chroot field is left unspecified at its
implicit default value, and the compatibility_level setting implicit default value, and the compatibility_level setting
is less than 1, Postfix may log the following message while it is less than 1, Postfix may log the following message while it
reads the master.cf file: </p> reads the master.cf file: </p>
@ -218,7 +230,8 @@ from an older Postfix version. The backwards-compatibility safety
net is designed to prevent such surprises. </p> net is designed to prevent such surprises. </p>
<p> When the compatibility_level less than 1, and the <p> When the compatibility_level less than 1, and the
smtpd_relay_restrictions parameter is left at its implicit default smtpd_relay_restrictions parameter is left unspecified at its
implicit default
setting, Postfix may log the following message: </p> setting, Postfix may log the following message: </p>
<blockquote> <blockquote>
@ -250,7 +263,8 @@ addresses from clients that don't request SMTPUTF8 support, after
Postfix is updated from an older version. The backwards-compatibility Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p> safety net is designed to prevent such surprises. </p>
<p> As long as the smtputf8_enable parameter is left at its implicit <p> As long as the smtputf8_enable parameter is left unspecified
at its implicit
default value, and the compatibility_level setting is default value, and the compatibility_level setting is
less than 1, Postfix logs a warning each time an SMTP command uses a less than 1, Postfix logs a warning each time an SMTP command uses a
non-ASCII address localpart without requesting SMTPUTF8 support: </p> non-ASCII address localpart without requesting SMTPUTF8 support: </p>
@ -293,7 +307,8 @@ Postfix is updated from an older version. The backwards-compatibility
safety net is designed to prevent such surprises. </p> safety net is designed to prevent such surprises. </p>
<p> As long as the mynetworks and mynetworks_style parameters are <p> As long as the mynetworks and mynetworks_style parameters are
left at their implicit default values, and the compatibility_level 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 setting is less than 2, the Postfix SMTP server may log one of the
following messages: </p> following messages: </p>
@ -333,7 +348,8 @@ denied' errors or ETRN errors after Postfix is updated from an older
version. The backwards-compatibility safety net is designed to version. The backwards-compatibility safety net is designed to
prevent such surprises. </p> prevent such surprises. </p>
<p> As long as the relay_domains parameter is left at its implicit <p> As long as the relay_domains parameter is left unspecified at
its implicit
default value, and the compatibility_level setting is less than 2, default value, and the compatibility_level setting is less than 2,
Postfix may log one of the following messages. </p> Postfix may log one of the following messages. </p>
@ -408,7 +424,8 @@ secure digest of the client certificate. </p>
with the "sha256" digests of the expected client certificate or public with the "sha256" digests of the expected client certificate or public
key. </p> key. </p>
<p> As long as the smtpd_tls_fingerprint_digest parameter is left at its <p> 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 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 3.6, Postfix logs a warning each time a client certificate or public key
fingerprint is (potentially) used for access control: </p> fingerprint is (potentially) used for access control: </p>
@ -455,7 +472,8 @@ policies in the TLS policy table to specify matching "sha256" digests of
the expected server certificates or public keys. </p> the expected server certificates or public keys. </p>
<p> As long as the smtp_tls_fingerprint_digest (or LMTP equivalent) <p> As long as the smtp_tls_fingerprint_digest (or LMTP equivalent)
parameter is left at its implicit default value, and the parameter is left unspecified at its implicit default value, and
the
compatibility_level setting is less than 3.6, Postfix logs a warning each compatibility_level setting is less than 3.6, Postfix logs a warning each
time the "fingerprint" security level is used to specify matching "md5" time the "fingerprint" security level is used to specify matching "md5"
digests of trusted server certificates or public keys: </p> digests of trusted server certificates or public keys: </p>
@ -499,7 +517,8 @@ command, and both support the same features. </p> </blockquote>
keep evaluating smtpd_recipient_restrictions before keep evaluating smtpd_recipient_restrictions before
smtpd_relay_restrictions, as long as the compatibility_level is smtpd_relay_restrictions, as long as the compatibility_level is
less than 3.6, and the smtpd_relay_before_recipient_restrictions less than 3.6, and the smtpd_relay_before_recipient_restrictions
parameter is left at its implicit default setting. As a reminder, parameter is left unspecified at its implicit default setting. As
a reminder,
Postfix may log the following message: </p> Postfix may log the following message: </p>
<blockquote> <blockquote>
@ -533,7 +552,8 @@ the changes in logging could affect logfile analysis tools. </p>
<p> To avoid breaking existing logfile analysis tools, Postfix will keep <p> To avoid breaking existing logfile analysis tools, Postfix will keep
logging the deprecated form, as long as the respectful_logging parameter logging the deprecated form, as long as the respectful_logging parameter
is left at its implicit default value, and the compatibility_level 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 setting is less than 3.6. As a reminder, Postfix may log the following
when a remote SMTP client is allowlisted or denylisted: </p> when a remote SMTP client is allowlisted or denylisted: </p>
@ -555,6 +575,38 @@ system administrator should make the backwards-compatible setting
</pre> </pre>
</blockquote> </blockquote>
<h2> <a name="tlsrpt_reused"> Using backwards-compatible
default setting smtp_tlsrpt_skip_reused_handshakes=yes</a> </h2>
<p> 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. </p>
<p> 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: </p>
<blockquote>
<pre>
postfix/smtp[388157] using backwards-compatible default setting
smtp_tlsrpt_skip_reused_handshakes=yes
</pre>
</blockquote>
<p> 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:
<blockquote>
<pre>
# <b>postconf smtp_tlsrpt_skip_reused_handshakes=yes</b>
# <b>postfix reload</b>
</pre>
</blockquote>
<h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2> <h2> <a name="turnoff">Turning off the backwards-compatibility safety net</a> </h2>
<p> Backwards compatibility is turned off by updating the <p> Backwards compatibility is turned off by updating the

View File

@ -375,7 +375,7 @@ Firefox and Chrome web browsers. Specify "enable_idna2003_compatibility
= yes" to get the historical behavior. </p> = yes" to get the historical behavior. </p>
<p> This affects the conversion of domain names that contain for <p> This affects the conversion of domain names that contain for
example the German sz (ß) and the Greek zeta (ς). See example the German sz (ß) and the Greek (final) sigma (ς). See
https://unicode.org/cldr/utility/idna.jsp for more examples. </p> https://unicode.org/cldr/utility/idna.jsp for more examples. </p>
<h2> <a name="credits">Credits</a> </h2> <h2> <a name="credits">Credits</a> </h2>

View File

@ -286,12 +286,12 @@ Untrusted <b>TLS connection reused</b> to mail.example.com[ipaddr]:25:
TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits) TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)
</pre> </pre>
<li> <p> By default, Postfix does not report the TLSRPT status for <li> <p> With TLSRPT enabled, the Postfix SMTP client reports the
a TLS handshake that reuses a previously-negotiated TLS session TLSRPT status for all TLS handshakes (the default as of Postfix
(there would be no new information to report). Specify 3.11). Specify "smtp_tlsrpt_skip_reused_handshakes = yes" (the
"smtp_tlsrpt_skip_reused_handshakes = no" to report the TLSRPT default with Postfix 3.10) to skip reporting TLS handshakes that
status for all TLS handshakes. This may be useful for troubleshooting. reuse a previously-negotiated TLS session as there would be no new
</p> information to report. </p>
<li> <p> Postfix logging for certificate verification failures may <li> <p> Postfix logging for certificate verification failures may
differ between new or reused TLS sessions. </p> differ between new or reused TLS sessions. </p>
@ -373,7 +373,7 @@ generator's sender address): </p>
<h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps <h2> <a name="mta-sts"> MTA-STS Support via smtp_tls_policy_maps
</a></h2> </a></h2>
<p> Postfix supports MTA-STS though an smtp_tls_policy_maps policy <p> Postfix supports MTA-STS through an smtp_tls_policy_maps policy
plugin, which replies with a TLS security level and name=value plugin, which replies with a TLS security level and name=value
attributes with certificate matching requirements. Postfix 3.10 and attributes with certificate matching requirements. Postfix 3.10 and
later extend the policy plugin response with additional name=value later extend the policy plugin response with additional name=value

View File

@ -60,16 +60,17 @@
# .fi # .fi
# The Postfix LMDB adapter does not use LMDB's built-in locking # The Postfix LMDB adapter does not use LMDB's built-in locking
# scheme, because that would require world-writable lockfiles # scheme, because that would require world-writable lockfiles
# and would violate the Postfix security model. Instead, # and therefore violate the Postfix security model. Instead,
# Postfix uses fcntl(2) locks with whole-file granularity. # Postfix uses fcntl(2) locks with whole-file granularity.
# Programs that use LMDB's built-in locking protocol will # Programs that use LMDB's built-in locking protocol will
# corrupt a Postfix LMDB database or will read garbage. # corrupt a Postfix LMDB database or will read garbage.
# #
# Every Postfix LMDB database read or write transaction must # Every Postfix LMDB database read or write transaction must
# be protected from start to end with a shared or exclusive # be protected from start to end with a shared or exclusive
# fcntl(2) lock. A writer may atomically downgrade an exclusive # fcntl(2) lock. A process may atomically downgrade an exclusive
# lock to a shared lock, but it must hold an exclusive lock # lock to a shared lock before opening a database read transaction,
# while opening another write transaction. # but it must hold an exclusive lock while opening a write
# transaction.
# #
# Note that fcntl(2) locks do not protect transactions within # Note that fcntl(2) locks do not protect transactions within
# the same process against each other. If a program cannot # the same process against each other. If a program cannot

View File

@ -102,6 +102,17 @@
# MEMCACHE KEY PARAMETERS # MEMCACHE KEY PARAMETERS
# .ad # .ad
# .fi # .fi
# .IP "\fBkey_digest (default: empty)\fB"
# After processing the \fBkey_format\fR setting, and before sending
# a request to the memcache server, run the key through the named
# message digest algorithm and convert the result to lowercase
# hexadecimal characters. This prevents a database access error
# when keys may exceed the memcache server's key length limit
# (usually, 250 bytes). Specify the name of a message digest
# algorithm that is supported by OpenSSL, for example, \fBsha256\fR.
#
# This feature is available in Postfix 3.11 and later, and requires
# that Postfix is built with TLS support.
# .IP "\fBkey_format (default: %s)\fB" # .IP "\fBkey_format (default: %s)\fB"
# Format of the lookup and update keys that the Postfix # Format of the lookup and update keys that the Postfix
# memcache client sends to the memcache server. # memcache client sends to the memcache server.
@ -193,7 +204,7 @@
# "\fI|command\fR and "\fI/file/name\fR" destinations), or # "\fI|command\fR and "\fI/file/name\fR" destinations), or
# \fBvirtual_uid_maps\fR, \fBvirtual_gid_maps\fR and # \fBvirtual_uid_maps\fR, \fBvirtual_gid_maps\fR and
# \fBvirtual_mailbox_maps\fR (these specify UNIX process # \fBvirtual_mailbox_maps\fR (these specify UNIX process
# privileges or "\fI/file/name\fR" destinations). In a typical # privileges for "\fI/file/name\fR" destinations). In a typical
# deployment a memcache database is writable by any process # deployment a memcache database is writable by any process
# that can talk to the memcache server; in contrast, # that can talk to the memcache server; in contrast,
# security-sensitive tables must never be writable by the # security-sensitive tables must never be writable by the

View File

@ -67,11 +67,10 @@
# hosts = 127.0.0.1 # hosts = 127.0.0.1
# .fi # .fi
# #
# NOTE: if the \fBhosts\fR setting specifies one server, this client # NOTE: if the \fBhosts\fR setting specifies only one server,
# assumes that the target is a load balancer and will reconnect # this client assumes that the target is a load balancer and
# immediately after a single failure, instead of failing all # will reconnect immediately after a single failure. With Postfix
# requests temporarily. With older versions of this client, # versions 3.9 and earlier, specify the same server twice.
# specify the same server twice.
# .IP "\fBuser\fR" # .IP "\fBuser\fR"
# .IP "\fBpassword\fR" # .IP "\fBpassword\fR"
# The user name and password to log into the mysql server. # The user name and password to log into the mysql server.
@ -102,11 +101,10 @@
# The number of seconds that a database connection will be # The number of seconds that a database connection will be
# skipped after an error. # skipped after an error.
# #
# NOTE: if the \fBhosts\fR setting specifies one server, this client # NOTE: if the \fBhosts\fR setting specifies only one server,
# assumes that the target is a load balancer and will reconnect # this client assumes that the target is a load balancer and
# immediately after a single failure, instead of failing all # will reconnect immediately after a single failure. With Postfix
# requests temporarily. With older versions of this client, # versions 3.9 and earlier, specify the same server twice.
# specify the same server twice.
# #
# This feature is available in Postfix 3.9 and later. # This feature is available in Postfix 3.9 and later.
# .IP "\fBquery\fR" # .IP "\fBquery\fR"

View File

@ -71,11 +71,10 @@
# URI, the Postfix PostgreSQL client will ignore the \fBdbname\fR, # URI, the Postfix PostgreSQL client will ignore the \fBdbname\fR,
# \fBuser\fR, and \fBpassword\fR settings for that connection. # \fBuser\fR, and \fBpassword\fR settings for that connection.
# #
# NOTE: if the \fBhosts\fR setting specifies one server, this client # NOTE: if the \fBhosts\fR setting specifies only one server,
# assumes that the target is a load balancer and will reconnect # this client assumes that the target is a load balancer and
# immediately after a single failure, instead of failing all # will reconnect immediately after a single failure. With Postfix
# requests temporarily. With older versions of this client, # versions 3.9 and earlier, specify the same server twice.
# specify the same server twice.
# .IP "\fBuser\fR" # .IP "\fBuser\fR"
# .IP "\fBpassword\fR" # .IP "\fBpassword\fR"
# The user name and password to log into the pgsql server. # The user name and password to log into the pgsql server.
@ -119,11 +118,10 @@
# The number of seconds that a database connection will be # The number of seconds that a database connection will be
# skipped after an error. # skipped after an error.
# #
# NOTE: if the \fBhosts\fR setting specifies one server, this client # NOTE: if the \fBhosts\fR setting specifies only one server,
# assumes that the target is a load balancer and will reconnect # this client assumes that the target is a load balancer and
# immediately after a single failure, instead of failing all # will reconnect immediately after a single failure. With Postfix
# requests temporarily. With older versions of this client, # versions 3.9 and earlier, specify the same server twice.
# specify the same server twice.
# #
# This feature is available in Postfix 3.9 and later. # This feature is available in Postfix 3.9 and later.
# .IP "\fBquery\fR" # .IP "\fBquery\fR"

View File

@ -20,7 +20,7 @@ if (hash && isChrome) {
setTimeout(function() { setTimeout(function() {
window.location.hash = ""; window.location.hash = "";
window.location.hash = hash; window.location.hash = hash;
}, 1000); }, 1500);
} }
</script> </script>

View File

@ -17765,7 +17765,7 @@ Milter support should be disabled. </p>
when converting UTF-8 domain names to/from the ASCII form that is when converting UTF-8 domain names to/from the ASCII form that is
used for DNS lookups. Specify "yes" for compatibility with Postfix used for DNS lookups. Specify "yes" for compatibility with Postfix
&le; 3.1 (not recommended). This affects the conversion of domain &le; 3.1 (not recommended). This affects the conversion of domain
names that contain for example the German sz and the Greek zeta. names that contain for example the German sz and the Greek sigma.
See https://unicode.org/cldr/utility/idna.jsp for more examples. See https://unicode.org/cldr/utility/idna.jsp for more examples.
</p> </p>
@ -19521,13 +19521,11 @@ requirements for MTA-STS smtp_tls_policy_maps plugins. </p>
<p> This feature is available in Postfix &ge; 3.10. </p> <p> This feature is available in Postfix &ge; 3.10. </p>
%PARAM smtp_tlsrpt_skip_reused_handshakes yes %PARAM smtp_tlsrpt_skip_reused_handshakes Postfix &ge; 3.11: no, Postfix 3.10: yes
<p> Do not report the TLSRPT status for TLS protocol handshakes <p> When set to "yes", report the TLSRPT status only for "new" TLS
that reuse a previously-negotiated TLS session (there is no new sessions. When set to "no", also report the TLSRPT status for TLS
information to report). Report the TLSRPT status only for "new" TLS protocol handshakes that reuse a previously-negotiated TLS session.
sessions. Set this to "no" to log the TLSRPT status of all TLS
handshakes, for example to troubleshoot Postfix TLSRPT support.
</p> </p>
<p> Note: if an SMTP over TLS connection is reused, there is no <p> Note: if an SMTP over TLS connection is reused, there is no

View File

@ -1674,3 +1674,11 @@ MLKEM
cleartext cleartext
redacted redacted
subclassed subclassed
nosleep
preload
memcached
Geert
Hendrickx
typofix
LD
PRELOAD

View File

@ -343,3 +343,4 @@ additional_info additional_info
ignored ignored ignored ignored
USE_TLSRPT USE_TLSRPT USE_TLSRPT USE_TLSRPT
encoded encoded text can contain only alpha digit encoded encoded text can contain only alpha digit
ossl_digest_new ossl_digest_new returns NULL after error ossl_digest_data

View File

@ -166,3 +166,8 @@ proto proto socketmap_table
global mail_params h smtpd smtpd c global mail_params h smtpd smtpd c
global mail_params h proto postconf proto smtp smtp c global mail_params h proto postconf proto smtp smtp c
proto postconf proto proto TLS_README html proto postconf proto proto TLS_README html
the command line Files postmap postmap c postalias postalias c
verification in progress File verify verify c
+ address failed File verify verify c
address failed File verify verify c
address failed due to a database error File verify verify c

View File

@ -1860,3 +1860,7 @@ XXXSENDOPTS
xtra xtra
HAPROXY HAPROXY
SRVR SRVR
DGST
DIGEST
OSSL
ossl

View File

@ -1223,10 +1223,12 @@ dict_memcache.o: ../../include/argv.h
dict_memcache.o: ../../include/auto_clnt.h dict_memcache.o: ../../include/auto_clnt.h
dict_memcache.o: ../../include/check_arg.h dict_memcache.o: ../../include/check_arg.h
dict_memcache.o: ../../include/dict.h dict_memcache.o: ../../include/dict.h
dict_memcache.o: ../../include/hex_code.h
dict_memcache.o: ../../include/match_list.h dict_memcache.o: ../../include/match_list.h
dict_memcache.o: ../../include/msg.h dict_memcache.o: ../../include/msg.h
dict_memcache.o: ../../include/myflock.h dict_memcache.o: ../../include/myflock.h
dict_memcache.o: ../../include/mymalloc.h dict_memcache.o: ../../include/mymalloc.h
dict_memcache.o: ../../include/ossl_digest.h
dict_memcache.o: ../../include/stringops.h dict_memcache.o: ../../include/stringops.h
dict_memcache.o: ../../include/sys_defs.h dict_memcache.o: ../../include/sys_defs.h
dict_memcache.o: ../../include/vbuf.h dict_memcache.o: ../../include/vbuf.h

View File

@ -50,9 +50,11 @@
/* Utility library. */ /* Utility library. */
#include <hex_code.h>
#include <msg.h> #include <msg.h>
#include <mymalloc.h> #include <mymalloc.h>
#include <dict.h> #include <dict.h>
#include <ossl_digest.h>
#include <vstring.h> #include <vstring.h>
#include <stringops.h> #include <stringops.h>
#include <auto_clnt.h> #include <auto_clnt.h>
@ -75,6 +77,9 @@ typedef struct {
DICT dict; /* parent class */ DICT dict; /* parent class */
CFG_PARSER *parser; /* common parameter parser */ CFG_PARSER *parser; /* common parameter parser */
void *dbc_ctxt; /* db_common context */ void *dbc_ctxt; /* db_common context */
char *key_digest; /* digest the query key */
OSSL_DGST *key_dgst_eng; /* digest engine */
VSTRING *key_dgst_out; /* digest result */
char *key_format; /* query key translation */ char *key_format; /* query key translation */
int timeout; /* client timeout */ int timeout; /* client timeout */
int mc_ttl; /* memcache update expiration */ int mc_ttl; /* memcache update expiration */
@ -99,6 +104,7 @@ typedef struct {
#define DICT_MC_DEF_PORT "11211" #define DICT_MC_DEF_PORT "11211"
#define DICT_MC_DEF_MEMCACHE "inet:" DICT_MC_DEF_HOST ":" DICT_MC_DEF_PORT #define DICT_MC_DEF_MEMCACHE "inet:" DICT_MC_DEF_HOST ":" DICT_MC_DEF_PORT
#define DICT_MC_DEF_KEY_FMT "%s" #define DICT_MC_DEF_KEY_FMT "%s"
#define DICT_MC_DEF_KEY_DGST ""
#define DICT_MC_DEF_MC_TTL 3600 #define DICT_MC_DEF_MC_TTL 3600
#define DICT_MC_DEF_MC_TIMEOUT 2 #define DICT_MC_DEF_MC_TIMEOUT 2
#define DICT_MC_DEF_MC_FLAGS 0 #define DICT_MC_DEF_MC_FLAGS 0
@ -109,6 +115,7 @@ typedef struct {
#define DICT_MC_NAME_MEMCACHE "memcache" #define DICT_MC_NAME_MEMCACHE "memcache"
#define DICT_MC_NAME_BACKUP "backup" #define DICT_MC_NAME_BACKUP "backup"
#define DICT_MC_NAME_KEY_DGST "key_digest"
#define DICT_MC_NAME_KEY_FMT "key_format" #define DICT_MC_NAME_KEY_FMT "key_format"
#define DICT_MC_NAME_MC_TTL "ttl" #define DICT_MC_NAME_MC_TTL "ttl"
#define DICT_MC_NAME_MC_TIMEOUT "timeout" #define DICT_MC_NAME_MC_TIMEOUT "timeout"
@ -163,7 +170,7 @@ static int dict_memcache_set(DICT_MC *dict_mc, const char *value, int ttl)
DICT_TYPE_MEMCACHE, dict_mc->dict.name); DICT_TYPE_MEMCACHE, dict_mc->dict.name);
} else if (strcmp(STR(dict_mc->clnt_buf), "STORED") != 0) { } else if (strcmp(STR(dict_mc->clnt_buf), "STORED") != 0) {
if (count > 0) if (count > 0)
msg_warn("database %s:%s: update failed: %.30s", msg_warn("database %s:%s: update failed: %.100s",
DICT_TYPE_MEMCACHE, dict_mc->dict.name, DICT_TYPE_MEMCACHE, dict_mc->dict.name,
STR(dict_mc->clnt_buf)); STR(dict_mc->clnt_buf));
} else { } else {
@ -285,6 +292,18 @@ static ssize_t dict_memcache_prepare_key(DICT_MC *dict_mc, const char *name)
} else { } else {
vstring_strcpy(dict_mc->key_buf, name); vstring_strcpy(dict_mc->key_buf, name);
} }
if (dict_mc->key_dgst_eng) {
if (ossl_digest_data(dict_mc->key_dgst_eng, STR(dict_mc->key_buf),
LEN(dict_mc->key_buf), dict_mc->key_dgst_out) < 0) {
ossl_digest_log_errors(msg_warn);
msg_warn("%s:%s: %s message digest failed",
DICT_TYPE_MEMCACHE, dict_mc->dict.name,
dict_mc->key_digest);
return (-1);
}
hex_encode_opt(dict_mc->key_buf, STR(dict_mc->key_dgst_out),
LEN(dict_mc->key_dgst_out), HEX_ENCODE_FLAG_LOWERCASE);
}
/* /*
* The length indicates whether the expansion is empty or not. * The length indicates whether the expansion is empty or not.
@ -315,8 +334,10 @@ static int dict_memcache_valid_key(DICT_MC *dict_mc,
DICT_MC_SKIP("domain mismatch"); DICT_MC_SKIP("domain mismatch");
if (rc < 0) if (rc < 0)
DICT_ERR_VAL_RETURN(dict_mc, rc, 0); DICT_ERR_VAL_RETURN(dict_mc, rc, 0);
if (dict_memcache_prepare_key(dict_mc, name) == 0) if ((rc = dict_memcache_prepare_key(dict_mc, name)) == 0)
DICT_MC_SKIP("empty lookup key expansion"); DICT_MC_SKIP("empty lookup key expansion");
if (rc < 0)
DICT_ERR_VAL_RETURN(dict_mc, rc, 0);
for (cp = (unsigned char *) STR(dict_mc->key_buf); *cp; cp++) for (cp = (unsigned char *) STR(dict_mc->key_buf); *cp; cp++)
if (isascii(*cp) && isspace(*cp)) if (isascii(*cp) && isspace(*cp))
DICT_MC_SKIP("name contains space"); DICT_MC_SKIP("name contains space");
@ -480,6 +501,12 @@ static void dict_memcache_close(DICT *dict)
cfg_parser_free(dict_mc->parser); cfg_parser_free(dict_mc->parser);
db_common_free_ctx(dict_mc->dbc_ctxt); db_common_free_ctx(dict_mc->dbc_ctxt);
if (dict_mc->key_digest)
myfree(dict_mc->key_digest);
if (dict_mc->key_dgst_eng)
ossl_digest_free(dict_mc->key_dgst_eng);
if (dict_mc->key_dgst_out)
vstring_free(dict_mc->key_dgst_out);
if (dict_mc->key_format) if (dict_mc->key_format)
myfree(dict_mc->key_format); myfree(dict_mc->key_format);
myfree(dict_mc->memcache); myfree(dict_mc->memcache);
@ -542,6 +569,17 @@ DICT *dict_memcache_open(const char *name, int open_flags, int dict_flags)
* Parse the configuration file. * Parse the configuration file.
*/ */
dict_mc->parser = parser; dict_mc->parser = parser;
dict_mc->key_digest = cfg_get_str(dict_mc->parser, DICT_MC_NAME_KEY_DGST,
DICT_MC_DEF_KEY_DGST, 0, 0);
if (*dict_mc->key_digest) {
if ((dict_mc->key_dgst_eng = ossl_digest_new(dict_mc->key_digest)) == 0)
/* See below for dict_surrogate() error propagation. */
ossl_digest_log_errors(msg_warn);
dict_mc->key_dgst_out = vstring_alloc(1);
} else {
dict_mc->key_dgst_eng = 0;
dict_mc->key_dgst_out = 0;
}
dict_mc->key_format = cfg_get_str(dict_mc->parser, DICT_MC_NAME_KEY_FMT, dict_mc->key_format = cfg_get_str(dict_mc->parser, DICT_MC_NAME_KEY_FMT,
DICT_MC_DEF_KEY_FMT, 0, 0); DICT_MC_DEF_KEY_FMT, 0, 0);
dict_mc->timeout = cfg_get_int(dict_mc->parser, DICT_MC_NAME_MC_TIMEOUT, dict_mc->timeout = cfg_get_int(dict_mc->parser, DICT_MC_NAME_MC_TIMEOUT,
@ -594,5 +632,15 @@ DICT *dict_memcache_open(const char *name, int open_flags, int dict_flags)
dict_mc->dict.flags |= DICT_FLAG_MULTI_WRITER; dict_mc->dict.flags |= DICT_FLAG_MULTI_WRITER;
if (*dict_mc->key_digest && dict_mc->key_dgst_eng == 0) {
/* See above for ossl_digest_new() error detection. */
DICT *d = dict_surrogate(DICT_TYPE_MEMCACHE, name,
open_flags, dict_flags,
"open %s: key digest %s is not available",
name, dict_mc->key_digest);
dict_memcache_close(&dict_mc->dict);
return (d);
}
return (&dict_mc->dict); return (&dict_mc->dict);
} }

View File

@ -390,6 +390,11 @@ char *var_known_tcp_ports;
const char null_format_string[1] = ""; const char null_format_string[1] = "";
/*
* Compatibility level 3.11.
*/
int warn_compat_break_smtp_tlsrpt_skip_reused_hs;
/* /*
* Compatibility level 3.6. * Compatibility level 3.6.
*/ */
@ -662,6 +667,15 @@ static void check_legacy_defaults(void)
* bits. * bits.
*/ */
/*
* Look for specific parameters whose default changed when the
* compatibility level changed to 3.11.
*/
if (compat_level < compat_level_from_string(COMPAT_LEVEL_3_11, msg_panic)) {
if (mail_conf_lookup(VAR_SMTP_TLSRPT_SKIP_REUSED_HS) == 0)
warn_compat_break_smtp_tlsrpt_skip_reused_hs = 1;
}
/* /*
* Look for specific parameters whose default changed when the * Look for specific parameters whose default changed when the
* compatibility level changed to 3.6. * compatibility level changed to 3.6.

View File

@ -51,10 +51,11 @@ extern bool var_show_unk_rcpt_table;
* updating the current compatibility level. * updating the current compatibility level.
*/ */
#define COMPAT_LEVEL_0 "0" #define COMPAT_LEVEL_0 "0"
#define COMPAT_LEVEL_1 "1" #define COMPAT_LEVEL_1 "1" /* Introduced: Postfix 3.0 */
#define COMPAT_LEVEL_2 "2" #define COMPAT_LEVEL_2 "2" /* Introduced: Postfix 3.0 */
#define COMPAT_LEVEL_3_6 "3.6" #define COMPAT_LEVEL_3_6 "3.6"
#define LAST_COMPAT_LEVEL COMPAT_LEVEL_3_6 #define COMPAT_LEVEL_3_11 "3.11"
#define LAST_COMPAT_LEVEL COMPAT_LEVEL_3_11
#define VAR_COMPAT_LEVEL "compatibility_level" #define VAR_COMPAT_LEVEL "compatibility_level"
#define DEF_COMPAT_LEVEL COMPAT_LEVEL_0 #define DEF_COMPAT_LEVEL COMPAT_LEVEL_0
@ -75,6 +76,8 @@ extern int warn_compat_break_lmtp_tls_fpt_dgst;
extern int warn_compat_relay_before_rcpt_checks; extern int warn_compat_relay_before_rcpt_checks;
extern int warn_compat_respectful_logging; extern int warn_compat_respectful_logging;
extern int warn_compat_break_smtp_tlsrpt_skip_reused_hs;
extern long compat_level; extern long compat_level;
/* /*
@ -4483,7 +4486,7 @@ extern bool var_smtp_tlsrpt_enable;
extern char *var_smtp_tlsrpt_sockname; extern char *var_smtp_tlsrpt_sockname;
#define VAR_SMTP_TLSRPT_SKIP_REUSED_HS "smtp_tlsrpt_skip_reused_handshakes" #define VAR_SMTP_TLSRPT_SKIP_REUSED_HS "smtp_tlsrpt_skip_reused_handshakes"
#define DEF_SMTP_TLSRPT_SKIP_REUSED_HS "yes" #define DEF_SMTP_TLSRPT_SKIP_REUSED_HS "no"
#define VAR_LMTP_TLSRPT_SKIP_REUSED_HS "lmtp_tlsrpt_skip_reused_handshakes" #define VAR_LMTP_TLSRPT_SKIP_REUSED_HS "lmtp_tlsrpt_skip_reused_handshakes"
#define DEF_LMTP_TLSRPT_SKIP_REUSED_HS DEF_SMTP_TLSRPT_SKIP_REUSED_HS #define DEF_LMTP_TLSRPT_SKIP_REUSED_HS DEF_SMTP_TLSRPT_SKIP_REUSED_HS
extern int var_smtp_tlsrpt_skip_reused_hs; extern int var_smtp_tlsrpt_skip_reused_hs;

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no * Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only. * patchlevel; they change the release date only.
*/ */
#define MAIL_RELEASE_DATE "20250418" #define MAIL_RELEASE_DATE "20250606"
#define MAIL_VERSION_NUMBER "3.11" #define MAIL_VERSION_NUMBER "3.11"
#ifdef SNAPSHOT #ifdef SNAPSHOT

View File

@ -10,6 +10,7 @@ PROG = postalias
INC_DIR = ../../include INC_DIR = ../../include
LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \ LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX) ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
NOSLEEP = LD_PRELOAD=../../lib/nosleep.so
.c.o:; $(CC) $(CFLAGS) -c $*.c .c.o:; $(CC) $(CFLAGS) -c $*.c
@ -23,42 +24,55 @@ Makefile: Makefile.in
update: ../../bin/$(PROG) update: ../../bin/$(PROG)
tests: test1 test2 fail_test tests: test1 test2 fail_test mode_conflict_test
root_tests: root_tests:
test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-uABC1.ref test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-uABC1.ref
${SHLIB_ENV} ${VALGRIND} ./$(PROG) map.in rm -f main.cf
touch -t 197101010000 main.cf
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . map.in
for key in abc ghi; \ for key in abc ghi; \
do \ do \
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -q $${key} map.in | diff map-$${key}1.ref -; \ ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -q $${key} map.in | diff map-$${key}1.ref -; \
done done
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -f map.in ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -f map.in
for key in ABC; \ for key in ABC; \
do \ do \
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -fq $${key} map.in | diff map-u$${key}1.ref -; \ ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -fq $${key} map.in | diff map-u$${key}1.ref -; \
done done
rm -f map.in.db rm -f map.in.db main.cf
test2: $(PROG) map.in map-abc2.ref map-ghi2.ref map-uABC2.ref test2: $(PROG) map.in map-abc2.ref map-ghi2.ref map-uABC2.ref
${SHLIB_ENV} ${VALGRIND} ./$(PROG) map.in rm -f main.cf
touch -t 197101010000 main.cf
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . map.in
for key in abc ghi; \ for key in abc ghi; \
do \ do \
echo $${key} | ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -q - map.in | diff map-$${key}2.ref -; \ echo $${key} | ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -q - map.in | diff map-$${key}2.ref -; \
done done
${SHLIB_ENV} ${VALGRIND} ./$(PROG) -f map.in ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -f map.in
for key in ABC; \ for key in ABC; \
do \ do \
echo $${key} | ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -fq - map.in | diff map-u$${key}2.ref -; \ echo $${key} | ${SHLIB_ENV} ${VALGRIND} ./$(PROG) -c . -fq - map.in | diff map-u$${key}2.ref -; \
done done
rm -f map.in.db rm -f map.in.db main.cf
fail_test: $(PROG) aliases fail_test.in fail_test.ref fail_test: $(PROG) aliases fail_test.in fail_test.ref
-(${SHLIB_ENV} sh fail_test.in 2>&1 || exit 0) | sed \ rm -f main.cf
touch -t 197101010000 main.cf
-(${SHLIB_ENV} MAIL_CONFIG=. $(NOSLEEP) sh fail_test.in 2>&1 || exit 0) | sed \
-e 's/No error:/Unknown error:/' \ -e 's/No error:/Unknown error:/' \
-e 's/Success/Unknown error: 0/' > fail_test.tmp -e 's/Success/Unknown error: 0/' > fail_test.tmp
diff fail_test.ref fail_test.tmp diff fail_test.ref fail_test.tmp
rm -f fail_test.tmp rm -f fail_test.tmp main.cf
mode_conflict_test: $(PROG) mode_conflict_test.in mode_conflict_test.ref
rm -f main.cf
touch -t 197101010000 main.cf
$(SHLIB_ENV) MAIL_CONFIG=. $(NOSLEEP) sh -x mode_conflict_test.in >mode_conflict_test.tmp 2>&1
diff mode_conflict_test.ref mode_conflict_test.tmp
rm -f mode_conflict_test.tmp main.cf
../../bin/$(PROG): $(PROG) ../../bin/$(PROG): $(PROG)
cp $(PROG) ../../bin cp $(PROG) ../../bin

View File

@ -0,0 +1,21 @@
${VALGRIND} ./postalias -d yy -d xx whatever:whatever && exit 1
${VALGRIND} ./postalias -d yy -i whatever:whatever && exit 1
${VALGRIND} ./postalias -d yy -q xx whatever:whatever && exit 1
${VALGRIND} ./postalias -d yy -s whatever:whatever && exit 1
${VALGRIND} ./postalias -i -d xx whatever:whatever && exit 1
${VALGRIND} ./postalias -i -i whatever:whatever && exit 1
${VALGRIND} ./postalias -i -q xx whatever:whatever && exit 1
${VALGRIND} ./postalias -i -s whatever:whatever && exit 1
${VALGRIND} ./postalias -q yy -d xx whatever:whatever && exit 1
${VALGRIND} ./postalias -q yy -i whatever:whatever && exit 1
${VALGRIND} ./postalias -q yy -q xx whatever:whatever && exit 1
${VALGRIND} ./postalias -q yy -s whatever:whatever && exit 1
${VALGRIND} ./postalias -s -d xx whatever:whatever && exit 1
${VALGRIND} ./postalias -s -i whatever:whatever && exit 1
${VALGRIND} ./postalias -s -q xx whatever:whatever && exit 1
${VALGRIND} ./postalias -s -s whatever:whatever && exit 1
exit 0

View File

@ -0,0 +1,33 @@
+ ./postalias -d yy -d xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -d yy -i whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -d yy -q xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -d yy -s whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -i -d xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -i -i whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -i -q xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -i -s whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -q yy -d xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -q yy -i whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -q yy -q xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -q yy -s whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -s -d xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -s -i whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -s -q xx whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ ./postalias -s -s whatever:whatever
postalias: fatal: specify only one of -d -i -q or -s
+ exit 0

View File

@ -734,6 +734,7 @@ int main(int argc, char **argv)
int open_flags = O_RDWR | O_CREAT | O_TRUNC; int open_flags = O_RDWR | O_CREAT | O_TRUNC;
int dict_flags = (DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_FIX int dict_flags = (DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_FIX
| DICT_FLAG_UTF8_REQUEST); | DICT_FLAG_UTF8_REQUEST);
int update = 0;
char *query = 0; char *query = 0;
char *delkey = 0; char *delkey = 0;
int sequence = 0; int sequence = 0;
@ -798,14 +799,17 @@ int main(int argc, char **argv)
msg_fatal("out of memory"); msg_fatal("out of memory");
break; break;
case 'd': case 'd':
if (sequence || query || delkey) if (update || sequence || query || delkey)
msg_fatal("specify only one of -s -q or -d"); msg_fatal("specify only one of -d -i -q or -s");
delkey = optarg; delkey = optarg;
break; break;
case 'f': case 'f':
dict_flags &= ~DICT_FLAG_FOLD_FIX; dict_flags &= ~DICT_FLAG_FOLD_FIX;
break; break;
case 'i': case 'i':
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
update = 1;
open_flags &= ~O_TRUNC; open_flags &= ~O_TRUNC;
break; break;
case 'n': case 'n':
@ -819,8 +823,8 @@ int main(int argc, char **argv)
postalias_flags &= ~POSTALIAS_FLAG_SAVE_PERM; postalias_flags &= ~POSTALIAS_FLAG_SAVE_PERM;
break; break;
case 'q': case 'q':
if (sequence || query || delkey) if (update || sequence || query || delkey)
msg_fatal("specify only one of -s -q or -d"); msg_fatal("specify only one of -d -i -q or -s");
query = optarg; query = optarg;
break; break;
case 'r': case 'r':
@ -828,8 +832,8 @@ int main(int argc, char **argv)
dict_flags |= DICT_FLAG_DUP_REPLACE; dict_flags |= DICT_FLAG_DUP_REPLACE;
break; break;
case 's': case 's':
if (query || delkey) if (update || sequence || query || delkey)
msg_fatal("specify only one of -s or -q or -d"); msg_fatal("specify only one of -d -i -q or -s");
sequence = 1; sequence = 1;
break; break;
case 'u': case 'u':

View File

@ -10,6 +10,7 @@ PROG = postmap
INC_DIR = ../../include INC_DIR = ../../include
LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \ LIBS = ../../lib/lib$(LIB_PREFIX)global$(LIB_SUFFIX) \
../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX) ../../lib/lib$(LIB_PREFIX)util$(LIB_SUFFIX)
NOSLEEP = LD_PRELOAD=../../lib/nosleep.so
.c.o:; $(CC) $(CFLAGS) -c $*.c .c.o:; $(CC) $(CFLAGS) -c $*.c
@ -27,52 +28,70 @@ update: ../../bin/$(PROG)
cp $(PROG) ../../bin cp $(PROG) ../../bin
tests: test1 test2 fail_test quote_test file_test lmdb_abb_test \ tests: test1 test2 fail_test quote_test file_test lmdb_abb_test \
lmdb_bulk_test lmdb_incr_test cdb_bulk_test lmdb_bulk_test lmdb_incr_test cdb_bulk_test mode_conflict_test
root_tests: root_tests:
test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-uABC1.ref test1: $(PROG) map.in map-abc1.ref map-ghi1.ref map-uABC1.ref
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) map.in rm -f main.cf
touch -t 197101010000 main.cf
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . map.in
for key in abc ghi; \ for key in abc ghi; \
do \ do \
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -q $${key} map.in | diff map-$${key}1.ref -; \ $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -q $${key} map.in | diff map-$${key}1.ref -; \
done done
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -f map.in $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -f map.in
for key in ABC; \ for key in ABC; \
do \ do \
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -fq $${key} map.in | diff map-u$${key}1.ref -; \ $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -fq $${key} map.in | diff map-u$${key}1.ref -; \
done done
rm -f map.in.db rm -f map.in.db main.cf
test2: $(PROG) map.in map-abc2.ref map-ghi2.ref map-uABC2.ref test2: $(PROG) map.in map-abc2.ref map-ghi2.ref map-uABC2.ref
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) map.in rm -f main.cf
touch -t 197101010000 main.cf
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . map.in
for key in abc ghi; \ for key in abc ghi; \
do \ do \
echo $${key} | $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -q - map.in | diff map-$${key}2.ref -; \ echo $${key} | $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -q - map.in | diff map-$${key}2.ref -; \
done done
$(SHLIB_ENV) $(VALGRIND) ./$(PROG) -f map.in $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -f map.in
for key in ABC; \ for key in ABC; \
do \ do \
echo $${key} | $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -fq - map.in | diff map-u$${key}2.ref -; \ echo $${key} | $(SHLIB_ENV) $(VALGRIND) ./$(PROG) -c . -fq - map.in | diff map-u$${key}2.ref -; \
done done
rm -f map.in.db rm -f map.in.db main.cf
fail_test: $(PROG) aliases fail_test.in fail_test.ref fail_test: $(PROG) aliases fail_test.in fail_test.ref
-($(SHLIB_ENV) sh fail_test.in || exit 0) >fail_test.tmp 2>&1 rm -f main.cf
touch -t 197101010000 main.cf
-($(SHLIB_ENV) MAIL_CONFIG=. $(NOSLEEP) sh fail_test.in || exit 0) >fail_test.tmp 2>&1
diff fail_test.ref fail_test.tmp diff fail_test.ref fail_test.tmp
rm -f fail_test.tmp rm -f fail_test.tmp main.cf
quote_test: $(PROG) aliases quote_test.in quote_test.ref quote_test: $(PROG) aliases quote_test.in quote_test.ref
rm -f main.cf
touch -t 197101010000 main.cf
rm -f quote_test_map.* rm -f quote_test_map.*
$(SHLIB_ENV) sh quote_test.in >quote_test.tmp 2>&1 $(SHLIB_ENV) MAIL_CONFIG=. sh quote_test.in >quote_test.tmp 2>&1
diff quote_test.ref quote_test.tmp diff quote_test.ref quote_test.tmp
rm -f quote_test.tmp quote_test_map.* rm -f quote_test.tmp quote_test_map.* main.cf
file_test: $(PROG) file_test.in file_test.ref file_test: $(PROG) file_test.in file_test.ref
rm -f main.cf
touch -t 197101010000 main.cf
rm -f file_test_map.* postmap-file-1 postmap-file-2 rm -f file_test_map.* postmap-file-1 postmap-file-2
$(SHLIB_ENV) sh file_test.in >file_test.tmp 2>&1 $(SHLIB_ENV) MAIL_CONFIG=. $(NOSLEEP) sh file_test.in >file_test.tmp 2>&1
diff file_test.ref file_test.tmp diff file_test.ref file_test.tmp
rm -f file_test.tmp file_test_map.* postmap-file-1 postmap-file-2 rm -f file_test.tmp file_test_map.* postmap-file-1 postmap-file-2 \
main.cf
mode_conflict_test: $(PROG) mode_conflict_test.in mode_conflict_test.ref
rm -f main.cf
touch -t 197101010000 main.cf
$(SHLIB_ENV) MAIL_CONFIG=. $(NOSLEEP) sh -x mode_conflict_test.in >mode_conflict_test.tmp 2>&1
diff mode_conflict_test.ref mode_conflict_test.tmp
rm -f mode_conflict_test.tmp main.cf
cdb_bulk_test: $(PROG) cdb_bulk_test: $(PROG)
rm -f cdb_bulk.cdb main.cf rm -f cdb_bulk.cdb main.cf
@ -80,15 +99,17 @@ cdb_bulk_test: $(PROG)
sed -e 's/.*/& &/' -e 10000q| LANG=C sort -u >cdb_bulk sed -e 's/.*/& &/' -e 10000q| LANG=C sort -u >cdb_bulk
touch -t 197101010000 main.cf touch -t 197101010000 main.cf
($(SHLIB_ENV) $(VALGRIND) ./postmap -c . cdb:cdb_bulk; \ ($(SHLIB_ENV) $(VALGRIND) ./postmap -c . cdb:cdb_bulk; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s cdb:cdb_bulk | \ $(SHLIB_ENV) $(VALGRIND) ./postmap -c . -s cdb:cdb_bulk | \
LANG=C sort > cdb_bulk.tmp) LANG=C sort > cdb_bulk.tmp)
cmp cdb_bulk cdb_bulk.tmp cmp cdb_bulk cdb_bulk.tmp
rm -f cdb_bulk cdb_bulk.tmp cdb_bulk.cdb main.cf rm -f cdb_bulk cdb_bulk.tmp cdb_bulk.cdb main.cf
lmdb_abb_test: $(PROG) lmdb_abb lmdb_abb.ref lmdb_abb_test: $(PROG) lmdb_abb lmdb_abb.ref
rm -f main.cf
touch -t 197101010000 main.cf
rm -f lmdb_abb.lmdb rm -f lmdb_abb.lmdb
($(SHLIB_ENV) $(VALGRIND) ./postmap lmdb:lmdb_abb; \ ($(SHLIB_ENV) $(VALGRIND) ./postmap -c . lmdb:lmdb_abb; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_abb | sort) >lmdb_abb.tmp 2>&1 $(SHLIB_ENV) $(VALGRIND) ./postmap -c . -s lmdb:lmdb_abb | sort) >lmdb_abb.tmp 2>&1
diff lmdb_abb.ref lmdb_abb.tmp diff lmdb_abb.ref lmdb_abb.tmp
rm -f lmdb_abb.tmp lmdb_abb.lmdb rm -f lmdb_abb.tmp lmdb_abb.lmdb
@ -99,7 +120,7 @@ lmdb_bulk_test: $(PROG)
echo lmdb_map_size=10240 >main.cf echo lmdb_map_size=10240 >main.cf
touch -t 197101010000 main.cf touch -t 197101010000 main.cf
($(SHLIB_ENV) $(VALGRIND) ./postmap -c . lmdb:lmdb_retry; \ ($(SHLIB_ENV) $(VALGRIND) ./postmap -c . lmdb:lmdb_retry; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_retry | \ $(SHLIB_ENV) $(VALGRIND) ./postmap -c . -s lmdb:lmdb_retry | \
LANG=C sort > lmdb_retry.tmp) LANG=C sort > lmdb_retry.tmp)
cmp lmdb_retry lmdb_retry.tmp cmp lmdb_retry lmdb_retry.tmp
rm -f lmdb_retry lmdb_retry.tmp lmdb_retry.lmdb main.cf rm -f lmdb_retry lmdb_retry.tmp lmdb_retry.lmdb main.cf
@ -111,13 +132,13 @@ lmdb_incr_test: $(PROG)
echo lmdb_map_size=10240 >main.cf echo lmdb_map_size=10240 >main.cf
touch -t 197101010000 main.cf touch -t 197101010000 main.cf
($(SHLIB_ENV) $(VALGRIND) ./postmap -ic . lmdb:lmdb_retry <lmdb_retry; \ ($(SHLIB_ENV) $(VALGRIND) ./postmap -ic . lmdb:lmdb_retry <lmdb_retry; \
$(SHLIB_ENV) $(VALGRIND) ./postmap -s lmdb:lmdb_retry | \ $(SHLIB_ENV) $(VALGRIND) ./postmap -c . -s lmdb:lmdb_retry | \
LANG=C sort > lmdb_retry.tmp) LANG=C sort > lmdb_retry.tmp)
cmp lmdb_retry lmdb_retry.tmp cmp lmdb_retry lmdb_retry.tmp
rm -f lmdb_retry lmdb_retry.tmp lmdb_retry.lmdb main.cf rm -f lmdb_retry lmdb_retry.tmp lmdb_retry.lmdb main.cf
clean: clean:
rm -f *.o *core $(PROG) $(TESTPROG) *.tmp junk *.db rm -f *.o *core $(PROG) $(TESTPROG) *.tmp junk *.db main.cf master.cf
tidy: clean tidy: clean

View File

@ -0,0 +1,21 @@
${VALGRIND} ./postmap -d yy -d xx whatever:whatever && exit 1
${VALGRIND} ./postmap -d yy -i whatever:whatever && exit 1
${VALGRIND} ./postmap -d yy -q xx whatever:whatever && exit 1
${VALGRIND} ./postmap -d yy -s whatever:whatever && exit 1
${VALGRIND} ./postmap -i -d xx whatever:whatever && exit 1
${VALGRIND} ./postmap -i -i whatever:whatever && exit 1
${VALGRIND} ./postmap -i -q xx whatever:whatever && exit 1
${VALGRIND} ./postmap -i -s whatever:whatever && exit 1
${VALGRIND} ./postmap -q yy -d xx whatever:whatever && exit 1
${VALGRIND} ./postmap -q yy -i whatever:whatever && exit 1
${VALGRIND} ./postmap -q yy -q xx whatever:whatever && exit 1
${VALGRIND} ./postmap -q yy -s whatever:whatever && exit 1
${VALGRIND} ./postmap -s -d xx whatever:whatever && exit 1
${VALGRIND} ./postmap -s -i whatever:whatever && exit 1
${VALGRIND} ./postmap -s -q xx whatever:whatever && exit 1
${VALGRIND} ./postmap -s -s whatever:whatever && exit 1
exit 0

View File

@ -0,0 +1,33 @@
+ ./postmap -d yy -d xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -d yy -i whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -d yy -q xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -d yy -s whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -i -d xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -i -i whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -i -q xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -i -s whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -q yy -d xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -q yy -i whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -q yy -q xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -q yy -s whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -s -d xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -s -i whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -s -q xx whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ ./postmap -s -s whatever:whatever
postmap: fatal: specify only one of -d -i -q or -s
+ exit 0

View File

@ -957,6 +957,7 @@ int main(int argc, char **argv)
int open_flags = O_RDWR | O_CREAT | O_TRUNC; int open_flags = O_RDWR | O_CREAT | O_TRUNC;
int dict_flags = (DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_FIX int dict_flags = (DICT_FLAG_DUP_WARN | DICT_FLAG_FOLD_FIX
| DICT_FLAG_UTF8_REQUEST); | DICT_FLAG_UTF8_REQUEST);
int update = 0;
char *query = 0; char *query = 0;
char *delkey = 0; char *delkey = 0;
int sequence = 0; int sequence = 0;
@ -1025,8 +1026,8 @@ int main(int argc, char **argv)
msg_fatal("out of memory"); msg_fatal("out of memory");
break; break;
case 'd': case 'd':
if (sequence || query || delkey) if (update || sequence || query || delkey)
msg_fatal("specify only one of -s -q or -d"); msg_fatal("specify only one of -d -i -q or -s");
delkey = optarg; delkey = optarg;
break; break;
case 'f': case 'f':
@ -1039,6 +1040,9 @@ int main(int argc, char **argv)
postmap_flags |= POSTMAP_FLAG_HEADER_KEY; postmap_flags |= POSTMAP_FLAG_HEADER_KEY;
break; break;
case 'i': case 'i':
if (update || sequence || query || delkey)
msg_fatal("specify only one of -d -i -q or -s");
update = 1;
open_flags &= ~O_TRUNC; open_flags &= ~O_TRUNC;
break; break;
case 'm': case 'm':
@ -1055,8 +1059,8 @@ int main(int argc, char **argv)
postmap_flags &= ~POSTMAP_FLAG_SAVE_PERM; postmap_flags &= ~POSTMAP_FLAG_SAVE_PERM;
break; break;
case 'q': case 'q':
if (sequence || query || delkey) if (update || sequence || query || delkey)
msg_fatal("specify only one of -s -q or -d"); msg_fatal("specify only one of -d -i -q or -s");
query = optarg; query = optarg;
break; break;
case 'r': case 'r':
@ -1064,8 +1068,8 @@ int main(int argc, char **argv)
dict_flags |= DICT_FLAG_DUP_REPLACE; dict_flags |= DICT_FLAG_DUP_REPLACE;
break; break;
case 's': case 's':
if (query || delkey) if (update || sequence || query || delkey)
msg_fatal("specify only one of -s or -q or -d"); msg_fatal("specify only one of -d -i -q or -s");
sequence = 1; sequence = 1;
break; break;
case 'u': case 'u':

View File

@ -250,6 +250,12 @@ void smtp_tlsrpt_create_wrapper(SMTP_STATE *state, const char *domain)
if (msg_verbose) if (msg_verbose)
msg_info("%s: domain %s has policy %.100s", msg_info("%s: domain %s has policy %.100s",
smtp_tlsrpt_support, domain, rr->data); smtp_tlsrpt_support, domain, rr->data);
if (warn_compat_break_smtp_tlsrpt_skip_reused_hs) {
msg_info("using using backwards-compatible default setting "
VAR_SMTP_TLSRPT_SKIP_REUSED_HS "=yes");
var_smtp_tlsrpt_skip_reused_hs = 1;
warn_compat_break_smtp_tlsrpt_skip_reused_hs = 0;
}
state->tlsrpt = trw_create( state->tlsrpt = trw_create(
/* rpt_socket_name= */ var_smtp_tlsrpt_sockname, /* rpt_socket_name= */ var_smtp_tlsrpt_sockname,
/* rpt_policy_domain= */ adomain, /* rpt_policy_domain= */ adomain,

1
postfix/src/testing/.indent.pro vendored Symbolic link
View File

@ -0,0 +1 @@
../../.indent.pro

View File

@ -0,0 +1,35 @@
LIB_SO = nosleep.so
LIB_DIR = ../../lib
INC_DIR = ../../include
all: $(LIB_SO)
Makefile: Makefile.in
cat ../../conf/makedefs.out $? >$@
nosleep.so: nosleep.c
$(CC) $(CFLAGS) -fPIC -shared -o $@ $?
update: lib_so_update
lib_so_update: $(LIB_SO)
for i in $(LIB_SO); do \
cmp -s $$i $(LIB_DIR)/$$i 2>/dev/null || cp $$i $(LIB_DIR); \
done
clean:
rm -f $(LIB_SO) *.o
tidy: clean
depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \
$(CC) -E $(DEFS) $(INCL) $$i | grep -v '[<>]' | sed -n -e '/^# *1 *"\([^"]*\)".*/{' \
-e 's//'`echo $$i|sed 's/c$$/o/'`': \1/' \
-e 's/o: \.\//o: /' -e p -e '}' ; \
done | LANG=C sort -u) | grep -v '[.][o][:][ ][/]' >$$$$ && mv $$$$ Makefile.in
@$(EXPORT) make -f Makefile.in Makefile 1>&2
# do not edit below this line - it is generated by 'make depend'
nosleep.o: nosleep.c

View File

@ -0,0 +1,29 @@
/*++
/* NAME
/* nosleep 3
/* SUMMARY
/* override the system sleep(3) implementation
/* SYNOPSIS
/* LD_PRELOAD=/path/to/nosleep.so command....
/*
/* int sleep(unsigned int seconds)
/* DESCRIPTION
/* This sleep(3) implementation returns zero immediately. The purpose
/* is to speed up error handler tests by skipping the delay between
/* reporting a fatal error and before terminating the process.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
#include <unistd.h>
unsigned int sleep(unsigned int seconds)
{
/* Don't sleep. */
return (0);
}

View File

@ -47,7 +47,7 @@ SRCS = alldig.c allprint.c argv.c argv_split.c attr_clnt.c attr_print0.c \
mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c inet_prefix_top.c \ mkmap_fail.c mkmap_lmdb.c mkmap_open.c mkmap_sdbm.c inet_prefix_top.c \
inet_addr_sizes.c quote_for_json.c mystrerror.c \ inet_addr_sizes.c quote_for_json.c mystrerror.c \
sane_sockaddr_to_hostaddr.c normalize_ws.c valid_uri_scheme.c \ sane_sockaddr_to_hostaddr.c normalize_ws.c valid_uri_scheme.c \
clean_ascii_cntrl_space.c normalize_v4mapped_addr.c clean_ascii_cntrl_space.c normalize_v4mapped_addr.c ossl_digest.c
OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \ attr_print64.o attr_print_plain.o attr_scan0.o attr_scan64.o \
attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \ attr_scan_plain.o auto_clnt.o base64_code.o basename.o binhash.o \
@ -96,7 +96,7 @@ OBJS = alldig.o allprint.o argv.o argv_split.o attr_clnt.o attr_print0.o \
mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.o \ mkmap_fail.o mkmap_open.o inet_prefix_top.o inet_addr_sizes.o \
quote_for_json.o mystrerror.o sane_sockaddr_to_hostaddr.o \ quote_for_json.o mystrerror.o sane_sockaddr_to_hostaddr.o \
normalize_ws.o valid_uri_scheme.o clean_ascii_cntrl_space.o \ normalize_ws.o valid_uri_scheme.o clean_ascii_cntrl_space.o \
normalize_v4mapped_addr.o normalize_v4mapped_addr.o ossl_digest.o
# MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf. # MAP_OBJ is for maps that may be dynamically loaded with dynamicmaps.cf.
# When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ), # When hard-linking these, makedefs sets NON_PLUGIN_MAP_OBJ=$(MAP_OBJ),
# otherwise it sets the PLUGIN_* macros. # otherwise it sets the PLUGIN_* macros.
@ -129,7 +129,7 @@ HDRS = argv.h attr.h attr_clnt.h auto_clnt.h base64_code.h binhash.h \
check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \ check_arg.h argv_attr.h msg_logger.h logwriter.h byte_mask.h \
known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h \ known_tcp_ports.h sane_strtol.h hash_fnv.h ldseed.h mkmap.h \
inet_prefix_top.h inet_addr_sizes.h valid_uri_scheme.h \ inet_prefix_top.h inet_addr_sizes.h valid_uri_scheme.h \
clean_ascii_cntrl_space.h normalize_v4mapped_addr.h clean_ascii_cntrl_space.h normalize_v4mapped_addr.h ossl_digest.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \ TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c stream_test.c dup2_pass_on_exec.c
DEFS = -I. -D$(SYSTYPE) DEFS = -I. -D$(SYSTYPE)
@ -153,7 +153,7 @@ TESTPROG= dict_open dup2_pass_on_exec events exec_command fifo_open \
known_tcp_ports dict_stream find_inet binhash hash_fnv argv \ known_tcp_ports dict_stream find_inet binhash hash_fnv argv \
clean_env inet_prefix_top printable readlline quote_for_json \ clean_env inet_prefix_top printable readlline quote_for_json \
normalize_ws valid_uri_scheme clean_ascii_cntrl_space \ normalize_ws valid_uri_scheme clean_ascii_cntrl_space \
normalize_v4mapped_addr_test normalize_v4mapped_addr_test ossl_digest_test
PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \ PLUGIN_MAP_SO = $(LIB_PREFIX)pcre$(LIB_SUFFIX) $(LIB_PREFIX)lmdb$(LIB_SUFFIX) \
$(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX) $(LIB_PREFIX)cdb$(LIB_SUFFIX) $(LIB_PREFIX)sdbm$(LIB_SUFFIX)
HTABLE_FIX = NORANDOMIZE=1 HTABLE_FIX = NORANDOMIZE=1
@ -635,6 +635,9 @@ clean_ascii_cntrl_space: $(LIB)
normalize_v4mapped_addr_test: normalize_v4mapped_addr_test.c $(LIB) normalize_v4mapped_addr_test: normalize_v4mapped_addr_test.c $(LIB)
$(CC) $(CFLAGS) -o $@ normalize_v4mapped_addr_test.c $(LIB) $(SYSLIBS) $(CC) $(CFLAGS) -o $@ normalize_v4mapped_addr_test.c $(LIB) $(SYSLIBS)
ossl_digest_test: ossl_digest_test.c $(LIB)
$(CC) $(CFLAGS) -o $@ $@.c $(LIB) $(SYSLIBS)
tests: all valid_hostname_test mac_expand_test dict_test unescape_test \ tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
hex_quote_test ctable_test inet_addr_list_test base64_code_test \ hex_quote_test ctable_test inet_addr_list_test base64_code_test \
attr_scan64_test attr_scan0_test host_port_test dict_tests \ attr_scan64_test attr_scan0_test host_port_test dict_tests \
@ -647,7 +650,7 @@ tests: all valid_hostname_test mac_expand_test dict_test unescape_test \
binhash_test argv_test inet_prefix_top_test printable_test \ binhash_test argv_test inet_prefix_top_test printable_test \
valid_utf8_string_test readlline_test quote_for_json_test \ valid_utf8_string_test readlline_test quote_for_json_test \
normalize_ws_test valid_uri_scheme_test clean_ascii_cntrl_space_test \ normalize_ws_test valid_uri_scheme_test clean_ascii_cntrl_space_test \
test_normalize_v4mapped_addr test_normalize_v4mapped_addr test_ossl_digest
dict_tests: all dict_test \ dict_tests: all dict_test \
dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \ dict_pcre_tests dict_cidr_test dict_thash_test dict_static_test \
@ -1136,6 +1139,9 @@ clean_ascii_cntrl_space_test: clean_ascii_cntrl_space
test_normalize_v4mapped_addr: update normalize_v4mapped_addr_test test_normalize_v4mapped_addr: update normalize_v4mapped_addr_test
$(SHLIB_ENV) ${VALGRIND} ./normalize_v4mapped_addr_test $(SHLIB_ENV) ${VALGRIND} ./normalize_v4mapped_addr_test
test_ossl_digest: update ossl_digest_test
$(SHLIB_ENV) ${VALGRIND} ./ossl_digest_test
depend: $(MAKES) depend: $(MAKES)
(sed '1,/^# do not edit/!d' Makefile.in; \ (sed '1,/^# do not edit/!d' Makefile.in; \
set -e; for i in [a-z][a-z0-9]*.c; do \ set -e; for i in [a-z][a-z0-9]*.c; do \
@ -2480,10 +2486,14 @@ myaddrinfo.o: sys_defs.h
myaddrinfo.o: valid_hostname.h myaddrinfo.o: valid_hostname.h
myaddrinfo.o: vbuf.h myaddrinfo.o: vbuf.h
myaddrinfo.o: vstring.h myaddrinfo.o: vstring.h
myflock.o: check_arg.h
myflock.o: msg.h myflock.o: msg.h
myflock.o: myflock.c myflock.o: myflock.c
myflock.o: myflock.h myflock.o: myflock.h
myflock.o: name_mask.h
myflock.o: sys_defs.h myflock.o: sys_defs.h
myflock.o: vbuf.h
myflock.o: vstring.h
mymalloc.o: msg.h mymalloc.o: msg.h
mymalloc.o: mymalloc.c mymalloc.o: mymalloc.c
mymalloc.o: mymalloc.h mymalloc.o: mymalloc.h

View File

@ -32,6 +32,9 @@
/* int first_next; /* int first_next;
/* const char **cache_key; /* const char **cache_key;
/* const char **cache_val; /* const char **cache_val;
/*
/* int dict_cache_error(cache)
/* DICT_CACHE *cache;
/* AUXILIARY FUNCTIONS /* AUXILIARY FUNCTIONS
/* void dict_cache_control(cache, name, value, ...) /* void dict_cache_control(cache, name, value, ...)
/* DICT_CACHE *cache; /* DICT_CACHE *cache;
@ -122,6 +125,9 @@
/* .PP /* .PP
/* dict_cache_name() returns the name of the specified cache. /* dict_cache_name() returns the name of the specified cache.
/* /*
/* dict_cache_error() returns the error status for the underlying
/* dictionary.
/*
/* Arguments: /* Arguments:
/* .IP "dbname, open_flags, dict_flags" /* .IP "dbname, open_flags, dict_flags"
/* These are passed unchanged to dict_open(). The cache must /* These are passed unchanged to dict_open(). The cache must
@ -681,14 +687,21 @@ const char *dict_cache_name(DICT_CACHE *cp)
{ {
/* /*
* This is used for verbose logging or warning messages, so the cost of * This is used for verbose logging or warning messages, so the cost of a
* call is only made where needed (well sort off - code that does not * call is only made where needed (well sort of - code that does not
* execute still presents overhead for the processor pipeline, processor * execute still presents overhead for the processor pipeline, processor
* cache, etc). * cache, etc).
*/ */
return (cp->name); return (cp->name);
} }
/* dict_cache_error - get the dictionary error status */
int dict_cache_error(DICT_CACHE *cp)
{
return (cp->error);
}
/* /*
* Test driver with support for interleaved access. First, enter a number of * Test driver with support for interleaved access. First, enter a number of
* requests to look up, update or delete a sequence of cache entries, then * requests to look up, update or delete a sequence of cache entries, then

View File

@ -31,6 +31,7 @@ extern int dict_cache_delete(DICT_CACHE *, const char *);
extern int dict_cache_sequence(DICT_CACHE *, int, const char **, const char **); extern int dict_cache_sequence(DICT_CACHE *, int, const char **, const char **);
extern void dict_cache_control(DICT_CACHE *,...); extern void dict_cache_control(DICT_CACHE *,...);
extern const char *dict_cache_name(DICT_CACHE *); extern const char *dict_cache_name(DICT_CACHE *);
extern int dict_cache_error(DICT_CACHE *);
#define DICT_CACHE_FLAG_VERBOSE (1<<0) /* verbose operation */ #define DICT_CACHE_FLAG_VERBOSE (1<<0) /* verbose operation */
#define DICT_CACHE_FLAG_STATISTICS (1<<1) /* log cache statistics */ #define DICT_CACHE_FLAG_STATISTICS (1<<1) /* log cache statistics */

View File

@ -494,12 +494,18 @@ static DICT *dict_cdbm_open(const char *path, int dict_flags)
DICT *dict_cdb_open(const char *path, int open_flags, int dict_flags) DICT *dict_cdb_open(const char *path, int open_flags, int dict_flags)
{ {
switch (open_flags & (O_RDONLY | O_RDWR | O_WRONLY | O_CREAT | O_TRUNC)) { switch (open_flags & (O_RDONLY | O_RDWR | O_WRONLY | O_CREAT | O_TRUNC)) {
case O_RDONLY: /* query mode */ case O_RDONLY: /* query mode */
return dict_cdbq_open(path, dict_flags); return dict_cdbq_open(path, dict_flags);
case O_WRONLY | O_CREAT | O_TRUNC: /* create mode */ case O_WRONLY | O_CREAT | O_TRUNC: /* create mode */
case O_RDWR | O_CREAT | O_TRUNC: /* sloppiness */ case O_RDWR | O_CREAT | O_TRUNC: /* sloppiness */
return dict_cdbm_open(path, dict_flags); return dict_cdbm_open(path, dict_flags);
case O_RDWR | O_CREAT:
case O_RDWR:
/* User error. */
return (dict_surrogate(DICT_TYPE_CDB, path, open_flags, dict_flags,
"unsupported non-bulk change request"));
default: default:
/* Programmer error. */
msg_fatal("dict_cdb_open: inappropriate open flags for cdb database" msg_fatal("dict_cdb_open: inappropriate open flags for cdb database"
" - specify O_RDONLY or O_WRONLY|O_CREAT|O_TRUNC"); " - specify O_RDONLY or O_WRONLY|O_CREAT|O_TRUNC");
} }

View File

@ -650,9 +650,9 @@ static DICT *dict_db_open(const char *class, const char *path, int open_flags,
DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH, DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH,
major_version, minor_version, patch_version)); major_version, minor_version, patch_version));
if (msg_verbose) { if (msg_verbose) {
msg_info("Compiled against Berkeley DB: %d.%d.%d\n", msg_info("Compiled against Berkeley DB: %d.%d.%d",
DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH); DB_VERSION_MAJOR, DB_VERSION_MINOR, DB_VERSION_PATCH);
msg_info("Run-time linked against Berkeley DB: %d.%d.%d\n", msg_info("Run-time linked against Berkeley DB: %d.%d.%d",
major_version, minor_version, patch_version); major_version, minor_version, patch_version);
} }
#else #else

View File

@ -46,6 +46,8 @@
/* Inserts one ":" between bytes. /* Inserts one ":" between bytes.
/* .IP HEX_ENCODE_FLAG_APPEND /* .IP HEX_ENCODE_FLAG_APPEND
/* Append output to the buffer. /* Append output to the buffer.
/* .IP HEX_ENCODE_FLAG_LOWERCASE
/* Output lowercase characters.
/* .PP /* .PP
/* hex_decode_opt() enables extended functionality as controlled /* hex_decode_opt() enables extended functionality as controlled
/* with \fIflags\fR. /* with \fIflags\fR.
@ -91,7 +93,8 @@
/* Application-specific. */ /* Application-specific. */
static const unsigned char hex_chars[] = "0123456789ABCDEF"; static const unsigned char lower_hex_chars[] = "0123456789abcdef";
static const unsigned char upper_hex_chars[] = "0123456789ABCDEF";
#define UCHAR_PTR(x) ((const unsigned char *)(x)) #define UCHAR_PTR(x) ((const unsigned char *)(x))
@ -108,12 +111,17 @@ VSTRING *hex_encode(VSTRING *result, const char *in, ssize_t len)
VSTRING *hex_encode_opt(VSTRING *result, const char *in, ssize_t len, int flags) VSTRING *hex_encode_opt(VSTRING *result, const char *in, ssize_t len, int flags)
{ {
const unsigned char *hex_chars;
const unsigned char *cp; const unsigned char *cp;
int ch; int ch;
ssize_t count; ssize_t count;
if ((flags & HEX_ENCODE_FLAG_APPEND) == 0) if ((flags & HEX_ENCODE_FLAG_APPEND) == 0)
VSTRING_RESET(result); VSTRING_RESET(result);
if ((flags & HEX_ENCODE_FLAG_LOWERCASE) != 0)
hex_chars = lower_hex_chars;
else
hex_chars = upper_hex_chars;
for (cp = UCHAR_PTR(in), count = len; count > 0; count--, cp++) { for (cp = UCHAR_PTR(in), count = len; count > 0; count--, cp++) {
ch = *cp; ch = *cp;
VSTRING_ADDCH(result, hex_chars[(ch >> 4) & 0xf]); VSTRING_ADDCH(result, hex_chars[(ch >> 4) & 0xf]);
@ -256,6 +264,34 @@ static const TEST_CASE test_cases[] = {
0, 0,
0, 0,
}, },
{"hex_encode_to_lowercase", hex_encode_opt,
"\377\376\375\374\373\372",
sizeof("\377\376\375\374\373\372") - 1,
HEX_ENCODE_FLAG_LOWERCASE,
"fffefdfcfbfa",
sizeof("fffefdfcfbfa") - 1,
},
{"hex_decode_from_lowercase", hex_decode_opt,
"fffefdfcfbfa",
sizeof("fffefdfcfbfa") - 1,
0,
"\377\376\375\374\373\372",
sizeof("\377\376\375\374\373\372") - 1,
},
{"hex_encode_to_uppercase", hex_encode_opt,
"\377\376\375\374\373\372",
sizeof("\377\376\375\374\373\372") - 1,
0,
"FFFEFDFCFBFA",
sizeof("FFFEFDFCFBFA") - 1,
},
{"hex_decode_from_uppercase", hex_decode_opt,
"FFFEFDFCFBFA",
sizeof("FFFEFDFCFBFA") - 1,
0,
"\377\376\375\374\373\372",
sizeof("\377\376\375\374\373\372") - 1,
},
{0}, {0},
}; };

View File

@ -22,6 +22,7 @@
#define HEX_ENCODE_FLAG_NONE (0) #define HEX_ENCODE_FLAG_NONE (0)
#define HEX_ENCODE_FLAG_USE_COLON (1<<0) #define HEX_ENCODE_FLAG_USE_COLON (1<<0)
#define HEX_ENCODE_FLAG_APPEND (1<<1) #define HEX_ENCODE_FLAG_APPEND (1<<1)
#define HEX_ENCODE_FLAG_LOWERCASE (1<<2)
#define HEX_DECODE_FLAG_NONE (0) #define HEX_DECODE_FLAG_NONE (0)
#define HEX_DECODE_FLAG_ALLOW_COLON (1<<0) #define HEX_DECODE_FLAG_ALLOW_COLON (1<<0)

View File

@ -29,24 +29,33 @@
/* void mkmap_close(mkmap) /* void mkmap_close(mkmap)
/* MKMAP *mkmap; /* MKMAP *mkmap;
/* DESCRIPTION /* DESCRIPTION
/* This module implements support for creating Postfix databases. /* This module adds support for creating Postfix databases from
/* It is a dict(3) wrapper that adds global locking to dict-level /* scratch. See dict(3) for a description of the \fBopen_flags\fR
/* routines where appropriate. /* and \fBdict_flags\fR arguments.
/* /*
/* mkmap_open() creates or truncates the named database, after /* To create a database from scratch (open_flags contains O_TRUNC),
/* appending the appropriate suffixes to the specified filename. /* the plugin code for the database type must provide a
/* Before the database is updated, it is locked for exclusive /* mkmap_<type>_open() function that maintains a global lock for
/* access, and signal delivery is suspended. /* exclusive access until the database is closed.
/* See dict(3) for a description of \fBopen_flags\fR and /*
/* \fBdict_flags\fR. All errors are fatal. /* To access a database type that has no global locking support
/* (no mkmap_<type>_open() function), mkmap_open() opens the database
/* requesting its dict(3) built-in per-update locking.
/*
/* mkmap_open() suspends signal delivery before opening a database
/* and resumes signal delivery when it is safe: before the first
/* update if the database implements transaction safety, otherwise
/* after the database is closed.
/*
/* All mkmap_open() errors are fatal.
/* /*
/* mkmap_append() appends the named (key, value) pair to the /* mkmap_append() appends the named (key, value) pair to the
/* database. Update errors are fatal; duplicate keys are ignored /* database. Update errors are fatal; duplicate keys are ignored
/* (but a warning is issued). /* (but a warning is issued). The \fBlineno\fR argument is used
/* \fBlineno\fR is used for diagnostics. /* for diagnostic messages.
/* /*
/* mkmap_close() closes the database, releases any locks, /* mkmap_close() closes the database, releases any locks, and
/* and resumes signal delivery. All errors are fatal. /* resumes signal delivery. All errors are fatal.
/* SEE ALSO /* SEE ALSO
/* sigdelay(3) suspend/resume signal delivery /* sigdelay(3) suspend/resume signal delivery
/* LICENSE /* LICENSE
@ -63,6 +72,9 @@
/* Google, Inc. /* Google, Inc.
/* 111 8th Avenue /* 111 8th Avenue
/* New York, NY 10011, USA /* New York, NY 10011, USA
/*
/* Wietse Venema
/* porcupine.org
/*--*/ /*--*/
/* System library. */ /* System library. */
@ -125,7 +137,7 @@ MKMAP *mkmap_open(const char *type, const char *path,
*/ */
if ((dp = dict_open_lookup(type)) == 0) if ((dp = dict_open_lookup(type)) == 0)
msg_fatal("unsupported map type: %s", type); msg_fatal("unsupported map type: %s", type);
if (dp->mkmap_fn == 0) if (dp->mkmap_fn == 0 && (open_flags & O_TRUNC) != 0)
msg_fatal("no 'map create' support for this type: %s", type); msg_fatal("no 'map create' support for this type: %s", type);
if (msg_verbose) if (msg_verbose)
msg_info("open %s %s", type, path); msg_info("open %s %s", type, path);
@ -136,7 +148,8 @@ MKMAP *mkmap_open(const char *type, const char *path,
* dict modules implement locking only for individual record operations, * dict modules implement locking only for individual record operations,
* because most Postfix applications don't need global exclusive locks. * because most Postfix applications don't need global exclusive locks.
*/ */
mkmap = dp->mkmap_fn(path); if (dp->mkmap_fn != 0)
mkmap = dp->mkmap_fn(path);
/* /*
* Delay signal delivery, so that we won't leave the database in an * Delay signal delivery, so that we won't leave the database in an
@ -145,16 +158,28 @@ MKMAP *mkmap_open(const char *type, const char *path,
sigdelay(); sigdelay();
/* /*
* Truncate the database upon open, and update it. Read-write mode is * Create or open a database that supports global locking. We explicitly
* needed because the underlying routines read as well as write. We * clobber the per-table lock_fd to trigger a fatal error when a table
* explicitly clobber lock_fd to trigger a fatal error when a map wants * wants to release its lock after an individual transaction. We clobber
* to unlock the database after individual transactions: that would * stat_fd as well, because that, too, is used only for non-bulk
* result in race condition problems. We clobbber stat_fd as well, * applications.
* because that, too, is used only for individual-transaction clients.
*/ */
mkmap->dict = mkmap->open(path, open_flags, dict_flags); if (dp->mkmap_fn != 0) { /* Global lock */
mkmap->dict->lock_fd = -1; /* XXX just in case */ mkmap->dict = mkmap->open(path, open_flags, dict_flags);
mkmap->dict->stat_fd = -1; /* XXX just in case */ mkmap->dict->lock_fd = -1; /* XXX just in case */
mkmap->dict->stat_fd = -1; /* XXX just in case */
}
/*
* Otherwise, craft a surrogate MKMAP structure and request per-update
* locks.
*/
else { /* Per-update lock */
mkmap = (MKMAP *) mymalloc(sizeof(*mkmap));
mkmap->dict = dp->dict_fn(path, open_flags, dict_flags | DICT_FLAG_LOCK);
mkmap->after_open = 0; /* No global lock */
mkmap->after_close = 0; /* No global unlock */
}
mkmap->dict->flags |= DICT_FLAG_DUP_WARN; mkmap->dict->flags |= DICT_FLAG_DUP_WARN;
mkmap->multi_writer = (mkmap->dict->flags & DICT_FLAG_MULTI_WRITER); mkmap->multi_writer = (mkmap->dict->flags & DICT_FLAG_MULTI_WRITER);

View File

@ -81,12 +81,39 @@
#include "msg.h" #include "msg.h"
#include "myflock.h" #include "myflock.h"
#include "name_mask.h"
#include "vstring.h"
/* myflock - lock/unlock entire open file */ /* myflock - lock/unlock entire open file */
int myflock(int fd, int lock_style, int operation) int myflock(int fd, int lock_style, int operation)
{ {
int status; int status;
const static NAME_MASK lock_masks[] = {
"MYFLOCK_STYLE_FLOCK", MYFLOCK_STYLE_FLOCK,
"MYFLOCK_STYLE_FCNTL", MYFLOCK_STYLE_FCNTL,
0,
};
const static NAME_MASK op_masks[] = {
"MYFLOCK_OP_SHARED", MYFLOCK_OP_SHARED,
"MYFLOCK_OP_EXCLUSIVE", MYFLOCK_OP_EXCLUSIVE,
"MYFLOCK_OP_NOWAIT", MYFLOCK_OP_NOWAIT,
0,
};
if (msg_verbose) {
VSTRING *style_buf = vstring_alloc(100);
VSTRING *op_buf = vstring_alloc(100);
msg_info("myflock(%d, %s, %s)", fd,
str_name_mask_opt(style_buf, "lock_style", lock_masks,
lock_style, NAME_MASK_PIPE | NAME_MASK_NUMBER),
operation == MYFLOCK_OP_NONE ? "MYFLOCK_OP_NONE" :
str_name_mask_opt(op_buf, "operation", op_masks,
operation, NAME_MASK_PIPE | NAME_MASK_NUMBER));
vstring_free(style_buf);
vstring_free(op_buf);
}
/* /*
* Sanity check. * Sanity check.
@ -139,13 +166,15 @@ int myflock(int fd, int lock_style, int operation)
default: default:
msg_panic("myflock: unsupported lock style: 0x%x", lock_style); msg_panic("myflock: unsupported lock style: 0x%x", lock_style);
} }
if (msg_verbose)
msg_info("myflock() returns %d", status);
/* /*
* Return a consistent result. Some systems return EACCES when a lock is * Return a consistent result. Some systems return EACCES when a lock is
* taken by someone else, and that would complicate error processing. * taken by someone else, and that would complicate error processing.
*/ */
if (status < 0 && (operation & MYFLOCK_OP_NOWAIT) != 0) if (status < 0 && (operation & MYFLOCK_OP_NOWAIT) != 0)
if (errno == EAGAIN || errno == EWOULDBLOCK || errno == EACCES) if (errno == EWOULDBLOCK || errno == EACCES)
errno = EAGAIN; errno = EAGAIN;
return (status); return (status);

View File

@ -0,0 +1,244 @@
/*++
/* NAME
/* ossl_digest 3
/* SUMMARY
/* OpenSSL message digest wrapper
/* SYNOPSIS
/* #define USE_TLS
/*
/* #include <ossl_digest.h>
/*
/* OSSL_DGST *ossl_digest_new(
/* const char *alg_name)
/*
/* int ossl_digest_data(
/* OSSL_DGST *dgst,
/* const void *data,
/* ssize_t data_len,
/* VSTRING *out);
/*
/* ARGV *ossl_digest_get_errors(void)
/*
/* ARGV *ossl_digest_log_errors(
/* void (*logger)(const char *,...))
/*
/* ssize_t ossl_digest_get_size(
/* OSSL_DGST *dgst)
/*
/* void ossl_digest_free(
/* OSSL_DGST *dgst)
/* DESCRIPTION
/* ossl_digest_new() allocates a wrapper for the named message
/* digest algorithm. This wrapper can be used in multiple successive
/* calls to compute a digest, and can be disposed of with
/* ossl_digest_free().
/*
/* ossl_digest_data() uses the specified message digest wrapper to
/* compute a digest over the specified data.
/*
/* ossl_digest_get_errors() dumps and clears the OpenSSL error stack.
/* Each stack entry is copied to one ARGV element. NOTE: The caller
/* should be prepared for the call to return an empty result,
/* and always report their own error info.
/*
/* ossl_digest_log_errors() logs and clears the OpenSSL error stack.
/* Each stack entry is logged by the specified function. NOTE:
/* The caller should be prepared for the call to return an empty
/* result, and log their own error message.
/*
/* ossl_digest_get_size() returns the output byte count for the
/* specified message digest wrapper.
/*
/* ossl_digest_free() releases storage allocated for or by the
/* specified message wrapper.
/* DIAGNOSTICS
/* Panic: ossl_digest_data() was called with an invalid data_len
/* argument; an ossl_digest_free() argument was not created with
/* ossl_digest_new().
/*
/* ossl_digest_new() returns NULL after error. ossl_digest_data()
/* returns 0 after success, -1 after error.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
#ifdef USE_TLS
/*
* System library.
*/
#include <sys_defs.h>
/*
* OpenSSL library.
*/
#include <openssl/err.h>
#include <openssl/evp.h>
/*
* Utility library.
*/
#include <msg.h>
#include <mymalloc.h>
#include <ossl_digest.h>
#include <vstring.h>
#ifndef OPENSSL_VERSION_PREREQ
#define OPENSSL_VERSION_PREREQ(m,n) 0
#endif
/*
* OpenSSL 1.1.1 compatibility crutches. Note: EVP_get_digestbyname()
* returns const EVP_MD * which can't be passed to EVP_MD_free(EVP_MD *).
*/
#if !OPENSSL_VERSION_PREREQ(3,0)
#define EVP_MD_fetch(ct, alg_name, pr) EVP_get_digestbyname(alg_name)
#define BC_CONST const
#define EVP_MD_free(m) /* */
#define EVP_MD_get_size EVP_MD_size
#else
#define BC_CONST /* */
#endif
/*
* Opaque object.
*/
struct OSSL_DGST {
EVP_MD_CTX *mdctx;
BC_CONST EVP_MD *dgst_alg;
};
/*
* SLMs.
*/
#define STR(x) vstring_str(x)
#define LEN(x) VSTRING_LEN(x)
/* ossl_digest_new - create OpenSSL digest wrapper */
OSSL_DGST *ossl_digest_new(const char *alg_name)
{
OSSL_DGST *dgst = (OSSL_DGST *) mymalloc(sizeof(*dgst));
/*
* https://docs.openssl.org/3.3/man7/ossl-guide-libcrypto-introduction
* "If you perform the same operation many times with the same algorithm
* then it is recommended to use a single explicit fetch of the algorithm
* and then reuse the explicitly fetched algorithm each subsequent time.
* This will typically be faster than implicitly fetching the algorithm
* every time you use it".
*
* That same text mentions that calling, for example, EVP_sha256(3), uses
* implicit fetching.
*/
if ((dgst->dgst_alg = EVP_MD_fetch(NULL, alg_name, NULL)) != 0) {
if ((dgst->mdctx = EVP_MD_CTX_new()) != 0) {
/* Success. */
return (dgst);
}
EVP_MD_free(dgst->dgst_alg);
}
/* Failure. */
myfree(dgst);
return (0);
}
/* ossl_digest_data - digest one data buffer */
int ossl_digest_data(OSSL_DGST *dgst, const void *data,
ssize_t data_len, VSTRING *out)
{
unsigned int out_len;
if (data_len < 0)
msg_panic("ossl_digest_data: bad data_len %ld", (long) data_len);
VSTRING_RESET(out);
VSTRING_SPACE(out, EVP_MD_get_size(dgst->dgst_alg));
if (EVP_DigestInit_ex(dgst->mdctx, dgst->dgst_alg, 0) != 1
|| EVP_DigestUpdate(dgst->mdctx, data, data_len) != 1
|| EVP_DigestFinal_ex(dgst->mdctx, (void *) STR(out),
&out_len) != 1)
return (-1);
vstring_set_payload_size(out, out_len);
return (0);
}
/* ossl_digest_get_size - determine digest output byte count */
ssize_t ossl_digest_get_size(OSSL_DGST *dgst)
{
return (EVP_MD_get_size(dgst->dgst_alg));
}
/* ossl_digest_get_errors - export and clear OpenSSL error stack */
ARGV *ossl_digest_get_errors(void)
{
ARGV *argv = argv_alloc(1);
VSTRING *tmp = vstring_alloc(100);
unsigned long err;
char buffer[1024]; /* XXX */
const char *file;
const char *data;
int line;
int flags;
/*
* Shamelessly copied from Postfix TLS library.
*/
#if OPENSSL_VERSION_PREREQ(3,0)
/* XXX: We're ignoring the function name, do we want to log it? */
#define ERRGET(fi, l, d, fl) ERR_get_error_all(fi, l, 0, d, fl)
#else
#define ERRGET(fi, l, d, fl) ERR_get_error_line_data(fi, l, d, fl)
#endif
while ((err = ERRGET(&file, &line, &data, &flags)) != 0) {
ERR_error_string_n(err, buffer, sizeof(buffer));
if (flags & ERR_TXT_STRING)
vstring_sprintf(tmp, "%s:%s:%d:%s:",
buffer, file, line, data);
else
vstring_sprintf(tmp, "%s:%s:%d:", buffer, file, line);
argv_add(argv, STR(tmp), (char *) 0);
}
vstring_free(tmp);
return (argv);
}
/* ossl_digest_log_errors - log and clear OpenSSL error stack */
void ossl_digest_log_errors(void (*logger)(const char *, ...))
{
unsigned long err;
char buffer[1024]; /* XXX */
const char *file;
const char *data;
int line;
int flags;
while ((err = ERRGET(&file, &line, &data, &flags)) != 0) {
ERR_error_string_n(err, buffer, sizeof(buffer));
if (flags & ERR_TXT_STRING)
logger("%s:%s:%d:%s:", buffer, file, line, data);
else
logger("%s:%s:%d:", buffer, file, line);
}
}
/* ossl_digest_free - dispose of digest wrapper */
void ossl_digest_free(OSSL_DGST *dgst)
{
EVP_MD_CTX_destroy(dgst->mdctx);
EVP_MD_free(dgst->dgst_alg);
myfree(dgst);
}
#endif /* USE_TLS */

View File

@ -0,0 +1,51 @@
#ifndef _OSSL_DIGEST_H_INCLUDED_
#define _OSSL_DIGEST_H_INCLUDED_
#ifdef USE_TLS
/*++
/* NAME
/* ossl_digest 3h
/* SUMMARY
/* OpenSSL message digest wrapper
/* SYNOPSIS
/* #include <ossl_digest.h>
/* DESCRIPTION
/* .nf
/*
* System library.
*/
#include <sys_defs.h>
/*
* Utility library.
*/
#include <argv.h>
#include <vstring.h>
/*
* External interface.
*/
typedef struct OSSL_DGST OSSL_DGST;
extern OSSL_DGST *ossl_digest_new(const char *);
extern int ossl_digest_data(OSSL_DGST *, const void *data, ssize_t data_len,
VSTRING *out);
extern ARGV *ossl_digest_get_errors(void);
extern void ossl_digest_log_errors(void (*logger) (const char *,...));
extern ssize_t ossl_digest_get_size(OSSL_DGST *);
extern void ossl_digest_free(OSSL_DGST *);
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
#endif /* USE_TLS */
#endif /* _OSSL_DIGEST_H_INCLUDED_ */

View File

@ -0,0 +1,204 @@
/*++
/* NAME
/* ossl_digest_test 1t
/* SUMMARY
/* ossl_digest unit tests
/* SYNOPSIS
/* ./ossl_digest_test
/* DESCRIPTION
/* ossl_digest_test runs and logs each configured test, reports if
/* a test is a PASS or FAIL, and returns an exit status of zero if
/* all tests are a PASS.
/* LICENSE
/* .ad
/* .fi
/* The Secure Mailer license must be distributed with this software.
/* AUTHOR(S)
/* Wietse Venema
/* porcupine.org
/*--*/
/*
* System library.
*/
#include <sys_defs.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
/*
* Utility library.
*/
#include <argv.h>
#include <hex_code.h>
#include <msg.h>
#include <mymalloc.h>
#include <ossl_digest.h>
#include <stringops.h>
#include <vstring.h>
#ifdef USE_TLS
#define LEN(x) VSTRING_LEN(x)
#define STR(x) vstring_str(x)
#define PASS 1
#define FAIL 0
/* get_error_string - return error info as one string */
static char *get_error_string(void)
{
VSTRING *err_string;
ARGV *err_list;
err_list = ossl_digest_get_errors();
err_string = vstring_alloc(100);
argv_join(err_string, err_list, '\n');
argv_free(err_list);
return (vstring_export(err_string));
}
static int reports_bad_digest_name(void)
{
const char *bad_digest_name = "doesnotexist";
OSSL_DGST *dgst;
int status = PASS;
if ((dgst = ossl_digest_new(bad_digest_name)) != 0) {
msg_warn("want: NULL, got: %p", (void *) dgst);
ossl_digest_free(dgst);
status = FAIL;
} else {
char *err_string;
err_string = get_error_string();
if (strstr(err_string, bad_digest_name) == 0) {
status = FAIL;
msg_warn("want: '%s', got: '%s'", bad_digest_name, err_string);
}
myfree(err_string);
}
return (status);
}
static int computes_sha256_digests(void)
{
OSSL_DGST *dgst;
struct DGST_TEST {
const char *in;
const char *want_hex;
};
static const struct DGST_TEST sha256_tests[] = {
{"",
"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
},
{"one",
"7692c3ad3540bb803c020b3aee66cd8887123234ea0c6e7143c0add73ff431ed",
},
{"two",
"3fc4ccfe745870e2c0d99f71f30ff0656c8dedd41cc1d7d3d376b0dbe685e2f3",
},
{0},
};
const struct DGST_TEST *dp;
int status = PASS;
if ((dgst = ossl_digest_new("sha256")) == 0) {
char *err_string = get_error_string();
msg_warn("want: noerror, got: '%s'", err_string);
myfree(err_string);
status = FAIL;
} else {
VSTRING *out = vstring_alloc(10);
VSTRING *got_hex = vstring_alloc(10);
for (dp = sha256_tests; dp->in != 0; dp++) {
if (ossl_digest_data(dgst, dp->in, strlen(dp->in), out) < 0) {
char *err_string = get_error_string();
msg_warn("want: noerror, got: '%s'", err_string);
myfree(err_string);
status = FAIL;
continue;
}
hex_encode(got_hex, STR(out), LEN(out));
lowercase(STR(got_hex));
if (strcmp(STR(got_hex), dp->want_hex) != 0) {
msg_warn("got: '%s', want: '%s'", STR(got_hex), dp->want_hex);
status = FAIL;
continue;
}
}
ossl_digest_free(dgst);
vstring_free(got_hex);
vstring_free(out);
}
return (status);
}
static int returns_sha256_output_size(void)
{
OSSL_DGST *dgst;
ssize_t got_size, want_size = 256 / 8;
int status = PASS;
if ((dgst = ossl_digest_new("sha256")) == 0) {
char *err_string;
err_string = get_error_string();
msg_warn("want: noerror, got: '%s'", err_string);
myfree(err_string);
status = FAIL;
} else {
if ((got_size = ossl_digest_get_size(dgst)) != want_size) {
msg_warn("want: %ld, got: %ld", (long) got_size, (long) want_size);
status = FAIL;
}
ossl_digest_free(dgst);
}
return (status);
}
struct TEST_CASE {
const char *label;
int (*action) (void);
};
static const struct TEST_CASE test_cases[] = {
{"reports_bad_digest_name", reports_bad_digest_name,},
/* TODO(wietse) test ossl_digest_log_errors() */
{"computes_sha256_digests", computes_sha256_digests,},
{"returns_sha256_output_size", returns_sha256_output_size,},
{0},
};
int main(int argc, char **argv)
{
static int tests_passed = 0;
static int tests_failed = 0;
const struct TEST_CASE *tp;
for (tp = test_cases; tp->label; tp++) {
msg_info("RUN %s", tp->label);
if (tp->action() == PASS) {
msg_info("PASS %s", tp->label);
tests_passed += 1;
} else {
msg_info("FAIL %s", tp->label);
tests_failed += 1;
}
}
msg_info("PASS=%d FAIL=%d", tests_passed, tests_failed);
exit(tests_failed != 0);
}
#else
int main(int argc, char **argv)
{
msg_fatal("this program requires `#define USE_TLS'");
}
#endif

View File

@ -481,14 +481,20 @@ static void verify_query_service(VSTREAM *client_stream)
/* FIX 200501 IPv6 patch did not neuter ":" in address literals. */ /* FIX 200501 IPv6 patch did not neuter ":" in address literals. */
translit(STR(addr), ":", "_"); translit(STR(addr), ":", "_");
if ((raw_data = dict_cache_lookup(verify_map, STR(addr))) == 0 /* not found */ raw_data = dict_cache_lookup(verify_map, STR(addr));
|| ((get_buf = vstring_alloc(10)), if (dict_cache_error(verify_map) != 0) {
vstring_strcpy(get_buf, raw_data), /* malformed */ addr_status = DEL_RCPT_STAT_DEFER;
verify_parse_entry(STR(get_buf), &addr_status, &probed, probed = 0;
&updated, &text) < 0) updated = 0;
|| (now - probed > PROBE_TTL /* safe to probe */ text = "Address verification status unavailable";
&& (POSITIVE_ENTRY_EXPIRED(addr_status, updated) } else if (raw_data == 0 /* not found */
|| NEGATIVE_ENTRY_EXPIRED(addr_status, updated)))) { || ((get_buf = vstring_alloc(10)),
vstring_strcpy(get_buf, raw_data), /* malformed */
verify_parse_entry(STR(get_buf), &addr_status, &probed,
&updated, &text) < 0)
|| (now - probed > PROBE_TTL /* safe to probe */
&& (POSITIVE_ENTRY_EXPIRED(addr_status, updated)
|| NEGATIVE_ENTRY_EXPIRED(addr_status, updated)))) {
addr_status = DEL_RCPT_STAT_TODO; addr_status = DEL_RCPT_STAT_TODO;
probed = 0; probed = 0;
updated = 0; updated = 0;
@ -525,7 +531,7 @@ static void verify_query_service(VSTREAM *client_stream)
#define NEGATIVE_REFRESH_NEEDED(addr_status, updated) \ #define NEGATIVE_REFRESH_NEEDED(addr_status, updated) \
(addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_try < now) (addr_status != DEL_RCPT_STAT_OK && updated + var_verify_neg_try < now)
if (now - probed > PROBE_TTL if (dict_cache_error(verify_map) == 0 && now - probed > PROBE_TTL
&& (POSITIVE_REFRESH_NEEDED(addr_status, updated) && (POSITIVE_REFRESH_NEEDED(addr_status, updated)
|| NEGATIVE_REFRESH_NEEDED(addr_status, updated))) { || NEGATIVE_REFRESH_NEEDED(addr_status, updated))) {
if (msg_verbose) if (msg_verbose)
@ -534,7 +540,7 @@ static void verify_query_service(VSTREAM *client_stream)
post_mail_fopen_async(make_verify_sender_addr(), STR(addr), post_mail_fopen_async(make_verify_sender_addr(), STR(addr),
MAIL_SRC_MASK_VERIFY, MAIL_SRC_MASK_VERIFY,
DEL_REQ_FLAG_MTA_VRFY, DEL_REQ_FLAG_MTA_VRFY,
/* TODO(wietse) disable REQUIRETLS? */ /* TODO(wietse) disable REQUIRETLS? */
SMTPUTF8_FLAG_NONE, SMTPUTF8_FLAG_NONE,
(VSTRING *) 0, (VSTRING *) 0,
verify_post_mail_action, verify_post_mail_action,