From 6e36f536307a2e3552459975b0f26dc129d00b06 Mon Sep 17 00:00:00 2001
From: Wietse Z Venema
Date: Wed, 29 Jan 2025 00:00:00 -0500
Subject: [PATCH] postfix-3.10-20250129-nonprod
---
postfix/HISTORY | 25 ++++---
postfix/html/lmtp.8.html | 7 ++
postfix/html/postconf.5.html | 102 ++++++++++++++++++++++++++-
postfix/html/smtp.8.html | 7 ++
postfix/man/man5/postconf.5 | 84 +++++++++++++++++++++-
postfix/man/man8/smtp.8 | 6 ++
postfix/mantools/postlink | 2 +
postfix/proto/postconf.proto | 94 +++++++++++++++++++++++-
postfix/proto/stop.spell-cc | 1 +
postfix/src/global/addr_match_list.c | 7 ++
postfix/src/global/domain_list.c | 7 ++
postfix/src/global/mail_params.h | 7 ++
postfix/src/global/mail_version.h | 2 +-
postfix/src/global/namadr_list.c | 7 ++
postfix/src/global/string_list.c | 7 ++
postfix/src/smtp/Makefile.in | 19 +++++
postfix/src/smtp/lmtp_params.c | 1 +
postfix/src/smtp/smtp.c | 27 +++++++
postfix/src/smtp/smtp.h | 3 +
postfix/src/smtp/smtp_connect.c | 50 +++++++++++--
postfix/src/smtp/smtp_params.c | 1 +
postfix/src/smtp/smtp_proto.c | 55 ++++++++++-----
postfix/src/smtp/smtp_state.c | 3 +
postfix/src/util/binhash.c | 3 +-
postfix/src/util/close_on_exec.c | 4 +-
postfix/src/util/match_list.c | 13 +++-
postfix/src/util/match_list.h | 6 +-
postfix/src/util/non_blocking.c | 4 +-
postfix/src/util/ring.c | 14 ++--
29 files changed, 508 insertions(+), 60 deletions(-)
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 19895a78c..913da047d 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -28959,20 +28959,29 @@ Apologies for any names omitted.
Completed: simplified cleanup_envelope_test implementation.
-TODO:
+20250127
- Add a log-only mode for REQUIRETLS, so that one can find out
- how much would break. Maybe make it a map, so that different
- sites can have different enforcement levels.
+ Cleanup: broken non-TLS builds because of a missing #ifdef
+ USE_TLS/#endif around a new function get_effective_tls_level().
+ File: smtp/smtp_connect.c.
- If we support log-only REQUIRETLS, then don't panic ("can't
- happen") when the code reaches a point that can't be reached
- when REQUIRETLS is actually enforced.
+ Cleanup: a few remaining pre-ANSI C function definitions
+ in the lowest-level Postfix code. Files: util/binhash.c,
+ util/close_on_exec.c, util/non_blocking.c, util/ring.c.
+
+20250129
+
+ Completed: smtp_enforce_requiretls list of next-hop domains
+ (or UNIX-domain pathnames) that are ready for REQUIRETLS
+ enforcement. This may help with gradual adoption.
+
+TODO
Encapsulate the sendopts-to-cleanup-flags mapping.
How do we make it work with multi-instance SMTP-based content
- filters? How is this different from the single-instance case?
+ filters? How is this different from the single-instance
+ case?
What REQUIRETLS expectations can we enforce when delivering
over a UNIX-domain channel? The SMTP/LMTP client currently
diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html
index 054c592fd..715a34ee9 100644
--- a/postfix/html/lmtp.8.html
+++ b/postfix/html/lmtp.8.html
@@ -765,6 +765,13 @@ SMTP(8) SMTP(8)
Enable support for the ESMTP verb "REQUIRETLS", defined in RFC
8689.
+ smtp_enforce_requiretls (empty)
+ An optional list of next-hop destinations that the Postfix
+ SMTP/LMTP client will enforce REQUIRETLS for, when a message was
+ received with the REQUIRETLS option: the next-hop server must
+ offer a matching TLS server certificate, and the server must
+ announce REQUIRETLS support).
+
OBSOLETE TLS CONTROLS
The following configuration parameters exist for compatibility with
Postfix versions before 2.3. Support for these will be removed in a
diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html
index 1150d0316..c755aaabf 100644
--- a/postfix/html/postconf.5.html
+++ b/postfix/html/postconf.5.html
@@ -5041,6 +5041,17 @@ configuration parameter. See there for details.
This feature is available in Postfix 2.11 and later.
+
+
+lmtp_enforce_requiretls
+(default: empty)
+
+ The LMTP-specific version of the smtp_enforce_requiretls
+configuration parameter. See there for details.
+
+ This feature is available in Postfix ≥ 3.10.
+
+
lmtp_enforce_tls
@@ -10585,7 +10596,16 @@ the smtp_mx_address_limit pa
satisfies requirements. Otherwise, Postfix returns the message as
undeliverable.
- Note: REQUIRETLS overrides "TLS-Required: no".
+ Notes:
+
+
This feature is available in Postfix ≥ 3.10.
@@ -11921,6 +11941,86 @@ RES_USE_DNSSEC and RES_USE_EDNS0 resolver options.
This feature is available in Postfix 2.11 and later.
+
+
+smtp_enforce_requiretls
+(default: empty)
+
+ An optional list of next-hop destinations that the Postfix
+SMTP/LMTP client will enforce REQUIRETLS for, when a message was
+received with the REQUIRETLS option: the next-hop server must offer
+a matching TLS server certificate, and the server must announce
+REQUIRETLS support). Such a message will be returned to the sender
+if some REQUIRETLS requirement cannot be satisfied. These "hard"
+REQUIRETLS failures are logged as "REQUIRETLS failure".
+
+ Other messages that were received with the REQUIRETLS option
+will be delivered with REQUIRETLS if possible. If not, a message
+will be delivered as if it was received without the REQUIRETLS
+option. This allows a mail sending site to discover when REQUIRETLS
+can be enforced, without disrupting email deliveries. These "soft"
+REQUIRETLS failures are logged with "REQUIRETLS Debug".
+
+ On a perimeter MTA, it can make sense to turn off REQUIRETLS
+enforcement, or even to turn off REQUIRETLS support, when delivering
+a message to an internal destination. The internal servers may not
+support REQUIRETLS, and their connections may be secured with means
+other than DANE, STS, and the like.
+
+ The supported syntax differs with SMTP and LMTP:
+
+
+
+-
With SMTP, specify a list of next-hop domain names (without
+the ":port" or ":service" suffix), "/file/name" patterns or
+"type:table" lookup tables, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace. A
+"/file/name" pattern is replaced by its contents; a "type:table"
+lookup table is matched when a domain appears as lookup key. Specify
+"!pattern" to exclude a domain from the list.
+
+ -
With LMTP, specify list of domain names (without the "inet":
+prefix, or ":port" or ":service" suffix), and/or UNIX-domain socket
+"/path/name" (without the "unix:" prefix), separated by commas
+and/or whitespace. Continue long lines by starting the next line
+with whitespace. Specify "!pattern" to exclude a pattern from the
+list.
+
+
+
+ By default, specify the form ".domain" to match any name ending
+in ".domain". This behavior is controlled by the presence or absence
+of "smtp_enforce_requiretls" or "lmtp_enforce_requiretls" in the
+parent_domain_matches_subdomains parameter value (by default they
+are absent).
+
+
+SMTP Examples:
+
+
+
+# Enforce REQUIRETLS for SMTP with selected next-hop domains.
+smtp_enforce_requiretls = example.com, foo.example
+
+# Enforce REQUIRETLS for SMTP with all but a few next-hop domains.
+smtp_enforce_requiretls = !foo.example, static:all
+
+
+
+LMTP examples:
+
+
+
+# Don't enforce REQUIRETLS
+lmtp_enforce_requiretls =
+
+# Enforce REQUIRETLS for specific destinations.
+lmtp_enforce_requiretls = /path/to/socket, message-store.example
+
+
+ This feature is available in Postfix ≥ 3.10.
+
+
smtp_enforce_tls
diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html
index 054c592fd..715a34ee9 100644
--- a/postfix/html/smtp.8.html
+++ b/postfix/html/smtp.8.html
@@ -765,6 +765,13 @@ SMTP(8) SMTP(8)
Enable support for the ESMTP verb "REQUIRETLS", defined in RFC
8689.
+ smtp_enforce_requiretls (empty)
+ An optional list of next-hop destinations that the Postfix
+ SMTP/LMTP client will enforce REQUIRETLS for, when a message was
+ received with the REQUIRETLS option: the next-hop server must
+ offer a matching TLS server certificate, and the server must
+ announce REQUIRETLS support).
+
OBSOLETE TLS CONTROLS
The following configuration parameters exist for compatibility with
Postfix versions before 2.3. Support for these will be removed in a
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index 502baddc6..3c66468c7 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -3136,6 +3136,11 @@ The LMTP\-specific version of the smtp_dns_support_level
configuration parameter. See there for details.
.PP
This feature is available in Postfix 2.11 and later.
+.SH lmtp_enforce_requiretls (default: empty)
+The LMTP\-specific version of the smtp_enforce_requiretls
+configuration parameter. See there for details.
+.PP
+This feature is available in Postfix >= 3.10.
.SH lmtp_enforce_tls (default: no)
The LMTP\-specific version of the smtp_enforce_tls configuration
parameter. See there for details.
@@ -6591,7 +6596,13 @@ the smtp_mx_address_limit parameter, until it finds a server that
satisfies requirements. Otherwise, Postfix returns the message as
undeliverable.
.PP
-Note: REQUIRETLS overrides "TLS\-Required: no".
+Notes:
+.IP \(bu
+REQUIRETLS enforcement is controlled with smtp_enforce_requiretls
+or lmtp_enforce_requiretls.
+.IP \(bu
+REQUIRETLS overrides "TLS\-Required: no".
+.br
.PP
This feature is available in Postfix >= 3.10.
.SH reset_owner_alias (default: no)
@@ -7528,6 +7539,77 @@ reasonably\-modern DNS \fBresolver\fR(3) library that implements the
RES_USE_DNSSEC and RES_USE_EDNS0 resolver options.
.PP
This feature is available in Postfix 2.11 and later.
+.SH smtp_enforce_requiretls (default: empty)
+An optional list of next\-hop destinations that the Postfix
+SMTP/LMTP client will enforce REQUIRETLS for, when a message was
+received with the REQUIRETLS option: the next\-hop server must offer
+a matching TLS server certificate, and the server must announce
+REQUIRETLS support). Such a message will be returned to the sender
+if some REQUIRETLS requirement cannot be satisfied. These "hard"
+REQUIRETLS failures are logged as "REQUIRETLS failure".
+.PP
+Other messages that were received with the REQUIRETLS option
+will be delivered with REQUIRETLS if possible. If not, a message
+will be delivered as if it was received without the REQUIRETLS
+option. This allows a mail sending site to discover when REQUIRETLS
+can be enforced, without disrupting email deliveries. These "soft"
+REQUIRETLS failures are logged with "REQUIRETLS Debug".
+.PP
+On a perimeter MTA, it can make sense to turn off REQUIRETLS
+enforcement, or even to turn off REQUIRETLS support, when delivering
+a message to an internal destination. The internal servers may not
+support REQUIRETLS, and their connections may be secured with means
+other than DANE, STS, and the like.
+.PP
+The supported syntax differs with SMTP and LMTP:
+.IP \(bu
+With SMTP, specify a list of next\-hop domain names (without
+the ":port" or ":service" suffix), "/file/name" patterns or
+"type:table" lookup tables, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace. A
+"/file/name" pattern is replaced by its contents; a "type:table"
+lookup table is matched when a domain appears as lookup key. Specify
+"!pattern" to exclude a domain from the list.
+.IP \(bu
+With LMTP, specify list of domain names (without the "inet":
+prefix, or ":port" or ":service" suffix), and/or UNIX\-domain socket
+"/path/name" (without the "unix:" prefix), separated by commas
+and/or whitespace. Continue long lines by starting the next line
+with whitespace. Specify "!pattern" to exclude a pattern from the
+list.
+.br
+.PP
+By default, specify the form ".domain" to match any name ending
+in ".domain". This behavior is controlled by the presence or absence
+of "smtp_enforce_requiretls" or "lmtp_enforce_requiretls" in the
+parent_domain_matches_subdomains parameter value (by default they
+are absent).
+.PP
+SMTP Examples:
+.PP
+.nf
+.na
+# Enforce REQUIRETLS for SMTP with selected next\-hop domains.
+smtp_enforce_requiretls = example.com, foo.example
+.br
+# Enforce REQUIRETLS for SMTP with all but a few next\-hop domains.
+smtp_enforce_requiretls = !foo.example, static:all
+.fi
+.ad
+.PP
+LMTP examples:
+.PP
+.nf
+.na
+# Don't enforce REQUIRETLS
+lmtp_enforce_requiretls =
+.br
+# Enforce REQUIRETLS for specific destinations.
+lmtp_enforce_requiretls = /path/to/socket, message\-store.example
+.fi
+.ad
+.PP
+This feature is available in Postfix >= 3.10.
.SH smtp_enforce_tls (default: no)
Enforcement mode: require that remote SMTP servers use TLS
encryption, and never send mail in the clear. This also requires
diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8
index a4a343a2f..9f5f726ca 100644
--- a/postfix/man/man8/smtp.8
+++ b/postfix/man/man8/smtp.8
@@ -687,6 +687,12 @@ information to report).
.IP "\fBrequiretls_enable (yes)\fR"
Enable support for the ESMTP verb "REQUIRETLS", defined in RFC
8689.
+.IP "\fBsmtp_enforce_requiretls (empty)\fR"
+An optional list of next\-hop destinations that the Postfix
+SMTP/LMTP client will enforce REQUIRETLS for, when a message was
+received with the REQUIRETLS option: the next\-hop server must offer
+a matching TLS server certificate, and the server must announce
+REQUIRETLS support).
.SH "OBSOLETE TLS CONTROLS"
.na
.nf
diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink
index c2fb9b476..8cd3fe4d4 100755
--- a/postfix/mantools/postlink
+++ b/postfix/mantools/postlink
@@ -1188,6 +1188,8 @@ while (<>) {
s;\btls_required_enable\b;$&;g;
s;\brequiretls_enable\b;$&;g;
+ s;\bsmtp_enforce_requiretls\b;$&;g;
+ s;\blmtp_enforce_requiretls\b;$&;g;
s;\bfull_name_encoding_charset\b;$&;g;
diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto
index d9b191878..674c6dde9 100644
--- a/postfix/proto/postconf.proto
+++ b/postfix/proto/postconf.proto
@@ -19501,6 +19501,98 @@ the smtp_mx_address_limit parameter, until it finds a server that
satisfies requirements. Otherwise, Postfix returns the message as
undeliverable.
- Note: REQUIRETLS overrides "TLS-Required: no".
+ Notes:
+
+
+
+ This feature is available in Postfix ≥ 3.10.
+
+%PARAM smtp_enforce_requiretls empty
+
+ An optional list of next-hop destinations that the Postfix
+SMTP/LMTP client will enforce REQUIRETLS for, when a message was
+received with the REQUIRETLS option: the next-hop server must offer
+a matching TLS server certificate, and the server must announce
+REQUIRETLS support). Such a message will be returned to the sender
+if some REQUIRETLS requirement cannot be satisfied. These "hard"
+REQUIRETLS failures are logged as "REQUIRETLS failure".
+
+ Other messages that were received with the REQUIRETLS option
+will be delivered with REQUIRETLS if possible. If not, a message
+will be delivered as if it was received without the REQUIRETLS
+option. This allows a mail sending site to discover when REQUIRETLS
+can be enforced, without disrupting email deliveries. These "soft"
+REQUIRETLS failures are logged with "REQUIRETLS Debug".
+
+ On a perimeter MTA, it can make sense to turn off REQUIRETLS
+enforcement, or even to turn off REQUIRETLS support, when delivering
+a message to an internal destination. The internal servers may not
+support REQUIRETLS, and their connections may be secured with means
+other than DANE, STS, and the like.
+
+ The supported syntax differs with SMTP and LMTP:
+
+
+
+-
With SMTP, specify a list of next-hop domain names (without
+the ":port" or ":service" suffix), "/file/name" patterns or
+"type:table" lookup tables, separated by commas and/or whitespace.
+Continue long lines by starting the next line with whitespace. A
+"/file/name" pattern is replaced by its contents; a "type:table"
+lookup table is matched when a domain appears as lookup key. Specify
+"!pattern" to exclude a domain from the list.
+
+ -
With LMTP, specify list of domain names (without the "inet":
+prefix, or ":port" or ":service" suffix), and/or UNIX-domain socket
+"/path/name" (without the "unix:" prefix), separated by commas
+and/or whitespace. Continue long lines by starting the next line
+with whitespace. Specify "!pattern" to exclude a pattern from the
+list.
+
+
+
+ By default, specify the form ".domain" to match any name ending
+in ".domain". This behavior is controlled by the presence or absence
+of "smtp_enforce_requiretls" or "lmtp_enforce_requiretls" in the
+parent_domain_matches_subdomains parameter value (by default they
+are absent).
+
+
+SMTP Examples:
+
+
+
+# Enforce REQUIRETLS for SMTP with selected next-hop domains.
+smtp_enforce_requiretls = example.com, foo.example
+
+# Enforce REQUIRETLS for SMTP with all but a few next-hop domains.
+smtp_enforce_requiretls = !foo.example, static:all
+
+
+
+LMTP examples:
+
+
+
+# Don't enforce REQUIRETLS
+lmtp_enforce_requiretls =
+
+# Enforce REQUIRETLS for specific destinations.
+lmtp_enforce_requiretls = /path/to/socket, message-store.example
+
+
+ This feature is available in Postfix ≥ 3.10.
+
+%PARAM lmtp_enforce_requiretls empty
+
+ The LMTP-specific version of the smtp_enforce_requiretls
+configuration parameter. See there for details.
This feature is available in Postfix ≥ 3.10.
diff --git a/postfix/proto/stop.spell-cc b/postfix/proto/stop.spell-cc
index 34e439196..c8fffdf36 100644
--- a/postfix/proto/stop.spell-cc
+++ b/postfix/proto/stop.spell-cc
@@ -1858,3 +1858,4 @@ TINYCDB
getdata
XXXSENDOPTS
xtra
+NODICT
diff --git a/postfix/src/global/addr_match_list.c b/postfix/src/global/addr_match_list.c
index 8008df203..136ce24b5 100644
--- a/postfix/src/global/addr_match_list.c
+++ b/postfix/src/global/addr_match_list.c
@@ -42,6 +42,10 @@
/* Request that addr_match_list_match() logs a warning and
/* returns zero with list->error set to a non-zero dictionary
/* error code, instead of raising a fatal error.
+/* .IP MATCH_FLAG_NOFILE
+/* Disable special handling for /file/name.
+/* .IP MATCH_FLAG_NODICT
+/* Disable special handling for type:name.
/* .PP
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The last argument is a list of patterns, or the absolute
@@ -67,6 +71,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
diff --git a/postfix/src/global/domain_list.c b/postfix/src/global/domain_list.c
index d79beafd3..e3fe1caec 100644
--- a/postfix/src/global/domain_list.c
+++ b/postfix/src/global/domain_list.c
@@ -45,6 +45,10 @@
/* Request that domain_list_match() logs a warning and returns
/* zero, with list->error set to a non-zero dictionary error
/* code, instead of raising a fatal error.
+/* .IP MATCH_FLAG_NOFILE
+/* Disable special handling for /file/name.
+/* .IP MATCH_FLAG_NODICT
+/* Disable special handling for type:name.
/* .PP
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The last argument is a list of domain patterns, or the name of
@@ -69,6 +73,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h
index fc0b7a5f6..6a0417169 100644
--- a/postfix/src/global/mail_params.h
+++ b/postfix/src/global/mail_params.h
@@ -4387,6 +4387,13 @@ extern int var_requiretls_enable;
#define DEF_TLSREQUIRED_ENABLE "yes"
extern int var_tls_required_enable;
+#define VAR_SMTP_ENFORCE_REQUIRETLS "smtp_enforce_requiretls"
+#define DEF_SMTP_ENFORCE_REQUIRETLS ""
+extern char *var_smtp_enforce_requiretls;
+
+#define VAR_LMTP_ENFORCE_REQUIRETLS "lmtp_enforce_requiretls"
+#define DEF_LMTP_ENFORCE_REQUIRETLS ""
+
/*
* Workaround for future incompatibility. Our implementation of RFC 2308
* negative reply caching relies on the promise that res_query() and
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index f2675f1fd..41df81ba5 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20250126"
+#define MAIL_RELEASE_DATE "20250129"
#define MAIL_VERSION_NUMBER "3.10"
#ifdef SNAPSHOT
diff --git a/postfix/src/global/namadr_list.c b/postfix/src/global/namadr_list.c
index 071a73341..0a9a9054f 100644
--- a/postfix/src/global/namadr_list.c
+++ b/postfix/src/global/namadr_list.c
@@ -51,6 +51,10 @@
/* Request that namadr_list_match() logs a warning and returns
/* zero with list->error set to a non-zero dictionary error
/* code, instead of raising a fatal error.
+/* .IP MATCH_FLAG_NOFILE
+/* Disable special handling for /file/name.
+/* .IP MATCH_FLAG_NODICT
+/* Disable special handling for type:name.
/* .PP
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The last argument is a list of patterns, or the absolute
@@ -75,6 +79,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
diff --git a/postfix/src/global/string_list.c b/postfix/src/global/string_list.c
index ddd950a00..88a43fb1b 100644
--- a/postfix/src/global/string_list.c
+++ b/postfix/src/global/string_list.c
@@ -39,6 +39,10 @@
/* Request that string_list_match() logs a warning and returns
/* zero with list->error set to a non-zero dictionary error
/* code, instead of raising a fatal error.
+/* .IP MATCH_FLAG_NOFILE
+/* Disable special handling for /file/name.
+/* .IP MATCH_FLAG_NODICT
+/* Disable special handling for type:name.
/* .PP
/* Specify MATCH_FLAG_NONE to request none of the above.
/* The last argument specifies a list of string patterns.
@@ -61,6 +65,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
diff --git a/postfix/src/smtp/Makefile.in b/postfix/src/smtp/Makefile.in
index 44add46b2..801e7ee0e 100644
--- a/postfix/src/smtp/Makefile.in
+++ b/postfix/src/smtp/Makefile.in
@@ -84,6 +84,7 @@ smtp.o: ../../include/deliver_request.h
smtp.o: ../../include/delivered_hdr.h
smtp.o: ../../include/dict.h
smtp.o: ../../include/dns.h
+smtp.o: ../../include/domain_list.h
smtp.o: ../../include/dsn.h
smtp.o: ../../include/dsn_buf.h
smtp.o: ../../include/ext_prop.h
@@ -134,6 +135,7 @@ smtp_addr.o: ../../include/check_arg.h
smtp_addr.o: ../../include/deliver_request.h
smtp_addr.o: ../../include/dict.h
smtp_addr.o: ../../include/dns.h
+smtp_addr.o: ../../include/domain_list.h
smtp_addr.o: ../../include/dsn.h
smtp_addr.o: ../../include/dsn_buf.h
smtp_addr.o: ../../include/header_body_checks.h
@@ -178,6 +180,7 @@ smtp_chat.o: ../../include/cleanup_user.h
smtp_chat.o: ../../include/deliver_request.h
smtp_chat.o: ../../include/dict.h
smtp_chat.o: ../../include/dns.h
+smtp_chat.o: ../../include/domain_list.h
smtp_chat.o: ../../include/dsn.h
smtp_chat.o: ../../include/dsn_buf.h
smtp_chat.o: ../../include/dsn_util.h
@@ -229,6 +232,7 @@ smtp_connect.o: ../../include/deliver_pass.h
smtp_connect.o: ../../include/deliver_request.h
smtp_connect.o: ../../include/dict.h
smtp_connect.o: ../../include/dns.h
+smtp_connect.o: ../../include/domain_list.h
smtp_connect.o: ../../include/dsn.h
smtp_connect.o: ../../include/dsn_buf.h
smtp_connect.o: ../../include/header_body_checks.h
@@ -284,6 +288,7 @@ smtp_key.o: ../../include/check_arg.h
smtp_key.o: ../../include/deliver_request.h
smtp_key.o: ../../include/dict.h
smtp_key.o: ../../include/dns.h
+smtp_key.o: ../../include/domain_list.h
smtp_key.o: ../../include/dsn.h
smtp_key.o: ../../include/dsn_buf.h
smtp_key.o: ../../include/header_body_checks.h
@@ -321,6 +326,7 @@ smtp_map11.o: ../../include/check_arg.h
smtp_map11.o: ../../include/deliver_request.h
smtp_map11.o: ../../include/dict.h
smtp_map11.o: ../../include/dns.h
+smtp_map11.o: ../../include/domain_list.h
smtp_map11.o: ../../include/dsn.h
smtp_map11.o: ../../include/dsn_buf.h
smtp_map11.o: ../../include/header_body_checks.h
@@ -361,6 +367,7 @@ smtp_misc.o: ../../include/check_arg.h
smtp_misc.o: ../../include/deliver_request.h
smtp_misc.o: ../../include/dict.h
smtp_misc.o: ../../include/dns.h
+smtp_misc.o: ../../include/domain_list.h
smtp_misc.o: ../../include/dsn.h
smtp_misc.o: ../../include/dsn_buf.h
smtp_misc.o: ../../include/ext_prop.h
@@ -404,6 +411,7 @@ smtp_proto.o: ../../include/defer.h
smtp_proto.o: ../../include/deliver_request.h
smtp_proto.o: ../../include/dict.h
smtp_proto.o: ../../include/dns.h
+smtp_proto.o: ../../include/domain_list.h
smtp_proto.o: ../../include/dsn.h
smtp_proto.o: ../../include/dsn_buf.h
smtp_proto.o: ../../include/dsn_mask.h
@@ -470,6 +478,7 @@ smtp_rcpt.o: ../../include/deliver_completed.h
smtp_rcpt.o: ../../include/deliver_request.h
smtp_rcpt.o: ../../include/dict.h
smtp_rcpt.o: ../../include/dns.h
+smtp_rcpt.o: ../../include/domain_list.h
smtp_rcpt.o: ../../include/dsn.h
smtp_rcpt.o: ../../include/dsn_buf.h
smtp_rcpt.o: ../../include/dsn_mask.h
@@ -510,6 +519,7 @@ smtp_reuse.o: ../../include/check_arg.h
smtp_reuse.o: ../../include/deliver_request.h
smtp_reuse.o: ../../include/dict.h
smtp_reuse.o: ../../include/dns.h
+smtp_reuse.o: ../../include/domain_list.h
smtp_reuse.o: ../../include/dsn.h
smtp_reuse.o: ../../include/dsn_buf.h
smtp_reuse.o: ../../include/header_body_checks.h
@@ -551,6 +561,7 @@ smtp_sasl_auth_cache.o: ../../include/deliver_request.h
smtp_sasl_auth_cache.o: ../../include/dict.h
smtp_sasl_auth_cache.o: ../../include/dict_proxy.h
smtp_sasl_auth_cache.o: ../../include/dns.h
+smtp_sasl_auth_cache.o: ../../include/domain_list.h
smtp_sasl_auth_cache.o: ../../include/dsn.h
smtp_sasl_auth_cache.o: ../../include/dsn_buf.h
smtp_sasl_auth_cache.o: ../../include/dsn_util.h
@@ -591,6 +602,7 @@ smtp_sasl_glue.o: ../../include/check_arg.h
smtp_sasl_glue.o: ../../include/deliver_request.h
smtp_sasl_glue.o: ../../include/dict.h
smtp_sasl_glue.o: ../../include/dns.h
+smtp_sasl_glue.o: ../../include/domain_list.h
smtp_sasl_glue.o: ../../include/dsn.h
smtp_sasl_glue.o: ../../include/dsn_buf.h
smtp_sasl_glue.o: ../../include/header_body_checks.h
@@ -636,6 +648,7 @@ smtp_sasl_proto.o: ../../include/check_arg.h
smtp_sasl_proto.o: ../../include/deliver_request.h
smtp_sasl_proto.o: ../../include/dict.h
smtp_sasl_proto.o: ../../include/dns.h
+smtp_sasl_proto.o: ../../include/domain_list.h
smtp_sasl_proto.o: ../../include/dsn.h
smtp_sasl_proto.o: ../../include/dsn_buf.h
smtp_sasl_proto.o: ../../include/header_body_checks.h
@@ -677,6 +690,7 @@ smtp_session.o: ../../include/debug_peer.h
smtp_session.o: ../../include/deliver_request.h
smtp_session.o: ../../include/dict.h
smtp_session.o: ../../include/dns.h
+smtp_session.o: ../../include/domain_list.h
smtp_session.o: ../../include/dsn.h
smtp_session.o: ../../include/dsn_buf.h
smtp_session.o: ../../include/header_body_checks.h
@@ -717,6 +731,7 @@ smtp_state.o: ../../include/debug_peer.h
smtp_state.o: ../../include/deliver_request.h
smtp_state.o: ../../include/dict.h
smtp_state.o: ../../include/dns.h
+smtp_state.o: ../../include/domain_list.h
smtp_state.o: ../../include/dsn.h
smtp_state.o: ../../include/dsn_buf.h
smtp_state.o: ../../include/header_body_checks.h
@@ -757,6 +772,7 @@ smtp_tls_policy.o: ../../include/ctable.h
smtp_tls_policy.o: ../../include/deliver_request.h
smtp_tls_policy.o: ../../include/dict.h
smtp_tls_policy.o: ../../include/dns.h
+smtp_tls_policy.o: ../../include/domain_list.h
smtp_tls_policy.o: ../../include/dsn.h
smtp_tls_policy.o: ../../include/dsn_buf.h
smtp_tls_policy.o: ../../include/header_body_checks.h
@@ -799,6 +815,7 @@ smtp_tlsrpt.o: ../../include/check_arg.h
smtp_tlsrpt.o: ../../include/deliver_request.h
smtp_tlsrpt.o: ../../include/dict.h
smtp_tlsrpt.o: ../../include/dns.h
+smtp_tlsrpt.o: ../../include/domain_list.h
smtp_tlsrpt.o: ../../include/dsn.h
smtp_tlsrpt.o: ../../include/dsn_buf.h
smtp_tlsrpt.o: ../../include/header_body_checks.h
@@ -843,6 +860,7 @@ smtp_trouble.o: ../../include/deliver_completed.h
smtp_trouble.o: ../../include/deliver_request.h
smtp_trouble.o: ../../include/dict.h
smtp_trouble.o: ../../include/dns.h
+smtp_trouble.o: ../../include/domain_list.h
smtp_trouble.o: ../../include/dsn.h
smtp_trouble.o: ../../include/dsn_buf.h
smtp_trouble.o: ../../include/header_body_checks.h
@@ -884,6 +902,7 @@ smtp_unalias.o: ../../include/check_arg.h
smtp_unalias.o: ../../include/deliver_request.h
smtp_unalias.o: ../../include/dict.h
smtp_unalias.o: ../../include/dns.h
+smtp_unalias.o: ../../include/domain_list.h
smtp_unalias.o: ../../include/dsn.h
smtp_unalias.o: ../../include/dsn_buf.h
smtp_unalias.o: ../../include/header_body_checks.h
diff --git a/postfix/src/smtp/lmtp_params.c b/postfix/src/smtp/lmtp_params.c
index b77500326..8dfc5ace9 100644
--- a/postfix/src/smtp/lmtp_params.c
+++ b/postfix/src/smtp/lmtp_params.c
@@ -68,6 +68,7 @@
VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
VAR_USE_SRV_LOOKUP, DEF_USE_SRV_LOOKUP, &var_use_srv_lookup, 0, 0,
VAR_LMTP_TLSRPT_SOCKNAME, DEF_LMTP_TLSRPT_SOCKNAME, &var_smtp_tlsrpt_sockname, 0, 0,
+ VAR_LMTP_ENFORCE_REQUIRETLS, DEF_LMTP_ENFORCE_REQUIRETLS, &var_smtp_enforce_requiretls, 0, 0,
0,
};
static const CONFIG_TIME_TABLE lmtp_time_table[] = {
diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c
index 597cc105a..fbaa452a4 100644
--- a/postfix/src/smtp/smtp.c
+++ b/postfix/src/smtp/smtp.c
@@ -653,6 +653,12 @@
/* .IP "\fBrequiretls_enable (yes)\fR"
/* Enable support for the ESMTP verb "REQUIRETLS", defined in RFC
/* 8689.
+/* .IP "\fBsmtp_enforce_requiretls (empty)\fR"
+/* An optional list of next-hop destinations that the Postfix
+/* SMTP/LMTP client will enforce REQUIRETLS for, when a message was
+/* received with the REQUIRETLS option: the next-hop server must offer
+/* a matching TLS server certificate, and the server must announce
+/* REQUIRETLS support).
/* OBSOLETE TLS CONTROLS
/* .ad
/* .fi
@@ -1020,6 +1026,8 @@
#include
#include
#include
+#include
+#include
/* DNS library. */
@@ -1164,6 +1172,7 @@ bool var_allow_srv_fallback;
bool var_smtp_tlsrpt_enable;
char *var_smtp_tlsrpt_sockname;
bool var_smtp_tlsrpt_skip_reused_hs;
+char *var_smtp_enforce_requiretls;
/* Special handling of 535 AUTH errors. */
char *var_smtp_sasl_auth_cache_name;
@@ -1191,6 +1200,7 @@ HBC_CHECKS *smtp_body_checks; /* limited body checks */
SMTP_CLI_ATTR smtp_cli_attr; /* parsed command-line */
int smtp_hfrom_format; /* postmaster notifications */
STRING_LIST *smtp_use_srv_lookup;
+DOMAIN_LIST *smtp_enforce_requiretls;
#ifdef USE_TLS
@@ -1692,6 +1702,23 @@ static void pre_init(char *unused_name, char **unused_argv)
if (*var_smtp_dns_re_filter)
dns_rr_filter_compile(VAR_LMTP_SMTP(DNS_RE_FILTER),
var_smtp_dns_re_filter);
+
+ /*
+ * REQUIRETLS enforcement uses a match list. No MATCH_FLAG_RETURN after
+ * table lookup error, because fail-open is not a good option. We would
+ * have to defer all delivery requests anyway. Disable magic syntax for
+ * LMTP, because the syntax would interfere with UNIX-domain socket
+ * pathnames.
+ */
+ if (var_requiretls_enable && *var_smtp_enforce_requiretls) {
+ int flags = smtp_mode ? 0 : (MATCH_FLAG_NOFILE | MATCH_FLAG_NODICT);
+ const char *param_name = VAR_LMTP_SMTP(ENFORCE_REQUIRETLS);
+
+ smtp_enforce_requiretls =
+ string_list_init(param_name,
+ match_parent_style(param_name) | flags,
+ var_smtp_enforce_requiretls);
+ }
}
/* pre_accept - see if tables have changed */
diff --git a/postfix/src/smtp/smtp.h b/postfix/src/smtp/smtp.h
index 9dc8c70cf..9f36daeec 100644
--- a/postfix/src/smtp/smtp.h
+++ b/postfix/src/smtp/smtp.h
@@ -32,6 +32,7 @@
#include
#include
#include
+#include
/*
* Postfix TLS library.
@@ -200,6 +201,7 @@ typedef struct SMTP_STATE {
#ifdef USE_TLSRPT
struct TLSRPT_WRAPPER *tlsrpt;
#endif
+ int enforce_requiretls; /* from smtp_enforce_requiretls */
#endif
/*
@@ -359,6 +361,7 @@ extern STRING_LIST *smtp_use_srv_lookup;/* services with SRV record lookup */
extern TLS_APPL_STATE *smtp_tls_ctx; /* client-side TLS engine */
extern int smtp_tls_insecure_mx_policy; /* DANE post insecure MX? */
+extern DOMAIN_LIST *smtp_enforce_requiretls; /* parsed list */
#endif
diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c
index 72abf67c8..c7524a69a 100644
--- a/postfix/src/smtp/smtp_connect.c
+++ b/postfix/src/smtp/smtp_connect.c
@@ -106,6 +106,7 @@
#include
#include
#include
+#include
/* DNS library. */
@@ -521,13 +522,24 @@ static int smtp_get_effective_tls_level(DSN_BUF *why, SMTP_STATE *state)
else if (var_requiretls_enable
&& (state->request->sendopts & SOPT_REQUIRETLS_ESMTP)) {
if (TLS_MUST_MATCH(tls->level) == 0) {
- dsb_simple(why, "5.7.10", "Sender requires a TLS server "
- "certificate match, but the configured %s TLS "
- "security level '%s' does not support that. "
- "The last attempted server was %s",
- var_mail_name, str_tls_level(tls->level),
- STR(iter->host));
- return (0);
+ if (state->enforce_requiretls) {
+ dsb_simple(why, "5.7.10", "REQUIRETLS Failure: Sender "
+ "requires a TLS server certificate match, "
+ "but the configured %s TLS security level '%s' "
+ "does not support that. The last attempted "
+ "server was %s",
+ var_mail_name, str_tls_level(tls->level),
+ STR(iter->host));
+ return (0);
+ } else {
+ msg_info("REQUIRETLS Debug: Sender requires a TLS server "
+ "certificate match, but the configured %s TLS "
+ "security level '%s' does not support that. "
+ "The last attempted server was %s",
+ var_mail_name, str_tls_level(tls->level),
+ STR(iter->host));
+ return (0);
+ }
}
}
@@ -576,6 +588,18 @@ static void smtp_connect_local(SMTP_STATE *state, const char *path)
if (state->misc_flags & SMTP_MISC_FLAG_CONN_CACHE_MASK)
SET_SCACHE_REQUEST_NEXTHOP(state, path);
+ /*
+ * REQUIRETLS enforcement is based on the UNIX-domain pathname, without
+ * the "unix:" prefix.
+ */
+#ifdef USE_TLS
+ state->enforce_requiretls =
+ (var_requiretls_enable
+ && smtp_enforce_requiretls
+ && (state->request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0
+ && domain_list_match(smtp_enforce_requiretls, path));
+#endif
+
/*
* Here we ensure that the iter->addr member refers to a copy of the
* UNIX-domain pathname, so that smtp_save_session() will cache the
@@ -980,6 +1004,18 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
state->tlsrpt = 0;
#endif /* USE_TLSRPT */
+ /*
+ * REQUIRETLS enforcement is based on the next-hop domain name
+ * without the service or port.
+ */
+#ifdef USE_TLS
+ state->enforce_requiretls =
+ (var_requiretls_enable
+ && smtp_enforce_requiretls
+ && (state->request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0
+ && domain_list_match(smtp_enforce_requiretls, domain));
+#endif
+
/*
* Resolve an SMTP or LMTP server. Skip MX or SRV lookups when a
* quoted domain is specified or when DNS lookups are disabled.
diff --git a/postfix/src/smtp/smtp_params.c b/postfix/src/smtp/smtp_params.c
index 6d80ef105..65940a61a 100644
--- a/postfix/src/smtp/smtp_params.c
+++ b/postfix/src/smtp/smtp_params.c
@@ -69,6 +69,7 @@
VAR_HFROM_FORMAT, DEF_HFROM_FORMAT, &var_hfrom_format, 1, 0,
VAR_USE_SRV_LOOKUP, DEF_USE_SRV_LOOKUP, &var_use_srv_lookup, 0, 0,
VAR_SMTP_TLSRPT_SOCKNAME, DEF_SMTP_TLSRPT_SOCKNAME, &var_smtp_tlsrpt_sockname, 0, 0,
+ VAR_SMTP_ENFORCE_REQUIRETLS, DEF_SMTP_ENFORCE_REQUIRETLS, &var_smtp_enforce_requiretls, 0, 0,
0,
};
static const CONFIG_TIME_TABLE smtp_time_table[] = {
diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c
index 1c7ca195b..2f71a926a 100644
--- a/postfix/src/smtp/smtp_proto.c
+++ b/postfix/src/smtp/smtp_proto.c
@@ -693,15 +693,24 @@ int smtp_helo(SMTP_STATE *state)
if (var_requiretls_enable
&& (request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0
&& (state->misc_flags & SMTP_MISC_FLAG_IN_STARTTLS) != 0
- && (session->features & SMTP_FEATURE_REQUIRETLS) == 0)
- return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
- DSN_BY_LOCAL_MTA,
- SMTP_RESP_FAKE(&fake, "5.7.30"),
- "Sender requested delivery wth "
- "REQUIRETLS, but no mail server was "
- "found with REQUIRETLS support. The "
- "last attempted server was %s",
- session->namaddr));
+ && (session->features & SMTP_FEATURE_REQUIRETLS) == 0) {
+ if (state->enforce_requiretls) {
+ return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
+ DSN_BY_LOCAL_MTA,
+ SMTP_RESP_FAKE(&fake, "5.7.30"),
+ "REQUIRETLS Failure: Sender requested "
+ "delivery wth REQUIRETLS, but no mail "
+ "server was found with REQUIRETLS "
+ "support. The last attempted server "
+ "was %s", session->namaddr));
+ } else {
+ msg_info("REQUIRETLS Debug: Sender requested delivery wth "
+ "REQUIRETLS, but no mail server was found with "
+ "REQUIRETLS support. The last attempted server was "
+ "%s", session->namaddr);
+ }
+
+ }
#endif
/*
@@ -1221,14 +1230,22 @@ static int smtp_start_tls(SMTP_STATE *state)
*/
if (var_requiretls_enable
&& (state->request->sendopts & SOPT_REQUIRETLS_ESMTP)) {
- return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
- DSN_BY_LOCAL_MTA,
- SMTP_RESP_FAKE(&fake, "5.7.10"),
- "Sender requires a TLS server "
- "certificate match, but no matching "
- "mail server was found. The last "
- "attempted server was %s",
- session->namaddr));
+ if (state->enforce_requiretls) {
+ return (smtp_misc_fail(state, SMTP_MISC_FAIL_SOFT_NON_FINAL,
+ DSN_BY_LOCAL_MTA,
+ SMTP_RESP_FAKE(&fake, "5.7.10"),
+ "REQUIRETLS Failure: Sender "
+ "requested a TLS server "
+ "certificate match, but no "
+ "match was found. The last "
+ "attempted server was %s",
+ session->namaddr));
+ } else {
+ msg_info("REQUIRETLS Debug: Sender requested a TLS "
+ "server certificate match, but no match was "
+ "found. The last attempted server was %s",
+ session->namaddr);
+ }
}
return (smtp_site_fail(state, DSN_BY_LOCAL_MTA,
SMTP_RESP_FAKE(&fake, "4.7.5"),
@@ -1830,8 +1847,8 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
&& (request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0) {
if ((session->features & SMTP_FEATURE_REQUIRETLS) != 0)
vstring_strcat(next_command, " REQUIRETLS");
- else if ((request->sendopts & SOPT_REQUIRETLS_ESMTP) != 0)
- msg_panic("Can't happen: message requires REQUIRETLS, but "
+ else if (state->enforce_requiretls)
+ msg_panic("Can't happen: must enforce REQUIRETLS, but "
"host %s did not announce REQUIRETLS support",
session->namaddr);
}
diff --git a/postfix/src/smtp/smtp_state.c b/postfix/src/smtp/smtp_state.c
index ec8cc2df3..42f7dc7ba 100644
--- a/postfix/src/smtp/smtp_state.c
+++ b/postfix/src/smtp/smtp_state.c
@@ -82,6 +82,9 @@ SMTP_STATE *smtp_state_alloc(void)
state->iterator->saved_dest = vstring_alloc(100);
#ifdef USE_TLSRPT
state->tlsrpt = 0;
+#endif
+#ifdef USE_TLS
+ state->enforce_requiretls = 0;
#endif
if (var_smtp_cache_conn) {
state->dest_label = vstring_alloc(10);
diff --git a/postfix/src/util/binhash.c b/postfix/src/util/binhash.c
index fd9bc8779..0383a899a 100644
--- a/postfix/src/util/binhash.c
+++ b/postfix/src/util/binhash.c
@@ -346,8 +346,7 @@ void binhash_walk(BINHASH *table, void (*action) (BINHASH_INFO *, void *),
/* binhash_list - list all table members */
-BINHASH_INFO **binhash_list(table)
-BINHASH *table;
+BINHASH_INFO **binhash_list(BINHASH *table)
{
BINHASH_INFO **list;
BINHASH_INFO *member;
diff --git a/postfix/src/util/close_on_exec.c b/postfix/src/util/close_on_exec.c
index efa341538..afa49b873 100644
--- a/postfix/src/util/close_on_exec.c
+++ b/postfix/src/util/close_on_exec.c
@@ -46,9 +46,7 @@
/* close_on_exec - set/clear close-on-exec flag */
-int close_on_exec(fd, on)
-int fd;
-int on;
+int close_on_exec(int fd, int on)
{
int flags;
diff --git a/postfix/src/util/match_list.c b/postfix/src/util/match_list.c
index fa533ba65..01dd37df2 100644
--- a/postfix/src/util/match_list.c
+++ b/postfix/src/util/match_list.c
@@ -60,6 +60,10 @@
/* Request that match_list_match() logs a warning and returns
/* zero (with list->error set to a non-zero dictionary error
/* code) instead of raising a fatal run-time error.
+/* .IP MATCH_FLAG_NOFILE
+/* Disable special handling for /file/name.
+/* .IP MATCH_FLAG_NODICT
+/* Disable special handling for type:name.
/* .RE
/* Specify MATCH_FLAG_NONE to request none of the above.
/* .IP pattern_list
@@ -84,6 +88,9 @@
/* IBM T.J. Watson Research
/* P.O. Box 704
/* Yorktown Heights, NY 10598, USA
+/*
+/* Wietse Venema
+/* porcupine.org
/*--*/
/* System library. */
@@ -152,7 +159,8 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
if (*item == 0)
/* No graceful degradation for this... */
msg_fatal("%s: no pattern after '!'", match_list->pname);
- if (*item == '/') { /* /file/name */
+ if (*item == '/' /* /file/name */
+ && (match_list->flags & MATCH_FLAG_NOFILE) == 0) {
if ((fp = vstream_fopen(item, O_RDONLY, 0)) == 0) {
/* Replace unusable pattern with pseudo table. */
vstring_sprintf(buf, "%s:%s", DICT_TYPE_NOFILE, item);
@@ -169,7 +177,8 @@ static ARGV *match_list_parse(MATCH_LIST *match_list, ARGV *pat_list,
if (vstream_fclose(fp))
msg_fatal("%s: read file %s: %m", myname, item);
}
- } else if (MATCH_DICTIONARY(item)) { /* type:table */
+ } else if (MATCH_DICTIONARY(item) /* type:table */
+ &&(match_list->flags & MATCH_FLAG_NODICT) == 0) {
vstring_sprintf(buf, "%s%s(%o,%s)", match ? "" : "!",
item, OPEN_FLAGS, dict_flags_str(DICT_FLAGS));
map_type_name_flags = STR(buf) + (match == 0);
diff --git a/postfix/src/util/match_list.h b/postfix/src/util/match_list.h
index d8b779430..e07d273eb 100644
--- a/postfix/src/util/match_list.h
+++ b/postfix/src/util/match_list.h
@@ -38,8 +38,10 @@ struct MATCH_LIST {
#define MATCH_FLAG_NONE 0
#define MATCH_FLAG_PARENT (1<<0)
#define MATCH_FLAG_RETURN (1<<1)
-#define MATCH_FLAG_ALL (MATCH_FLAG_PARENT | MATCH_FLAG_RETURN)
-
+#define MATCH_FLAG_NOFILE (1<<2)
+#define MATCH_FLAG_NODICT (1<<3)
+#define MATCH_FLAG_ALL (MATCH_FLAG_PARENT | MATCH_FLAG_RETURN | \
+ MATCH_FLAG_NOFILE | MATCH_FLAG_NODICT)
extern MATCH_LIST *match_list_init(const char *, int, const char *, int,...);
extern int match_list_match(MATCH_LIST *,...);
extern void match_list_free(MATCH_LIST *);
diff --git a/postfix/src/util/non_blocking.c b/postfix/src/util/non_blocking.c
index 6427cd80f..2343814eb 100644
--- a/postfix/src/util/non_blocking.c
+++ b/postfix/src/util/non_blocking.c
@@ -52,9 +52,7 @@
/* non_blocking - set/clear non-blocking flag */
-int non_blocking(fd, on)
-int fd;
-int on;
+int non_blocking(int fd, int on)
{
int flags;
diff --git a/postfix/src/util/ring.c b/postfix/src/util/ring.c
index d4c5f82ae..9933c4cc0 100644
--- a/postfix/src/util/ring.c
+++ b/postfix/src/util/ring.c
@@ -76,17 +76,14 @@
/* ring_init - initialize ring head */
-void ring_init(ring)
-RING *ring;
+void ring_init(RING *ring)
{
ring->pred = ring->succ = ring;
}
/* ring_append - insert entry after ring head */
-void ring_append(ring, entry)
-RING *ring;
-RING *entry;
+void ring_append(RING *ring, RING *entry)
{
entry->succ = ring->succ;
entry->pred = ring;
@@ -96,9 +93,7 @@ RING *entry;
/* ring_prepend - insert new entry before ring head */
-void ring_prepend(ring, entry)
-RING *ring;
-RING *entry;
+void ring_prepend(RING *ring, RING *entry)
{
entry->pred = ring->pred;
entry->succ = ring;
@@ -108,8 +103,7 @@ RING *entry;
/* ring_detach - remove entry from ring */
-void ring_detach(entry)
-RING *entry;
+void ring_detach(RING *entry)
{
RING *succ = entry->succ;
RING *pred = entry->pred;