Postfix may support LMDB again when it no
+longer limits the size of Postfix transactions, whether the limit
+is built into LMDB itself, or implicit by requiring an unbounded
+amount of memory to handle a large transaction.
Postfix uses databases of various kinds to store and look up
information. Postfix databases are specified as "type:name".
@@ -44,12 +45,10 @@ LMDB support.
Unexpected failure modes that
+don't exist with other Postfix databases.
- - Note:
-
The Postfix LMDB client implementation
-introduces unexpected failure modes that
-don't exist with other Postfix databases. Don't just yet abandon
-CDB.
+
diff --git a/postfix/html/lmtp.8.html b/postfix/html/lmtp.8.html
index 53bf1c711..20bed174b 100644
--- a/postfix/html/lmtp.8.html
+++ b/postfix/html/lmtp.8.html
@@ -203,7 +203,7 @@ SMTP(8) SMTP(8)
smtp_skip_5xx_greeting (yes)
Skip remote SMTP servers that greet with a 5XX sta-
- tus code (go away, do not try again later).
+ tus code.
smtp_skip_quit_response (yes)
Do not wait for the response to the SMTP QUIT com-
@@ -311,6 +311,11 @@ SMTP(8) SMTP(8)
the MAIL FROM command in SASL-authenticated SMTP
sessions.
+ Available in Postfix version 2.11 and later:
+
+ smtp_dns_support_level (empty)
+ Level of DNS support in the Postfix SMTP client.
+
MIME PROCESSING CONTROLS
Available in Postfix version 2.0 and later:
diff --git a/postfix/html/postconf.5.html b/postfix/html/postconf.5.html
index 562f34e51..1c7b27b8e 100644
--- a/postfix/html/postconf.5.html
+++ b/postfix/html/postconf.5.html
@@ -1739,7 +1739,7 @@ set up your XAUTHORITY environment variable before starting Postfix.
Note: the command is subject to $name expansion, before it is
-passed to the default commmand interpreter. Specify "$$" to
+passed to the default command interpreter. Specify "$$" to
produce a single "$" character.
@@ -2617,7 +2617,9 @@ behavior was hard-coded to be "always on".
Disable DNS lookups in the Postfix SMTP and LMTP clients. When
disabled, hosts are looked up with the getaddrinfo() system
-library routine which normally also looks in /etc/hosts.
+library routine which normally also looks in /etc/hosts. As of
+Postfix 2.11, this parameter is deprecated; use smtp_dns_support_level
+instead.
@@ -4113,6 +4115,17 @@ configuration parameter. See there for details.
This feature is available in Postfix 2.8 and later.
+
+
+lmtp_dns_support_level
+(default: empty)
+
+ The LMTP-specific version of the smtp_dns_support_level
+configuration parameter. See there for details.
+
+ This feature is available in Postfix 2.11 and later.
+
+
lmtp_enforce_tls
@@ -9389,6 +9402,10 @@ false hostname information in DNS CNAME records, and makes SASL
password file lookups more predictable. This is the default setting
as of Postfix 2.3.
+ When DNS CNAME records are validated with secure DNS lookups
+(smtp_dns_support_level = dnssec), they are always allowed to
+override the above servername (Postfix 2.11 and later).
+
This feature is available in Postfix 2.2.9 and later.
@@ -9724,6 +9741,95 @@ recommended.
This feature is available in Postfix 2.8 and later.
+
+
+smtp_dns_support_level
+(default: empty)
+
+ Level of DNS support in the Postfix SMTP client. With
+"smtp_dns_support_level" left at its empty default value, the legacy
+"disable_dns_lookups" parameter controls whether DNS is enabled in
+the Postfix SMTP client, otherwise the legacy parameter is ignored.
+
+
+ Specify one of the following:
+
+
+
+- disabled
+
+- Disable DNS lookups. No MX lookups are performed and hostname
+to address lookups are unconditionally "native". This setting is
+not appropriate for hosts that deliver mail to the public Internet.
+Some obsolete how-to documents recommend disabling DNS lookups in
+some configurations with content_filters. This is no longer required
+and strongly discouraged.
+
+- enabled
+
+- Enable DNS lookups. Nexthop destination domains not enclosed
+in "[]" will be subject to MX lookups. If "dns" and "native" are
+included in the "smtp_host_lookup" parameter value, DNS will be
+queried first to resolve MX-host A records, followed by "native"
+lookups if no answer is found in DNS.
+
+- dnssec
+
+- Enable DNSSEC
+lookups. The "dnssec" setting differs from the "enabled" setting
+above in the following ways:
- Any MX lookups will set
+RES_USE_DNSSEC and RES_USE_EDNS0 to request DNSSEC-validated
+responses. If the MX response is DNSSEC-validated the corresponding
+hostnames are considered validated.
- The address lookups of
+validated hostnames are also validated, (provided of course
+"smtp_host_lookup" includes "dns", see below).
- Temporary
+failures in DNSSEC-enabled hostname-to-address resolution block any
+"native" lookups. Additional "native" lookups only happen when
+DNSSEC lookups hard-fail (NODATA or NXDOMAIN).
+
+
+
+ The Postfix SMTP client considers non-MX "[nexthop]" and
+"[nexthop]:port" destinations equivalent to statically-validated
+MX records of the form "nexthop. IN MX 0 nexthop." Therefore,
+with "dnssec" support turned on, validated hostname-to-address
+lookups apply to the nexthop domain of any "[nexthop]" or
+"[nexthop]:port" destination. This is also true for LMTP "inet:host"
+and "inet:host:port" destinations, as LMTP hostnames are never
+subject to MX lookups.
+
+The "dnssec" setting is recommended only if you plan to use the
+"dane" TLS security
+level, otherwise enabling DNSSEC support in Postfix offers no
+additional security. Postfix DNSSEC support relies on an up-stream
+recursive nameserver that validates DNSSEC signatures. Such a DNS
+server will always filter out forged DNS responses, even when Postfix
+itself is not configured to use DNSSEC.
+
+ When using Postfix DANE support the "smtp_host_lookup" parameter
+should include "dns", as DANE is not applicable
+to hosts resolved via "native" lookups.
+
+ As mentioned above, Postfix is not a validating stub
+resolver; it relies on the system's configured DNSSEC-validating
+recursive
+nameserver to perform all DNSSEC validation. Since this
+nameserver's DNSSEC-validated responses will be fully trusted, it
+is strongly recommended that the MTA host have a local DNSSEC-validating
+recursive caching nameserver listening on a loopback address, and
+be configured to use only this nameserver for all lookups. Otherwise,
+Postfix may remain subject to man-in-the-middle attacks that forge
+responses from the recursive nameserver
+
+DNSSEC support requires a version of Postfix compiled against a
+reasonably-modern DNS resolver(3) library that implements the
+RES_USE_DNSSEC and RES_USE_EDNS0 resolver options.
+
+ This feature is available in Postfix 2.11 and later.
+
+
smtp_enforce_tls
@@ -9868,9 +9974,10 @@ The default time unit is s (seconds).
(default: dns)
-What mechanisms the Postfix SMTP client uses to look up a host's IP
-address. This parameter is ignored when DNS lookups are disabled
-(see: disable_dns_lookups).
+What mechanisms the Postfix SMTP client uses to look up a host's
+IP address. This parameter is ignored when DNS lookups are disabled
+(see: disable_dns_lookups and smtp_dns_support_level). The "dns"
+mechanism is always tried before "native" if both are listed.
@@ -10597,15 +10704,13 @@ with a
(default: yes)
-Skip remote SMTP servers that greet with a 5XX status code (go away,
-do
-not try again later).
+Skip remote SMTP servers that greet with a 5XX status code.
By default, the Postfix SMTP client moves on the next mail
exchanger. Specify "smtp_skip_5xx_greeting = no" if Postfix should
-bounce the mail immediately. The default setting is incorrect, but
-it is what a lot of people expect to happen.
+bounce the mail immediately. Caution: the latter behavior appears
+to contradict RFC 2821.
@@ -11593,8 +11698,7 @@ but not any CAs it delegates to.
(default: nexthop, dot-nexthop)
How the Postfix SMTP client verifies the server certificate
-peername for the
-"secure" TLS security level. In a "secure" TLS policy table
+peername for the "secure" TLS security level. In a "secure" TLS policy table
($smtp_tls_policy_maps) entry the optional "match" attribute
overrides this main.cf setting.
@@ -13152,7 +13256,7 @@ rejected requests (default: 504).
reject_rhsbl_helo rbl_domain=d.d.d.d
-Reject the request when the HELO or EHLO hostname hostname is
+Reject the request when the HELO or EHLO hostname is
listed with the A record "d.d.d.d" under rbl_domain
(Postfix version 2.1 and later only). Each "d" is a number,
or a pattern inside "[]" that contains one or more ";"-separated
@@ -13707,7 +13811,7 @@ change into 550 when you are confident that it is safe to do so).
numerical response code when an address probe failed due to a
temporary problem (default: 450).
The
unverified_recipient_tempfail_action parameter specifies the action
-after addres probe failure due to a temporary problem (default:
+after address probe failure due to a temporary problem (default:
defer_if_permit).
This feature is available in Postfix 2.1
and later.
@@ -14418,7 +14522,7 @@ see the ADDRESS_VERIFICATION_README
response code when an address is known to bounce (default: 450,
change into 550 when you are confident that it is safe to do so).
The unverified_sender_defer_code specifies the numerical response
-code when an address address probe failed due to a temporary problem
+code when an address probe failed due to a temporary problem
(default: 450).
The unverified_sender_tempfail_action parameter
specifies the action after address probe failure due to a temporary
problem (default: defer_if_permit).
This feature is available
diff --git a/postfix/html/smtp.8.html b/postfix/html/smtp.8.html
index 53bf1c711..20bed174b 100644
--- a/postfix/html/smtp.8.html
+++ b/postfix/html/smtp.8.html
@@ -203,7 +203,7 @@ SMTP(8) SMTP(8)
smtp_skip_5xx_greeting (yes)
Skip remote SMTP servers that greet with a 5XX sta-
- tus code (go away, do not try again later).
+ tus code.
smtp_skip_quit_response (yes)
Do not wait for the response to the SMTP QUIT com-
@@ -311,6 +311,11 @@ SMTP(8) SMTP(8)
the MAIL FROM command in SASL-authenticated SMTP
sessions.
+ Available in Postfix version 2.11 and later:
+
+ smtp_dns_support_level (empty)
+ Level of DNS support in the Postfix SMTP client.
+
MIME PROCESSING CONTROLS
Available in Postfix version 2.0 and later:
diff --git a/postfix/makedefs b/postfix/makedefs
index f0151f35d..71f5008d1 100644
--- a/postfix/makedefs
+++ b/postfix/makedefs
@@ -315,12 +315,12 @@ case "$SYSTEM.$RELEASE" in
# Workaround for retarded libc
2.6.*)
if [ `expr "X$CCARGS" : "X.*-DNO_EPOLL"` -gt 0 ]
- then
- :
- elif [ ! -e /usr/include/sys/epoll.h ]
- then
- echo CCARGS="$CCARGS -DNO_EPOLL"
- else
+ then
+ :
+ elif [ ! -e /usr/include/sys/epoll.h ]
+ then
+ echo CCARGS="$CCARGS -DNO_EPOLL"
+ else
trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
cat >makedefs.test.c <<'EOF'
#include
@@ -378,7 +378,7 @@ EOF
done
;;
GNU.0*|GNU/kFreeBSD.[567]*)
- SYSTYPE=GNU0
+ SYSTYPE=GNU0
case "$CCARGS" in
*-DNO_DB*) ;;
*) if [ -f /usr/include/db.h ]
@@ -475,64 +475,11 @@ ReliantUNIX-?.5.43) SYSTYPE=ReliantUnix543
?.*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_NAMESER8_COMPAT_H";;
*) CCARGS="$CCARGS -DRESOLVE_H_NEEDS_ARPA_NAMESER_COMPAT_H";;
esac
- # kqueue and/or poll are broken up to and including MacOS X 10.5
- CCARGS="$CCARGS -DNO_KQUEUE"
-# # Darwin 8.11.1 has kqueue support, but let's play safe
-# case $RELEASE in
-# [1-8].*) CCARGS="$CCARGS -DNO_KQUEUE";;
-# *) trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
-# cat >makedefs.test.c <<'EOF'
-#/* Adapted from libevent. */
-#
-##include
-##include
-##include
-##include
-##include
-##include
-#
-##ifndef EV_SET
-##define EV_SET(kp, id, fi, fl, ffl, da, ud) do { \
-# struct kevent *__kp = (kp); \
-# __kp->ident = (id); \
-# __kp->filter = (fi); \
-# __kp->flags = (fl); \
-# __kp->fflags = (ffl); \
-# __kp->data = (da); \
-# __kp->udata = (ud); \
-# } while(0)
-##endif
-#
-#int main(int argc, char **argv)
-#{
-# int kq;
-# struct kevent test_change;
-# struct kevent test_result;
-#
-# if ((kq = kqueue()) < 0) {
-# perror("kqueue");
-# exit(1);
-# }
-##define TEST_FD (-1)
-#
-# EV_SET(&test_change, TEST_FD, EVFILT_READ, EV_ADD, 0, 0, 0);
-# if (kevent(kq,
-# &test_change, sizeof(test_change) / sizeof(struct kevent),
-# &test_result, sizeof(test_result) / sizeof(struct kevent),
-# (struct timespec *) 0) != 1 ||
-# test_result.ident != TEST_FD ||
-# test_result.flags != EV_ERROR) {
-# fprintf(stderr, "Error: kevent reports errors incorrectly\n");
-# exit(1);
-# }
-# exit(0);
-#}
-#EOF
-# $CC -o makedefs.test makedefs.test.c || exit 1
-# ./makedefs.test 2>/dev/null ||
-# CCARGS="$CCARGS -DNO_KQUEUE"
-# rm -f makedefs.test makedefs.test.[co];;
-# esac
+ # kqueue and/or poll are broken in MacOS X 10.5 (Darwin 9).
+ # kqueue and poll work in Mac OS X 10.8 (Darwin 12).
+ case $RELEASE in
+ ?.*|1[0-1].*) CCARGS="$CCARGS -DNO_KQUEUE";;
+ esac
;;
dcosx.1*) SYSTYPE=DCOSX1
RANLIB=echo
@@ -562,7 +509,7 @@ esac
#
case "$CCARGS" in
*-DNO_SIGSETJMP*) ;;
- *) trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
+ *) trap 'rm -f makedefs.test makedefs.test.[co]' 1 2 3 15
cat >makedefs.test.c <<'EOF'
#include
#include
@@ -628,7 +575,7 @@ esac
case "$CCARGS" in
*-DHAS_PCRE*) ;;
*-DNO_PCRE*) ;;
- *) pcre_cflags=`(pcre-config --cflags) 2>/dev/null` &&
+ *) pcre_cflags=`(pcre-config --cflags) 2>/dev/null` &&
pcre_libs=`(pcre-config --libs) 2>/dev/null` && {
CCARGS="$CCARGS -DHAS_PCRE $pcre_cflags"
AUXLIBS="$AUXLIBS $pcre_libs"
@@ -647,7 +594,7 @@ case "$CC" in
"gcc version 2.8"*) : ${OPT=};;
esac;;
*CC) error "Don't use CC. That's the C++ compiler";;
- *) : ${OPT='-O'};;
+ *) : ${OPT='-O'};;
esac
#
# "gcc -W" 3.4.2 no longer reports functions that fail to return a
diff --git a/postfix/man/man5/postconf.5 b/postfix/man/man5/postconf.5
index f9706e676..3f9814927 100644
--- a/postfix/man/man5/postconf.5
+++ b/postfix/man/man5/postconf.5
@@ -1005,7 +1005,7 @@ the process marches on. If you use an X-based debugger, be sure to
set up your XAUTHORITY environment variable before starting Postfix.
.PP
Note: the command is subject to $name expansion, before it is
-passed to the default commmand interpreter. Specify "$$" to
+passed to the default command interpreter. Specify "$$" to
produce a single "$" character.
.PP
Example:
@@ -1561,7 +1561,9 @@ This feature is available in Postfix 2.5 and later.
.SH disable_dns_lookups (default: no)
Disable DNS lookups in the Postfix SMTP and LMTP clients. When
disabled, hosts are looked up with the getaddrinfo() system
-library routine which normally also looks in /etc/hosts.
+library routine which normally also looks in /etc/hosts. As of
+Postfix 2.11, this parameter is deprecated; use smtp_dns_support_level
+instead.
.PP
DNS lookups are enabled by default.
.SH disable_mime_input_processing (default: no)
@@ -2417,6 +2419,11 @@ The LMTP-specific version of the smtp_dns_resolver_options
configuration parameter. See there for details.
.PP
This feature is available in Postfix 2.8 and later.
+.SH lmtp_dns_support_level (default: empty)
+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_tls (default: no)
The LMTP-specific version of the smtp_enforce_tls configuration
parameter. See there for details.
@@ -5691,6 +5698,10 @@ false hostname information in DNS CNAME records, and makes SASL
password file lookups more predictable. This is the default setting
as of Postfix 2.3.
.PP
+When DNS CNAME records are validated with secure DNS lookups
+(smtp_dns_support_level = dnssec), they are always allowed to
+override the above servername (Postfix 2.11 and later).
+.PP
This feature is available in Postfix 2.2.9 and later.
.SH smtp_connect_timeout (default: 30s)
The Postfix SMTP client time limit for completing a TCP connection, or
@@ -5892,6 +5903,87 @@ recommended.
.br
.PP
This feature is available in Postfix 2.8 and later.
+.SH smtp_dns_support_level (default: empty)
+Level of DNS support in the Postfix SMTP client. With
+"smtp_dns_support_level" left at its empty default value, the legacy
+"disable_dns_lookups" parameter controls whether DNS is enabled in
+the Postfix SMTP client, otherwise the legacy parameter is ignored.
+.PP
+Specify one of the following:
+.IP "\fBdisabled\fR"
+Disable DNS lookups. No MX lookups are performed and hostname
+to address lookups are unconditionally "native". This setting is
+not appropriate for hosts that deliver mail to the public Internet.
+Some obsolete how-to documents recommend disabling DNS lookups in
+some configurations with content_filters. This is no longer required
+and strongly discouraged.
+.br
+.IP "\fBenabled\fR"
+Enable DNS lookups. Nexthop destination domains not enclosed
+in "[]" will be subject to MX lookups. If "dns" and "native" are
+included in the "smtp_host_lookup" parameter value, DNS will be
+queried first to resolve MX-host A records, followed by "native"
+lookups if no answer is found in DNS.
+.br
+.IP "\fBdnssec\fR"
+Enable DNSSEC
+lookups. The "dnssec" setting differs from the "enabled" setting
+above in the following ways:
+.IP \(bu
+Any MX lookups will set
+RES_USE_DNSSEC and RES_USE_EDNS0 to request DNSSEC-validated
+responses. If the MX response is DNSSEC-validated the corresponding
+hostnames are considered validated.
+.IP \(bu
+The address lookups of
+validated hostnames are also validated, (provided of course
+"smtp_host_lookup" includes "dns", see below).
+.IP \(bu
+Temporary
+failures in DNSSEC-enabled hostname-to-address resolution block any
+"native" lookups. Additional "native" lookups only happen when
+DNSSEC lookups hard-fail (NODATA or NXDOMAIN).
+.br
+.br
+.br
+.PP
+The Postfix SMTP client considers non-MX "[nexthop]" and
+"[nexthop]:port" destinations equivalent to statically-validated
+MX records of the form "nexthop. IN MX 0 nexthop." Therefore,
+with "dnssec" support turned on, validated hostname-to-address
+lookups apply to the nexthop domain of any "[nexthop]" or
+"[nexthop]:port" destination. This is also true for LMTP "inet:host"
+and "inet:host:port" destinations, as LMTP hostnames are never
+subject to MX lookups.
+.PP
+The "dnssec" setting is recommended only if you plan to use the
+"dane" TLS security
+level, otherwise enabling DNSSEC support in Postfix offers no
+additional security. Postfix DNSSEC support relies on an up-stream
+recursive nameserver that validates DNSSEC signatures. Such a DNS
+server will always filter out forged DNS responses, even when Postfix
+itself is not configured to use DNSSEC.
+.PP
+When using Postfix DANE support the "smtp_host_lookup" parameter
+should include "dns", as DANE is not applicable
+to hosts resolved via "native" lookups.
+.PP
+As mentioned above, Postfix is not a validating stub
+resolver; it relies on the system's configured DNSSEC-validating
+recursive
+nameserver to perform all DNSSEC validation. Since this
+nameserver's DNSSEC-validated responses will be fully trusted, it
+is strongly recommended that the MTA host have a local DNSSEC-validating
+recursive caching nameserver listening on a loopback address, and
+be configured to use only this nameserver for all lookups. Otherwise,
+Postfix may remain subject to man-in-the-middle attacks that forge
+responses from the recursive nameserver
+.PP
+DNSSEC support requires a version of Postfix compiled against a
+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_tls (default: no)
Enforcement mode: require that remote SMTP servers use TLS
encryption, and never send mail in the clear. This also requires
@@ -5982,9 +6074,10 @@ and for receiving the initial remote SMTP server response.
Time units: s (seconds), m (minutes), h (hours), d (days), w (weeks).
The default time unit is s (seconds).
.SH smtp_host_lookup (default: dns)
-What mechanisms the Postfix SMTP client uses to look up a host's IP
-address. This parameter is ignored when DNS lookups are disabled
-(see: disable_dns_lookups).
+What mechanisms the Postfix SMTP client uses to look up a host's
+IP address. This parameter is ignored when DNS lookups are disabled
+(see: disable_dns_lookups and smtp_dns_support_level). The "dns"
+mechanism is always tried before "native" if both are listed.
.PP
Specify one of the following:
.IP "\fBdns\fR"
@@ -6445,14 +6538,12 @@ Later Postfix versions always skip remote SMTP servers that greet
with a
4XX status code.
.SH smtp_skip_5xx_greeting (default: yes)
-Skip remote SMTP servers that greet with a 5XX status code (go away,
-do
-not try again later).
+Skip remote SMTP servers that greet with a 5XX status code.
.PP
By default, the Postfix SMTP client moves on the next mail
exchanger. Specify "smtp_skip_5xx_greeting = no" if Postfix should
-bounce the mail immediately. The default setting is incorrect, but
-it is what a lot of people expect to happen.
+bounce the mail immediately. Caution: the latter behavior appears
+to contradict RFC 2821.
.SH smtp_skip_quit_response (default: yes)
Do not wait for the response to the SMTP QUIT command.
.SH smtp_starttls_timeout (default: 300s)
@@ -7351,8 +7442,7 @@ but not any CAs it delegates to.
This feature is available in Postfix 2.2 and later.
.SH smtp_tls_secure_cert_match (default: nexthop, dot-nexthop)
How the Postfix SMTP client verifies the server certificate
-peername for the
-"secure" TLS security level. In a "secure" TLS policy table
+peername for the "secure" TLS security level. In a "secure" TLS policy table
($smtp_tls_policy_maps) entry the optional "match" attribute
overrides this main.cf setting.
.PP
@@ -8599,7 +8689,7 @@ The non_fqdn_reject_code parameter specifies the response code for
rejected requests (default: 504).
.br
.IP "\fBreject_rhsbl_helo \fIrbl_domain=d.d.d.d\fR\fR"
-Reject the request when the HELO or EHLO hostname hostname is
+Reject the request when the HELO or EHLO hostname is
listed with the A record "\fId.d.d.d\fR" under \fIrbl_domain\fR
(Postfix version 2.1 and later only). Each "\fId\fR" is a number,
or a pattern inside "[]" that contains one or more ";"-separated
@@ -9005,7 +9095,7 @@ temporary problem (default: 450).
.br
The
unverified_recipient_tempfail_action parameter specifies the action
-after addres probe failure due to a temporary problem (default:
+after address probe failure due to a temporary problem (default:
defer_if_permit).
.br
This feature is available in Postfix 2.1
@@ -9562,7 +9652,7 @@ response code when an address is known to bounce (default: 450,
change into 550 when you are confident that it is safe to do so).
.br
The unverified_sender_defer_code specifies the numerical response
-code when an address address probe failed due to a temporary problem
+code when an address probe failed due to a temporary problem
(default: 450).
.br
The unverified_sender_tempfail_action parameter
diff --git a/postfix/man/man8/smtp.8 b/postfix/man/man8/smtp.8
index 98b7fa622..57c0c9159 100644
--- a/postfix/man/man8/smtp.8
+++ b/postfix/man/man8/smtp.8
@@ -191,9 +191,7 @@ by RFC 5321.
A mechanism to transform replies from remote SMTP servers one
line at a time.
.IP "\fBsmtp_skip_5xx_greeting (yes)\fR"
-Skip remote SMTP servers that greet with a 5XX status code (go away,
-do
-not try again later).
+Skip remote SMTP servers that greet with a 5XX status code.
.IP "\fBsmtp_skip_quit_response (yes)\fR"
Do not wait for the response to the SMTP QUIT command.
.PP
@@ -271,6 +269,10 @@ line, SMTP message content line, or TLS protocol message).
.IP "\fBsmtp_send_dummy_mail_auth (no)\fR"
Whether or not to append the "AUTH=<>" option to the MAIL
FROM command in SASL-authenticated SMTP sessions.
+.PP
+Available in Postfix version 2.11 and later:
+.IP "\fBsmtp_dns_support_level (empty)\fR"
+Level of DNS support in the Postfix SMTP client.
.SH "MIME PROCESSING CONTROLS"
.na
.nf
@@ -406,8 +408,7 @@ mandatory TLS encryption.
The verification depth for remote SMTP server certificates.
.IP "\fBsmtp_tls_secure_cert_match (nexthop, dot-nexthop)\fR"
How the Postfix SMTP client verifies the server certificate
-peername for the
-"secure" TLS security level.
+peername for the "secure" TLS security level.
.IP "\fBsmtp_tls_session_cache_database (empty)\fR"
Name of the file containing the optional Postfix SMTP client
TLS session cache.
@@ -664,8 +665,8 @@ The hostname to send in the SMTP EHLO or HELO command.
.IP "\fBlmtp_lhlo_name ($myhostname)\fR"
The hostname to send in the LMTP LHLO command.
.IP "\fBsmtp_host_lookup (dns)\fR"
-What mechanisms the Postfix SMTP client uses to look up a host's IP
-address.
+What mechanisms the Postfix SMTP client uses to look up a host's
+IP address.
.IP "\fBsmtp_randomize_addresses (yes)\fR"
Randomize the order of equal-preference MX host addresses.
.IP "\fBsyslog_facility (mail)\fR"
diff --git a/postfix/mantools/postconf2man b/postfix/mantools/postconf2man
index 71bc32480..36bbea61a 100755
--- a/postfix/mantools/postconf2man
+++ b/postfix/mantools/postconf2man
@@ -40,8 +40,8 @@ while(<>) {
$block =~ tr/a-z/A-Z/;
}
$block =~ s/]+>([^<]+)<\/a>\n(.*)<\/b><\/DT>/\n.SH \1 \2\n/g;
- $block =~ s/<[Aa] [Hh][Rr][Ee][Ff]="[^"]+">//g;
- $block =~ s/<[Aa] [Nn][Aa][Mm][Ee]="[^"]+">//g;
+ $block =~ s/<[Aa][ \n]+[Hh][Rr][Ee][Ff]="[^"]+">//g;
+ $block =~ s/<[Aa][ \n]+[Nn][Aa][Mm][Ee]="[^"]+">//g;
$block =~ s/<\/[Aa]>//g;
$block =~ s/<\/DD>/\n/g;
$block =~ s//\n/g;
diff --git a/postfix/mantools/postlink b/postfix/mantools/postlink
index e2a54e2f0..4c12073ae 100755
--- a/postfix/mantools/postlink
+++ b/postfix/mantools/postlink
@@ -209,6 +209,19 @@ while (<>) {
s;\bipc_ttl\b;$&;g;
s;\bline_length_limit\b;$&;g;
s;\blmdb_map_size\b;$&;g;
+ s;\blmtp_address_preference\b;$&;g;
+ s;\blmtp_body_checks\b;$&;g;
+ s;\blmtp_cname_overrides_servername\b;$&;g;
+ s;\blmtp_dns_resolver_options\b;$&;g;
+ s;\blmtp_dns_support_level\b;$&;g;
+ s;\blmtp_header_checks\b;$&;g;
+ s;\blmtp_mime_header_checks\b;$&;g;
+ s;\blmtp_nested_header_checks\b;$&;g;
+ s;\blmtp_per_record_deadline\b;$&;g;
+ s;\blmtp_reply_filter\b;$&;g;
+ s;\blmtp_sasl_password_maps\b;$&;g;
+ s;\blmtp_send_dummy_mail_auth\b;$&;g;
+ s;\blmtp_sender_dependent_authentication\b;$&;g;
s;\blmtp_bind_address\b;$&;g;
s;\blmtp_bind_address6\b;$&;g;
s;\blmtp_assume_final\b;$&;g;
@@ -453,6 +466,7 @@ while (<>) {
s;\bsmtp_discard_ehlo_keyword_address_maps\b;$&;g;
s;\bsmtp_discard_ehlo_keywords\b;$&;g;
s;\bsmtp_dns_resolver_options\b;$&;g;
+ s;\bsmtp_dns_support_level\b;$&;g;
s;\bsmtp_helo_name\b;$&;g;
s;\bsmtp_helo_timeout\b;$&;g;
s;\bsmtp_host_lookup\b;$&;g;
diff --git a/postfix/proto/LMDB_README.html b/postfix/proto/LMDB_README.html
index df47dc431..3fd4b9b01 100644
--- a/postfix/proto/LMDB_README.html
+++ b/postfix/proto/LMDB_README.html
@@ -20,11 +20,12 @@
Introduction
- Note:
-
Postfix support for LMDB databases
-is withdrawn due to the existence of a hard limit (an "out of
+is suspended due to the existence of a hard limit (an "out of
storage" failure mode that cannot be resolved by increasing the
-database size).
Postfix may support LMDB again when without
-exception all "out of storage" failure modes are resolved by
-increasing the database size.
+database size). Postfix may support LMDB again when it no
+longer limits the size of Postfix transactions, whether the limit
+is built into LMDB itself, or implicit by requiring an unbounded
+amount of memory to handle a large transaction.
Postfix uses databases of various kinds to store and look up
information. Postfix databases are specified as "type:name".
@@ -44,12 +45,10 @@ LMDB support
.
Missing pthread library trouble.
-
+ Unexpected failure modes that
+don't exist with other Postfix databases.
- - Note:
-
The Postfix LMDB client implementation
-introduces unexpected failure modes that
-don't exist with other Postfix databases. Don't just yet abandon
-CDB.
+
diff --git a/postfix/proto/postconf.proto b/postfix/proto/postconf.proto
index 8ca20beed..c42856f1b 100644
--- a/postfix/proto/postconf.proto
+++ b/postfix/proto/postconf.proto
@@ -4178,9 +4178,10 @@ The default time unit is s (seconds).
%PARAM smtp_host_lookup dns
-What mechanisms the Postfix SMTP client uses to look up a host's IP
-address. This parameter is ignored when DNS lookups are disabled
-(see: disable_dns_lookups).
+What mechanisms the Postfix SMTP client uses to look up a host's
+IP address. This parameter is ignored when DNS lookups are disabled
+(see: disable_dns_lookups and smtp_dns_support_level). The "dns"
+mechanism is always tried before "native" if both are listed.
@@ -4488,15 +4489,13 @@ with a
%PARAM smtp_skip_5xx_greeting yes
-Skip remote SMTP servers that greet with a 5XX status code (go away,
-do
-not try again later).
+Skip remote SMTP servers that greet with a 5XX status code.
By default, the Postfix SMTP client moves on the next mail
exchanger. Specify "smtp_skip_5xx_greeting = no" if Postfix should
-bounce the mail immediately. The default setting is incorrect, but
-it is what a lot of people expect to happen.
+bounce the mail immediately. Caution: the latter behavior appears
+to contradict RFC 2821.
%PARAM smtp_skip_quit_response yes
@@ -5511,7 +5510,7 @@ rejected requests (default: 504).
reject_rhsbl_helo rbl_domain=d.d.d.d
-Reject the request when the HELO or EHLO hostname hostname is
+Reject the request when the HELO or EHLO hostname is
listed with the A record "d.d.d.d" under rbl_domain
(Postfix version 2.1 and later only). Each "d" is a number,
or a pattern inside "[]" that contains one or more ";"-separated
@@ -5881,7 +5880,7 @@ change into 550 when you are confident that it is safe to do so).
numerical response code when an address probe failed due to a
temporary problem (default: 450).
The
unverified_recipient_tempfail_action parameter specifies the action
-after addres probe failure due to a temporary problem (default:
+after address probe failure due to a temporary problem (default:
defer_if_permit).
This feature is available in Postfix 2.1
and later.
@@ -6330,7 +6329,7 @@ unverified_sender_reject_code parameter specifies the numerical
response code when an address is known to bounce (default: 450,
change into 550 when you are confident that it is safe to do so).
The unverified_sender_defer_code specifies the numerical response
-code when an address address probe failed due to a temporary problem
+code when an address probe failed due to a temporary problem
(default: 450).
The unverified_sender_tempfail_action parameter
specifies the action after address probe failure due to a temporary
problem (default: defer_if_permit).
This feature is available
@@ -6823,7 +6822,7 @@ set up your XAUTHORITY environment variable before starting Postfix.
Note: the command is subject to $name expansion, before it is
-passed to the default commmand interpreter. Specify "$$" to
+passed to the default command interpreter. Specify "$$" to
produce a single "$" character.
@@ -7314,7 +7313,9 @@ See also: delay_notice_recipient, notify_classes.
Disable DNS lookups in the Postfix SMTP and LMTP clients. When
disabled, hosts are looked up with the getaddrinfo() system
-library routine which normally also looks in /etc/hosts.
+library routine which normally also looks in /etc/hosts. As of
+Postfix 2.11, this parameter is deprecated; use smtp_dns_support_level
+instead.
@@ -10411,6 +10412,10 @@ false hostname information in DNS CNAME records, and makes SASL
password file lookups more predictable. This is the default setting
as of Postfix 2.3.
+ When DNS CNAME records are validated with secure DNS lookups
+(smtp_dns_support_level = dnssec), they are always allowed to
+override the above servername (Postfix 2.11 and later).
+
This feature is available in Postfix 2.2.9 and later.
%PARAM lmtp_cname_overrides_servername yes
@@ -10794,8 +10799,7 @@ example.com verify match=hostname:nexthop
%PARAM smtp_tls_secure_cert_match nexthop, dot-nexthop
How the Postfix SMTP client verifies the server certificate
-peername for the
-"secure" TLS security level. In a "secure" TLS policy table
+peername for the "secure" TLS security level. In a "secure" TLS policy table
($smtp_tls_policy_maps) entry the optional "match" attribute
overrides this main.cf setting.
@@ -14946,3 +14950,95 @@ from the list.
This feature is available in Postfix 2.10 and later.
+
+%PARAM smtp_dns_support_level
+
+ Level of DNS support in the Postfix SMTP client. With
+"smtp_dns_support_level" left at its empty default value, the legacy
+"disable_dns_lookups" parameter controls whether DNS is enabled in
+the Postfix SMTP client, otherwise the legacy parameter is ignored.
+
+
+ Specify one of the following:
+
+
+
+- disabled
+
+- Disable DNS lookups. No MX lookups are performed and hostname
+to address lookups are unconditionally "native". This setting is
+not appropriate for hosts that deliver mail to the public Internet.
+Some obsolete how-to documents recommend disabling DNS lookups in
+some configurations with content_filters. This is no longer required
+and strongly discouraged.
+
+- enabled
+
+- Enable DNS lookups. Nexthop destination domains not enclosed
+in "[]" will be subject to MX lookups. If "dns" and "native" are
+included in the "smtp_host_lookup" parameter value, DNS will be
+queried first to resolve MX-host A records, followed by "native"
+lookups if no answer is found in DNS.
+
+- dnssec
+
+- Enable DNSSEC
+lookups. The "dnssec" setting differs from the "enabled" setting
+above in the following ways:
- Any MX lookups will set
+RES_USE_DNSSEC and RES_USE_EDNS0 to request DNSSEC-validated
+responses. If the MX response is DNSSEC-validated the corresponding
+hostnames are considered validated.
- The address lookups of
+validated hostnames are also validated, (provided of course
+"smtp_host_lookup" includes "dns", see below).
- Temporary
+failures in DNSSEC-enabled hostname-to-address resolution block any
+"native" lookups. Additional "native" lookups only happen when
+DNSSEC lookups hard-fail (NODATA or NXDOMAIN).
+
+
+
+ The Postfix SMTP client considers non-MX "[nexthop]" and
+"[nexthop]:port" destinations equivalent to statically-validated
+MX records of the form "nexthop. IN MX 0 nexthop." Therefore,
+with "dnssec" support turned on, validated hostname-to-address
+lookups apply to the nexthop domain of any "[nexthop]" or
+"[nexthop]:port" destination. This is also true for LMTP "inet:host"
+and "inet:host:port" destinations, as LMTP hostnames are never
+subject to MX lookups.
+
+The "dnssec" setting is recommended only if you plan to use the
+"dane" TLS security
+level, otherwise enabling DNSSEC support in Postfix offers no
+additional security. Postfix DNSSEC support relies on an up-stream
+recursive nameserver that validates DNSSEC signatures. Such a DNS
+server will always filter out forged DNS responses, even when Postfix
+itself is not configured to use DNSSEC.
+
+ When using Postfix DANE support the "smtp_host_lookup" parameter
+should include "dns", as DANE is not applicable
+to hosts resolved via "native" lookups.
+
+ As mentioned above, Postfix is not a validating stub
+resolver; it relies on the system's configured DNSSEC-validating
+recursive
+nameserver to perform all DNSSEC validation. Since this
+nameserver's DNSSEC-validated responses will be fully trusted, it
+is strongly recommended that the MTA host have a local DNSSEC-validating
+recursive caching nameserver listening on a loopback address, and
+be configured to use only this nameserver for all lookups. Otherwise,
+Postfix may remain subject to man-in-the-middle attacks that forge
+responses from the recursive nameserver
+
+DNSSEC support requires a version of Postfix compiled against a
+reasonably-modern DNS resolver(3) library that implements the
+RES_USE_DNSSEC and RES_USE_EDNS0 resolver options.
+
+ This feature is available in Postfix 2.11 and later.
+
+%PARAM lmtp_dns_support_level
+
+ The LMTP-specific version of the smtp_dns_support_level
+configuration parameter. See there for details.
+
+ This feature is available in Postfix 2.11 and later.
diff --git a/postfix/proto/stop b/postfix/proto/stop
index f0340a8ee..396e2ff02 100644
--- a/postfix/proto/stop
+++ b/postfix/proto/stop
@@ -1144,7 +1144,6 @@ texthash
ul
whitelisted
whitelists
-=== proto/POSTSCREEN_README.html ===
Amavisd
MUA
Mailserver
@@ -1153,3 +1152,107 @@ barracudacentral
bl
spamcop
tlsproxy
+AEIOUaeiou
+AF
+ASN
+BB
+CB
+CBC
+CRYPTOPRO
+CTX
+CVE
+DER
+DES
+DNSSEC
+Diffie
+EC
+ECDH
+ECDSA
+EDNS
+EECDH
+FB
+GOST
+Hellman
+LMDB
+MSIE
+Mmm
+NODATA
+NXDOMAIN
+Nexthop
+OP
+OTIFY
+OpenSSL's
+Postix
+Pt
+SECG
+SSLEAY
+SSLREF
+SSLV
+TLSEXT
+VXxznjll
+Whitelist
+XYZ
+YYYYMMDDHHMMSS
+aRSA
+authcid
+authcid's
+authentiCation
+authoriZation
+authzid
+bc
+blockquote
+certfile
+cfm
+cipherlists
+ciphertext
+crypto
+dane
+defnames
+dgst
+dl
+dnsrch
+dnssec
+dnswl
+dotcrlf
+dt
+eNULL
+eccert
+ecdsa
+eckey
+ecparam
+eecdh
+fc
+fixup
+getaddrinfo
+haproxy
+headerbody
+hh
+hyperlinked
+ia
+kEDH
+lmdb
+localtime
+mN
+matchlists
+md
+mechs
+memcache
+mylmtp
+nginx
+noout
+nsa
+pkey
+postlink
+postmulti
+proxywrite
+pubin
+pubkey
+queueID
+rsa
+secp
+stdin
+tarpit
+uncached
+unzipping
+windowsize
+xpostconf
diff --git a/postfix/src/dns/dns.h b/postfix/src/dns/dns.h
index 212e00893..bedbbdddc 100644
--- a/postfix/src/dns/dns.h
+++ b/postfix/src/dns/dns.h
@@ -54,6 +54,50 @@
#endif
+ /*
+ * Compatibility with systems that lack RES_USE_DNSSEC and RES_USE_EDNS0
+ */
+#ifndef RES_USE_DNSSEC
+#define RES_USE_DNSSEC 0
+#endif
+#ifndef RES_USE_EDNS0
+#define RES_USE_EDNS0 0
+#endif
+
+ /*
+ * TLSA: https://tools.ietf.org/html/rfc6698#section-7.1 RRSIG:
+ * http://tools.ietf.org/html/rfc4034#section-3
+ *
+ * We don't request RRSIG, but we get it "for free" when we send the DO-bit.
+ */
+#ifndef T_TLSA
+#define T_TLSA 52
+#endif
+#ifndef T_RRSIG
+#define T_RRSIG 46 /* Avoid unknown RR in logs */
+#endif
+
+ /*
+ * https://tools.ietf.org/html/rfc6698#section-7.2
+ */
+#define DNS_TLSA_USAGE_CA_CONSTRAINT 0
+#define DNS_TLSA_USAGE_SERVICE_CERTIFICATE_CONSTRAINT 1
+#define DNS_TLSA_USAGE_TRUST_ANCHOR_ASSERTION 2
+#define DNS_TLSA_USAGE_DOMAIN_ISSUED_CERTIFICATE 3
+
+ /*
+ * https://tools.ietf.org/html/rfc6698#section-7.3
+ */
+#define DNS_TLSA_SELECTOR_FULL_CERTIFICATE 0
+#define DNS_TLSA_SELECTOR_SUBJECTPUBLICKEYINFO 1
+
+ /*
+ * https://tools.ietf.org/html/rfc6698#section-7.4
+ */
+#define DNS_TLSA_MATCHING_TYPE_NO_HASH_USED 0
+#define DNS_TLSA_MATCHING_TYPE_SHA256 1
+#define DNS_TLSA_MATCHING_TYPE_SHA512 2
+
/*
* SunOS 4 needs this.
*/
@@ -88,6 +132,7 @@ typedef struct DNS_RR {
unsigned short type; /* T_A, T_CNAME, etc. */
unsigned short class; /* C_IN, etc. */
unsigned int ttl; /* always */
+ unsigned int validated; /* DNSSEC */
unsigned short pref; /* T_MX only */
struct DNS_RR *next; /* linkage */
size_t data_len; /* actual data size */
diff --git a/postfix/src/dns/dns_lookup.c b/postfix/src/dns/dns_lookup.c
index 4de86edb2..daaaa9e18 100644
--- a/postfix/src/dns/dns_lookup.c
+++ b/postfix/src/dns/dns_lookup.c
@@ -60,6 +60,10 @@
/* Search local domain and parent domains.
/* .IP RES_DEFNAMES
/* Append local domain to unqualified names.
+/* .IP RES_USE_DNSSEC
+/* Request DNSSEC validation. This flag is silently ignored
+/* when the system stub resolver API, resolver(3), does not
+/* implement DNSSEC.
/* .RE
/* .IP lflags
/* Multi-type request control for dns_lookup_l() and dns_lookup_v().
@@ -162,6 +166,7 @@
typedef struct DNS_REPLY {
unsigned char *buf; /* raw reply data */
size_t buf_len; /* reply buffer length */
+ int validated; /* DNSSEC AD bit */
int query_count; /* number of queries */
int answer_count; /* number of answers */
unsigned char *query_start; /* start of query data */
@@ -202,11 +207,26 @@ static int dns_query(const char *name, int type, int flags,
* Set search options: debugging, parent domain search, append local
* domain. Do not allow the user to control other features.
*/
-#define USER_FLAGS (RES_DEBUG | RES_DNSRCH | RES_DEFNAMES)
+#define USER_FLAGS (RES_DEBUG | RES_DNSRCH | RES_DEFNAMES | RES_USE_DNSSEC)
if ((flags & USER_FLAGS) != flags)
msg_panic("dns_query: bad flags: %d", flags);
- saved_options = (_res.options & USER_FLAGS);
+
+ /*
+ * Set extra options that aren't exposed to the application.
+ */
+#define XTRA_FLAGS (RES_USE_EDNS0)
+
+ if (flags & RES_USE_DNSSEC)
+ flags |= RES_USE_EDNS0;
+
+ /*
+ * Save and restore resolver options that we overwrite, to avoid
+ * surprising behavior in other code that also invokes the resolver.
+ */
+#define SAVE_FLAGS (USER_FLAGS | XTRA_FLAGS)
+
+ saved_options = (_res.options & SAVE_FLAGS);
/*
* Perform the lookup. Claim that the information cannot be found if and
@@ -260,6 +280,11 @@ static int dns_query(const char *name, int type, int flags,
* Initialize the reply structure. Some structure members are filled on
* the fly while the reply is being parsed.
*/
+#if RES_USE_DNSSEC != 0
+ reply->validated = (flags & RES_USE_DNSSEC) ? reply_header->ad : 0;
+#else
+ reply->validated = 0;
+#endif
reply->end = reply->buf + len;
reply->query_start = reply->buf + sizeof(HEADER);
reply->answer_start = 0;
@@ -360,6 +385,7 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
DNS_FIXED *fixed)
{
char temp[DNS_NAME_LEN];
+ char *tempbuf = temp;
ssize_t data_len;
unsigned pref = 0;
unsigned char *src;
@@ -418,6 +444,11 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
data_len = fixed->length;
break;
#endif
+
+ /*
+ * We impose the same length limit here as for DNS names. However,
+ * see T_TLSA discussion below.
+ */
case T_TXT:
data_len = MIN2(pos[0] + 1, MIN2(fixed->length + 1, sizeof(temp)));
for (src = pos + 1, dst = (unsigned char *) (temp);
@@ -427,9 +458,24 @@ static int dns_get_rr(DNS_RR **list, const char *orig_name, DNS_REPLY *reply,
}
*dst = 0;
break;
+
+ /*
+ * For a full certificate, fixed->length may be longer than
+ * sizeof(tmpbuf) == DNS_NAME_LEN. Since we don't need a decode
+ * buffer, just copy the raw data into the rr.
+ *
+ * XXX Reject replies with bogus length < 3.
+ *
+ * XXX What about enforcing a sane upper bound? The RFC 1035 hard
+ * protocol limit is the RRDATA length limit of 65535.
+ */
+ case T_TLSA:
+ data_len = fixed->length;
+ tempbuf = (char *) pos;
+ break;
}
*list = dns_rr_create(orig_name, rr_name, fixed->type, fixed->class,
- fixed->ttl, pref, temp, data_len);
+ fixed->ttl, pref, tempbuf, data_len);
return (DNS_OK);
}
@@ -450,7 +496,8 @@ static int dns_get_alias(DNS_REPLY *reply, unsigned char *pos,
/* dns_get_answer - extract answers from name server reply */
static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
- DNS_RR **rrlist, VSTRING *fqdn, char *cname, int c_len)
+ DNS_RR **rrlist, VSTRING *fqdn, char *cname, int c_len,
+ int *validate_mask)
{
char rr_name[DNS_NAME_LEN];
unsigned char *pos;
@@ -526,6 +573,7 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
if ((status = dns_get_rr(&rr, orig_name, reply, pos, rr_name,
&fixed)) == DNS_OK) {
resource_found++;
+ rr->validated = (reply->validated & *validate_mask);
*rrlist = dns_rr_append(*rrlist, rr);
} else if (not_found_status != DNS_RETRY)
not_found_status = status;
@@ -536,6 +584,7 @@ static int dns_get_answer(const char *orig_name, DNS_REPLY *reply, int type,
if (cname && c_len > 0)
if ((status = dns_get_alias(reply, pos, &fixed, cname, c_len)) != DNS_OK)
CORRUPT(status);
+ *validate_mask &= reply->validated;
}
pos += fixed.length;
}
@@ -562,6 +611,7 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
static DNS_REPLY reply;
int count;
int status;
+ int validate_mask = 1; /* May reset to 0 via CNAME expansion */
const char *orig_name = name;
/*
@@ -602,10 +652,12 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
/*
* Extract resource records of the requested type. Pick up CNAME
- * information just in case the requested data is not found.
+ * information just in case the requested data is not found. If any
+ * CNAME result is not validated, all consequent RRs are deemed not
+ * validated (the validate_mask is set to 0).
*/
status = dns_get_answer(orig_name, &reply, type, rrlist, fqdn,
- cname, c_len);
+ cname, c_len, &validate_mask);
switch (status) {
default:
if (why)
diff --git a/postfix/src/dns/dns_rr.c b/postfix/src/dns/dns_rr.c
index ef0b66377..1e566949d 100644
--- a/postfix/src/dns/dns_rr.c
+++ b/postfix/src/dns/dns_rr.c
@@ -123,6 +123,7 @@ DNS_RR *dns_rr_create(const char *qname, const char *rname,
rr->type = type;
rr->class = class;
rr->ttl = ttl;
+ rr->validated = 0;
rr->pref = pref;
if (data && data_len > 0)
memcpy(rr->data, data, data_len);
diff --git a/postfix/src/dns/dns_rr_eq_sa.in b/postfix/src/dns/dns_rr_eq_sa.in
index e980daa33..89834d5c6 100644
--- a/postfix/src/dns/dns_rr_eq_sa.in
+++ b/postfix/src/dns/dns_rr_eq_sa.in
@@ -1,4 +1,4 @@
spike.porcupine.org 168.100.189.2
spike.porcupine.org 168.100.189.3
-spike.porcupine.org 2001:240:587:0:2d0:b7ff:fe88:2ca7
-spike.porcupine.org 2001:240:587:0:2d0:b7ff:febe:ca9f
+spike.porcupine.org 2604:8d00:189::2
+spike.porcupine.org 2604:8d00:189::3
diff --git a/postfix/src/dns/dns_rr_eq_sa.ref b/postfix/src/dns/dns_rr_eq_sa.ref
index d85216492..668726692 100644
--- a/postfix/src/dns/dns_rr_eq_sa.ref
+++ b/postfix/src/dns/dns_rr_eq_sa.ref
@@ -1,24 +1,24 @@
-168.100.189.2 =?= 168.100.189.2
-tested by function: yes
-tested by macro: yes
2604:8d00:189::2 =?= 168.100.189.2
tested by function: no
tested by macro: no
-168.100.189.2 =?= 168.100.189.3
-tested by function: no
-tested by macro: no
+168.100.189.2 =?= 168.100.189.2
+tested by function: yes
+tested by macro: yes
2604:8d00:189::2 =?= 168.100.189.3
tested by function: no
tested by macro: no
-168.100.189.2 =?= 2001:240:587:0:2d0:b7ff:fe88:2ca7
+168.100.189.2 =?= 168.100.189.3
tested by function: no
tested by macro: no
-2604:8d00:189::2 =?= 2001:240:587:0:2d0:b7ff:fe88:2ca7
+2604:8d00:189::2 =?= 2604:8d00:189::2
+tested by function: yes
+tested by macro: yes
+168.100.189.2 =?= 2604:8d00:189::2
tested by function: no
tested by macro: no
-168.100.189.2 =?= 2001:240:587:0:2d0:b7ff:febe:ca9f
+2604:8d00:189::2 =?= 2604:8d00:189::3
tested by function: no
tested by macro: no
-2604:8d00:189::2 =?= 2001:240:587:0:2d0:b7ff:febe:ca9f
+168.100.189.2 =?= 2604:8d00:189::3
tested by function: no
tested by macro: no
diff --git a/postfix/src/dns/dns_strtype.c b/postfix/src/dns/dns_strtype.c
index 5be711353..92ff4b7e7 100644
--- a/postfix/src/dns/dns_strtype.c
+++ b/postfix/src/dns/dns_strtype.c
@@ -168,6 +168,12 @@ static struct dns_type_map dns_type_map[] = {
#ifdef T_MAILA
T_MAILA, "MAILA",
#endif
+#ifdef T_TLSA
+ T_TLSA, "TLSA",
+#endif
+#ifdef T_RRSIG
+ T_RRSIG, "RRSIG",
+#endif
#ifdef T_ANY
T_ANY, "ANY",
#endif
diff --git a/postfix/src/dns/test_dns_lookup.c b/postfix/src/dns/test_dns_lookup.c
index d7a80a482..da3b3758c 100644
--- a/postfix/src/dns/test_dns_lookup.c
+++ b/postfix/src/dns/test_dns_lookup.c
@@ -43,9 +43,10 @@
static void print_rr(DNS_RR *rr)
{
MAI_HOSTADDR_STR host;
+ size_t i;
while (rr) {
- printf("%s: ttl: %9d ", rr->rname, rr->ttl);
+ printf("%s: ad: %d, ttl: %9d ", rr->rname, rr->validated, rr->ttl);
switch (rr->type) {
case T_A:
#ifdef T_AAAA
@@ -69,6 +70,22 @@ static void print_rr(DNS_RR *rr)
printf("pref: %d %s: %s\n",
rr->pref, dns_strtype(rr->type), rr->data);
break;
+ case T_TLSA:
+ if (rr->data_len >= 3) {
+ uint8_t *ip = (uint8_t *) rr->data;
+ uint8_t usage = *ip++;
+ uint8_t selector = *ip++;
+ uint8_t mtype = *ip++;
+
+ printf("%s: %d %d %d ", dns_strtype(rr->type),
+ usage, selector, mtype);
+ for (i = 3; i < rr->data_len; ++i)
+ printf("%02x", *ip++);
+ putchar('\n');
+ } else {
+ printf("%s: truncated record\n", dns_strtype(rr->type));
+ }
+ break;
default:
msg_fatal("print_rr: don't know how to print type %s",
dns_strtype(rr->type));
@@ -99,7 +116,7 @@ int main(int argc, char **argv)
argv_free(types_argv);
name = argv[2];
msg_verbose = 1;
- switch (dns_lookup_v(name, RES_DEBUG, &rr, fqdn, why,
+ switch (dns_lookup_v(name, RES_DEBUG | RES_USE_DNSSEC, &rr, fqdn, why,
DNS_REQ_FLAG_NONE, types)) {
default:
msg_fatal("%s", vstring_str(why));
diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h
index 53aa582cb..1e368f8a5 100644
--- a/postfix/src/global/mail_params.h
+++ b/postfix/src/global/mail_params.h
@@ -206,6 +206,16 @@ extern char *var_fallback_relay;
#define DEF_DISABLE_DNS 0
extern bool var_disable_dns;
+#define SMTP_DNS_SUPPORT_DISABLED "disabled"
+#define SMTP_DNS_SUPPORT_ENABLED "enabled"
+#define SMTP_DNS_SUPPORT_DNSSEC "dnssec"
+
+#define VAR_SMTP_DNS_SUPPORT "smtp_dns_support_level"
+#define DEF_SMTP_DNS_SUPPORT ""
+#define VAR_LMTP_DNS_SUPPORT "lmtp_dns_support_level"
+#define DEF_LMTP_DNS_SUPPORT ""
+extern char *var_smtp_dns_support;
+
#define SMTP_HOST_LOOKUP_DNS "dns"
#define SMTP_HOST_LOOKUP_NATIVE "native"
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index ab74d7106..5409efba0 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 "20130318"
+#define MAIL_RELEASE_DATE "20130324"
#define MAIL_VERSION_NUMBER "2.11"
#ifdef SNAPSHOT
diff --git a/postfix/src/global/mbox_open.c b/postfix/src/global/mbox_open.c
index 7ccd08a5a..bd0fbb30f 100644
--- a/postfix/src/global/mbox_open.c
+++ b/postfix/src/global/mbox_open.c
@@ -194,9 +194,9 @@ MBOX *mbox_open(const char *path, int flags, mode_t mode, struct stat * st,
/*
* Sanity check: reportedly, GNU POP3D creates a new mailbox file and
* deletes the old one. This does not play well with software that opens
- * the mailbox first and then locks it, such as software that that uses
- * FCNTL or FLOCK locks on open file descriptors (some UNIX systems don't
- * use dotlock files).
+ * the mailbox first and then locks it, such as software that uses FCNTL
+ * or FLOCK locks on open file descriptors (some UNIX systems don't use
+ * dotlock files).
*
* To detect that GNU POP3D deletes the mailbox file we look at the target
* file hard-link count. Note that safe_open() guarantees a hard-link
diff --git a/postfix/src/smtp/lmtp_params.c b/postfix/src/smtp/lmtp_params.c
index 4f68cecbd..cb645d567 100644
--- a/postfix/src/smtp/lmtp_params.c
+++ b/postfix/src/smtp/lmtp_params.c
@@ -34,6 +34,7 @@
VAR_LMTP_BIND_ADDR6, DEF_LMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
VAR_LMTP_HELO_NAME, DEF_LMTP_HELO_NAME, &var_smtp_helo_name, 1, 0,
VAR_LMTP_HOST_LOOKUP, DEF_LMTP_HOST_LOOKUP, &var_smtp_host_lookup, 1, 0,
+ VAR_LMTP_DNS_SUPPORT, DEF_LMTP_DNS_SUPPORT, &var_smtp_dns_support, 0, 0,
VAR_LMTP_CACHE_DEST, DEF_LMTP_CACHE_DEST, &var_smtp_cache_dest, 0, 0,
VAR_SCACHE_SERVICE, DEF_SCACHE_SERVICE, &var_scache_service, 1, 0,
VAR_LMTP_EHLO_DIS_WORDS, DEF_LMTP_EHLO_DIS_WORDS, &var_smtp_ehlo_dis_words, 0, 0,
diff --git a/postfix/src/smtp/smtp.c b/postfix/src/smtp/smtp.c
index d91724716..26e581c0d 100644
--- a/postfix/src/smtp/smtp.c
+++ b/postfix/src/smtp/smtp.c
@@ -169,9 +169,7 @@
/* A mechanism to transform replies from remote SMTP servers one
/* line at a time.
/* .IP "\fBsmtp_skip_5xx_greeting (yes)\fR"
-/* Skip remote SMTP servers that greet with a 5XX status code (go away,
-/* do
-/* not try again later).
+/* Skip remote SMTP servers that greet with a 5XX status code.
/* .IP "\fBsmtp_skip_quit_response (yes)\fR"
/* Do not wait for the response to the SMTP QUIT command.
/* .PP
@@ -249,6 +247,10 @@
/* .IP "\fBsmtp_send_dummy_mail_auth (no)\fR"
/* Whether or not to append the "AUTH=<>" option to the MAIL
/* FROM command in SASL-authenticated SMTP sessions.
+/* .PP
+/* Available in Postfix version 2.11 and later:
+/* .IP "\fBsmtp_dns_support_level (empty)\fR"
+/* Level of DNS support in the Postfix SMTP client.
/* MIME PROCESSING CONTROLS
/* .ad
/* .fi
@@ -376,8 +378,7 @@
/* The verification depth for remote SMTP server certificates.
/* .IP "\fBsmtp_tls_secure_cert_match (nexthop, dot-nexthop)\fR"
/* How the Postfix SMTP client verifies the server certificate
-/* peername for the
-/* "secure" TLS security level.
+/* peername for the "secure" TLS security level.
/* .IP "\fBsmtp_tls_session_cache_database (empty)\fR"
/* Name of the file containing the optional Postfix SMTP client
/* TLS session cache.
@@ -626,8 +627,8 @@
/* .IP "\fBlmtp_lhlo_name ($myhostname)\fR"
/* The hostname to send in the LMTP LHLO command.
/* .IP "\fBsmtp_host_lookup (dns)\fR"
-/* What mechanisms the Postfix SMTP client uses to look up a host's IP
-/* address.
+/* What mechanisms the Postfix SMTP client uses to look up a host's
+/* IP address.
/* .IP "\fBsmtp_randomize_addresses (yes)\fR"
/* Randomize the order of equal-preference MX host addresses.
/* .IP "\fBsyslog_facility (mail)\fR"
@@ -848,6 +849,7 @@ char *var_smtp_body_chks;
char *var_smtp_resp_filter;
bool var_lmtp_assume_final;
char *var_smtp_dns_res_opt;
+char *var_smtp_dns_support;
bool var_smtp_rec_deadline;
bool var_smtp_dummy_mail_auth;
@@ -859,7 +861,9 @@ bool var_smtp_sasl_auth_soft_bounce;
/*
* Global variables.
*/
+int smtp_mode;
int smtp_host_lookup_mask;
+int smtp_dns_support;
STRING_LIST *smtp_cache_dest;
SCACHE *smtp_scache;
MAPS *smtp_ehlo_dis_maps;
@@ -973,18 +977,39 @@ static void post_init(char *unused_name, char **unused_argv)
SMTP_DNS_RES_OPT_DNSRCH, RES_DNSRCH,
0,
};
+ static const NAME_CODE dns_support[] = {
+ SMTP_DNS_SUPPORT_DISABLED, SMTP_DNS_DISABLED,
+ SMTP_DNS_SUPPORT_ENABLED, SMTP_DNS_ENABLED,
+#if (RES_USE_DNSSEC != 0) && (RES_USE_EDNS0 != 0)
+ SMTP_DNS_SUPPORT_DNSSEC, SMTP_DNS_DNSSEC,
+#endif
+ 0, SMTP_DNS_INVALID,
+ };
+
+ if (*var_smtp_dns_support == 0) {
+ /* Backwards compatible empty setting */
+ smtp_dns_support =
+ var_disable_dns ? SMTP_DNS_DISABLED : SMTP_DNS_ENABLED;
+ } else {
+ smtp_dns_support =
+ name_code(dns_support, NAME_CODE_FLAG_NONE, var_smtp_dns_support);
+ if (smtp_dns_support == SMTP_DNS_INVALID)
+ msg_fatal("invalid %s: \"%s\"", SMTP_X(DNS_SUPPORT),
+ var_smtp_dns_support);
+ var_disable_dns = (smtp_dns_support == SMTP_DNS_DISABLED);
+ }
/*
* Select hostname lookup mechanisms.
*/
- if (var_disable_dns)
+ if (smtp_dns_support == SMTP_DNS_DISABLED)
smtp_host_lookup_mask = SMTP_HOST_FLAG_NATIVE;
else
- smtp_host_lookup_mask = name_mask(VAR_SMTP_HOST_LOOKUP, lookup_masks,
- var_smtp_host_lookup);
+ smtp_host_lookup_mask =
+ name_mask(SMTP_X(HOST_LOOKUP), lookup_masks, var_smtp_host_lookup);
if (msg_verbose)
msg_info("host name lookup methods: %s",
- str_name_mask(VAR_SMTP_HOST_LOOKUP, lookup_masks,
+ str_name_mask(SMTP_X(HOST_LOOKUP), lookup_masks,
smtp_host_lookup_mask));
/*
@@ -1003,7 +1028,7 @@ static void post_init(char *unused_name, char **unused_argv)
/*
* Select DNS query flags.
*/
- smtp_dns_res_opt = name_mask(VAR_SMTP_DNS_RES_OPT, dns_res_opt_masks,
+ smtp_dns_res_opt = name_mask(SMTP_X(DNS_RES_OPT), dns_res_opt_masks,
var_smtp_dns_res_opt);
}
@@ -1032,7 +1057,7 @@ static void pre_init(char *unused_name, char **unused_argv)
smtp_sasl_initialize();
#else
msg_warn("%s is true, but SASL support is not compiled in",
- VAR_SMTP_SASL_ENABLE);
+ SMTP_X(SASL_ENABLE));
#endif
if (*var_smtp_tls_level != 0)
@@ -1063,7 +1088,6 @@ static void pre_init(char *unused_name, char **unused_argv)
if (use_tls || var_smtp_tls_per_site[0] || var_smtp_tls_policy[0]) {
#ifdef USE_TLS
TLS_CLIENT_INIT_PROPS props;
- int using_smtp = (strcmp(var_procname, "smtp") == 0);
/*
* We get stronger type safety and a cleaner interface by combining
@@ -1074,12 +1098,10 @@ static void pre_init(char *unused_name, char **unused_argv)
*/
smtp_tls_ctx =
TLS_CLIENT_INIT(&props,
- log_param = using_smtp ?
- VAR_SMTP_TLS_LOGLEVEL : VAR_LMTP_TLS_LOGLEVEL,
+ log_param = SMTP_X(TLS_LOGLEVEL),
log_level = var_smtp_tls_loglevel,
verifydepth = var_smtp_tls_scert_vd,
- cache_type = using_smtp ?
- TLS_MGR_SCACHE_SMTP : TLS_MGR_SCACHE_LMTP,
+ cache_type = X_SMTP(TLS_MGR_SCACHE),
cert_file = var_smtp_tls_cert_file,
key_file = var_smtp_tls_key_file,
dcert_file = var_smtp_tls_dcert_file,
@@ -1110,7 +1132,7 @@ static void pre_init(char *unused_name, char **unused_argv)
* EHLO keyword filter.
*/
if (*var_smtp_ehlo_dis_maps)
- smtp_ehlo_dis_maps = maps_create(VAR_SMTP_EHLO_DIS_MAPS,
+ smtp_ehlo_dis_maps = maps_create(SMTP_X(EHLO_DIS_MAPS),
var_smtp_ehlo_dis_maps,
DICT_FLAG_LOCK);
@@ -1118,7 +1140,7 @@ static void pre_init(char *unused_name, char **unused_argv)
* PIX bug workarounds.
*/
if (*var_smtp_pix_bug_maps)
- smtp_pix_bug_maps = maps_create(VAR_SMTP_PIX_BUG_MAPS,
+ smtp_pix_bug_maps = maps_create(SMTP_X(PIX_BUG_MAPS),
var_smtp_pix_bug_maps,
DICT_FLAG_LOCK);
@@ -1130,19 +1152,19 @@ static void pre_init(char *unused_name, char **unused_argv)
ext_prop_mask(VAR_PROP_EXTENSION, var_prop_extension);
if (*var_smtp_generic_maps)
smtp_generic_maps =
- maps_create(VAR_SMTP_GENERIC_MAPS, var_smtp_generic_maps,
+ maps_create(SMTP_X(GENERIC_MAPS), var_smtp_generic_maps,
DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
/*
* Header/body checks.
*/
smtp_header_checks = hbc_header_checks_create(
- VAR_SMTP_HEAD_CHKS, var_smtp_head_chks,
- VAR_SMTP_MIME_CHKS, var_smtp_mime_chks,
- VAR_SMTP_NEST_CHKS, var_smtp_nest_chks,
+ SMTP_X(HEAD_CHKS), var_smtp_head_chks,
+ SMTP_X(MIME_CHKS), var_smtp_mime_chks,
+ SMTP_X(NEST_CHKS), var_smtp_nest_chks,
smtp_hbc_callbacks);
smtp_body_checks = hbc_body_checks_create(
- VAR_SMTP_BODY_CHKS, var_smtp_body_chks,
+ SMTP_X(BODY_CHKS), var_smtp_body_chks,
smtp_hbc_callbacks);
/*
@@ -1160,7 +1182,7 @@ static void pre_init(char *unused_name, char **unused_argv)
smtp_addr_pref = name_code(addr_pref_map, NAME_CODE_FLAG_NONE,
var_smtp_addr_pref);
if (smtp_addr_pref < 0)
- msg_fatal("bad %s value: %s", VAR_SMTP_ADDR_PREF, var_smtp_addr_pref);
+ msg_fatal("bad %s value: %s", SMTP_X(ADDR_PREF), var_smtp_addr_pref);
}
}
@@ -1182,9 +1204,10 @@ MAIL_VERSION_STAMP_DECLARE;
int main(int argc, char **argv)
{
+ char *sane_procname;
+
#include "smtp_params.c"
#include "lmtp_params.c"
- int smtp_mode;
/*
* Fingerprint executables and core dumps.
@@ -1193,8 +1216,19 @@ int main(int argc, char **argv)
/*
* XXX At this point, var_procname etc. are not initialized.
+ *
+ * The process name, "smtp" or "lmtp", determines the protocol, the DSN
+ * server reply type, SASL service information lookup, and more. Prepare
+ * for the possibility there may be another personality.
*/
- smtp_mode = (strcmp(sane_basename((VSTRING *) 0, argv[0]), "smtp") == 0);
+ sane_procname = sane_basename((VSTRING *) 0, argv[0]);
+ if (strcmp(sane_procname, "smtp") == 0)
+ smtp_mode = 1;
+ else if (strcmp(sane_procname, "lmtp") == 0)
+ smtp_mode = 0;
+ else
+ msg_fatal("unexpected process name \"%s\" - "
+ "specify \"smtp\" or \"lmtp\"", var_procname);
/*
* Initialize with the LMTP or SMTP parameter name space.
diff --git a/postfix/src/smtp/smtp.h b/postfix/src/smtp/smtp.h
index 7c087824d..cef94edb9 100644
--- a/postfix/src/smtp/smtp.h
+++ b/postfix/src/smtp/smtp.h
@@ -140,7 +140,7 @@ typedef struct SMTP_STATE {
*/
#define SMTP_MISC_FLAG_LOOP_DETECT (1<<0)
#define SMTP_MISC_FLAG_IN_STARTTLS (1<<1)
-#define SMTP_MISC_FLAG_USE_LMTP (1<<2)
+#define SMTP_MISC_FLAG_TLSA_HOST (1<<2)
#define SMTP_MISC_FLAG_FIRST_NEXTHOP (1<<3)
#define SMTP_MISC_FLAG_FINAL_NEXTHOP (1<<4)
#define SMTP_MISC_FLAG_FINAL_SERVER (1<<5)
@@ -170,6 +170,13 @@ extern int smtp_host_lookup_mask; /* host lookup methods to use */
#define SMTP_HOST_FLAG_DNS (1<<0)
#define SMTP_HOST_FLAG_NATIVE (1<<1)
+extern int smtp_dns_support; /* dns support level */
+
+#define SMTP_DNS_INVALID (-1) /* smtp_dns_support_level = */
+#define SMTP_DNS_DISABLED 0 /* smtp_dns_support_level = disabled */
+#define SMTP_DNS_ENABLED 1 /* smtp_dns_support_level = enabled */
+#define SMTP_DNS_DNSSEC 2 /* smtp_dns_support_level = dnssec */
+
extern SCACHE *smtp_scache; /* connection cache instance */
extern STRING_LIST *smtp_cache_dest; /* cached destinations */
@@ -257,9 +264,10 @@ extern void smtp_tls_list_init(void);
#endif
/*
- * What's in a name?
+ * What's in a name? With DANE TLSA we need the rr->rname (if validated).
*/
-#define SMTP_HNAME(rr) (var_smtp_cname_overr ? (rr)->rname : (rr)->qname)
+#define SMTP_HNAME(rr) ( (var_smtp_cname_overr || rr->validated) ? \
+ (rr)->rname : (rr)->qname )
/*
* smtp_connect.c
@@ -465,6 +473,11 @@ extern int smtp_map11_internal(VSTRING *, MAPS *, int);
#define STR(s) vstring_str(s)
#define LEN(s) VSTRING_LEN(s)
+extern int smtp_mode;
+
+#define SMTP_X(x) (smtp_mode ? VAR_SMTP_##x : VAR_LMTP_##x)
+#define X_SMTP(x) (smtp_mode ? x##_SMTP : x##_LMTP)
+
/* LICENSE
/* .ad
/* .fi
diff --git a/postfix/src/smtp/smtp_addr.c b/postfix/src/smtp/smtp_addr.c
index 811d18461..4f9853e13 100644
--- a/postfix/src/smtp/smtp_addr.c
+++ b/postfix/src/smtp/smtp_addr.c
@@ -120,7 +120,7 @@ static void smtp_print_addr(const char *what, DNS_RR *addr_list)
/* smtp_addr_one - address lookup for one host name */
-static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host,
+static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host, int res_opt,
unsigned pref, DSN_BUF *why)
{
const char *myname = "smtp_addr_one";
@@ -155,7 +155,8 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, const char *host,
* should not clobber a soft error text and status code.
*/
if (smtp_host_lookup_mask & SMTP_HOST_FLAG_DNS) {
- switch (dns_lookup_v(host, smtp_dns_res_opt, &addr, (VSTRING *) 0,
+ res_opt |= smtp_dns_res_opt;
+ switch (dns_lookup_v(host, res_opt, &addr, (VSTRING *) 0,
why->reason, DNS_REQ_FLAG_NONE,
proto_info->dns_atype_list)) {
case DNS_OK:
@@ -236,6 +237,7 @@ static DNS_RR *smtp_addr_list(DNS_RR *mx_names, DSN_BUF *why)
{
DNS_RR *addr_list = 0;
DNS_RR *rr;
+ int res_opt = mx_names->validated ? RES_USE_DNSSEC : 0;
/*
* As long as we are able to look up any host address, we ignore problems
@@ -261,7 +263,8 @@ static DNS_RR *smtp_addr_list(DNS_RR *mx_names, DSN_BUF *why)
for (rr = mx_names; rr; rr = rr->next) {
if (rr->type != T_MX)
msg_panic("smtp_addr_list: bad resource type: %d", rr->type);
- addr_list = smtp_addr_one(addr_list, (char *) rr->data, rr->pref, why);
+ addr_list = smtp_addr_one(addr_list, (char *) rr->data, res_opt,
+ rr->pref, why);
}
return (addr_list);
}
@@ -344,6 +347,7 @@ DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
DNS_RR *self = 0;
unsigned best_pref;
unsigned best_found;
+ int r = 0; /* Resolver flags */
dsb_reset(why); /* Paranoia */
@@ -355,8 +359,10 @@ DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
/*
* Sanity check.
*/
- if (var_disable_dns)
+ if (smtp_dns_support == SMTP_DNS_DISABLED)
msg_panic("smtp_domain_addr: DNS lookup is disabled");
+ if (smtp_dns_support == SMTP_DNS_DNSSEC)
+ r |= RES_USE_DNSSEC;
/*
* Look up the mail exchanger hosts listed for this name. Sort the
@@ -400,7 +406,7 @@ DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
* at hostnames provides a partial solution for MX hosts behind a NAT
* gateway.
*/
- switch (dns_lookup(name, T_MX, 0, &mx_names, (VSTRING *) 0, why->reason)) {
+ switch (dns_lookup(name, T_MX, r, &mx_names, (VSTRING *) 0, why->reason)) {
default:
dsb_status(why, "4.4.3");
if (var_ign_mx_lookup_err)
@@ -477,15 +483,19 @@ DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
DNS_RR *smtp_host_addr(const char *host, int misc_flags, DSN_BUF *why)
{
DNS_RR *addr_list;
+ int res_opt = 0;
dsb_reset(why); /* Paranoia */
+ if (smtp_dns_support == SMTP_DNS_DNSSEC)
+ res_opt |= RES_USE_DNSSEC;
+
/*
* If the host is specified by numerical address, just convert the
* address to internal form. Otherwise, the host is specified by name.
*/
#define PREF0 0
- addr_list = smtp_addr_one((DNS_RR *) 0, host, PREF0, why);
+ addr_list = smtp_addr_one((DNS_RR *) 0, host, res_opt, PREF0, why);
if (addr_list
&& (misc_flags & SMTP_MISC_FLAG_LOOP_DETECT)
&& smtp_find_self(addr_list) != 0) {
diff --git a/postfix/src/smtp/smtp_chat.c b/postfix/src/smtp/smtp_chat.c
index cad15c4bf..11dc90998 100644
--- a/postfix/src/smtp/smtp_chat.c
+++ b/postfix/src/smtp/smtp_chat.c
@@ -359,14 +359,12 @@ SMTP_RESP *smtp_chat_resp(SMTP_SESSION *session)
if (session->features & SMTP_FEATURE_PIPELINING) {
msg_warn("%s: non-%s response from %s: %.100s",
session->state->request->queue_id,
- (session->state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) ?
- "LMTP" : "ESMTP", session->namaddrport,
- STR(session->buffer));
+ smtp_mode ? "ESMTP" : "LMTP",
+ session->namaddrport, STR(session->buffer));
if (var_helpful_warnings)
msg_warn("to prevent loss of mail, turn off command pipelining "
"for %s with the %s parameter", session->addr,
- (session->state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) ?
- VAR_LMTP_EHLO_DIS_MAPS : VAR_SMTP_EHLO_DIS_MAPS);
+ SMTP_X(EHLO_DIS_MAPS));
}
}
@@ -469,9 +467,7 @@ void smtp_chat_notify(SMTP_SESSION *session)
mail_addr_mail_daemon());
post_mail_fprintf(notice, "To: %s (Postmaster)", var_error_rcpt);
post_mail_fprintf(notice, "Subject: %s %s client: errors from %s",
- var_mail_name,
- (session->state->misc_flags &
- SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "SMTP",
+ var_mail_name, smtp_mode ? "SMTP" : "LMTP",
session->namaddrport);
post_mail_fputs(notice, "");
post_mail_fprintf(notice, "Unexpected response from %s.",
diff --git a/postfix/src/smtp/smtp_connect.c b/postfix/src/smtp/smtp_connect.c
index 2abb49ccb..c04974206 100644
--- a/postfix/src/smtp/smtp_connect.c
+++ b/postfix/src/smtp/smtp_connect.c
@@ -209,12 +209,12 @@ static SMTP_SESSION *smtp_connect_addr(const char *destination, DNS_RR *addr,
#ifdef HAS_IPV6
if (sa->sa_family == AF_INET6) {
bind_addr = var_smtp_bind_addr6;
- bind_var = VAR_SMTP_BIND_ADDR6;
+ bind_var = SMTP_X(BIND_ADDR6);
} else
#endif
if (sa->sa_family == AF_INET) {
bind_addr = var_smtp_bind_addr;
- bind_var = VAR_SMTP_BIND_ADDR;
+ bind_var = SMTP_X(BIND_ADDR);
} else
bind_var = bind_addr = "";
if (*bind_addr) {
@@ -272,6 +272,9 @@ static SMTP_SESSION *smtp_connect_addr(const char *destination, DNS_RR *addr,
msg_info("%s: trying: %s[%s] port %d...",
myname, SMTP_HNAME(addr), hostaddr.buf, ntohs(port));
+ if (addr->validated)
+ sess_flags |= SMTP_MISC_FLAG_TLSA_HOST;
+
return (smtp_connect_sock(sock, sa, salen, SMTP_HNAME(addr), hostaddr.buf,
port, destination, why, sess_flags));
}
@@ -718,7 +721,8 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
if (sites->argc == 0)
msg_panic("null destination: \"%s\"", nexthop);
non_fallback_sites = sites->argc;
- if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0)
+ /* When we are lmtp(8) var_fallback_relay is null */
+ if (smtp_mode)
argv_split_append(sites, var_fallback_relay, ", \t\r\n");
/*
@@ -776,12 +780,12 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
*/
if (msg_verbose)
msg_info("connecting to %s port %d", domain, ntohs(port));
- if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+ if (smtp_mode) {
if (ntohs(port) == IPPORT_SMTP)
state->misc_flags |= SMTP_MISC_FLAG_LOOP_DETECT;
else
state->misc_flags &= ~SMTP_MISC_FLAG_LOOP_DETECT;
- lookup_mx = (var_disable_dns == 0 && *dest != '[');
+ lookup_mx = (smtp_dns_support != SMTP_DNS_DISABLED && *dest != '[');
} else
lookup_mx = 0;
if (!lookup_mx) {
@@ -972,8 +976,7 @@ static void smtp_connect_inet(SMTP_STATE *state, const char *nexthop,
* Pay attention to what could be configuration problems, and pretend
* that these are recoverable rather than bouncing the mail.
*/
- else if (!SMTP_HAS_SOFT_DSN(why)
- && (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+ else if (!SMTP_HAS_SOFT_DSN(why) && smtp_mode) {
/*
* The fall-back destination did not resolve as expected, or it
@@ -1041,7 +1044,7 @@ int smtp_connect(SMTP_STATE *state)
* With LMTP we have direct-to-host delivery only. The destination may
* have multiple IP addresses.
*/
- if (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) {
+ if (!smtp_mode) {
if (strncmp(destination, "unix:", 5) == 0) {
smtp_connect_local(state, destination + 5);
} else {
diff --git a/postfix/src/smtp/smtp_params.c b/postfix/src/smtp/smtp_params.c
index e4b841007..cd25fdc4f 100644
--- a/postfix/src/smtp/smtp_params.c
+++ b/postfix/src/smtp/smtp_params.c
@@ -35,6 +35,7 @@
VAR_SMTP_BIND_ADDR6, DEF_SMTP_BIND_ADDR6, &var_smtp_bind_addr6, 0, 0,
VAR_SMTP_HELO_NAME, DEF_SMTP_HELO_NAME, &var_smtp_helo_name, 1, 0,
VAR_SMTP_HOST_LOOKUP, DEF_SMTP_HOST_LOOKUP, &var_smtp_host_lookup, 1, 0,
+ VAR_SMTP_DNS_SUPPORT, DEF_SMTP_DNS_SUPPORT, &var_smtp_dns_support, 0, 0,
VAR_SMTP_CACHE_DEST, DEF_SMTP_CACHE_DEST, &var_smtp_cache_dest, 0, 0,
VAR_SCACHE_SERVICE, DEF_SCACHE_SERVICE, &var_scache_service, 1, 0,
VAR_SMTP_EHLO_DIS_WORDS, DEF_SMTP_EHLO_DIS_WORDS, &var_smtp_ehlo_dis_words, 0, 0,
diff --git a/postfix/src/smtp/smtp_proto.c b/postfix/src/smtp/smtp_proto.c
index e1775b1cf..cd5299e65 100644
--- a/postfix/src/smtp/smtp_proto.c
+++ b/postfix/src/smtp/smtp_proto.c
@@ -347,10 +347,10 @@ int smtp_helo(SMTP_STATE *state)
&& (pix_bug_words =
maps_find(smtp_pix_bug_maps,
state->session->addr, 0)) != 0) {
- pix_bug_source = VAR_SMTP_PIX_BUG_MAPS;
+ pix_bug_source = SMTP_X(PIX_BUG_MAPS);
} else {
pix_bug_words = var_smtp_pix_bug_words;
- pix_bug_source = VAR_SMTP_PIX_BUG_WORDS;
+ pix_bug_source = SMTP_X(PIX_BUG_WORDS);
}
if (*pix_bug_words) {
pix_bug_mask = name_mask_opt(pix_bug_source, pix_bug_table,
@@ -381,7 +381,7 @@ int smtp_helo(SMTP_STATE *state)
} else if (strcasecmp(word, "ESMTP") == 0)
session->features |= SMTP_FEATURE_ESMTP;
}
- if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+ if (smtp_mode) {
if (var_smtp_always_ehlo
&& (session->features & SMTP_FEATURE_PIX_NO_ESMTP) == 0)
session->features |= SMTP_FEATURE_ESMTP;
@@ -405,7 +405,7 @@ int smtp_helo(SMTP_STATE *state)
* Return the compliment. Fall back to SMTP if our ESMTP recognition
* heuristic failed.
*/
- if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+ if (smtp_mode) {
where = "performing the EHLO handshake";
if (session->features & SMTP_FEATURE_ESMTP) {
smtp_chat_cmd(session, "EHLO %s", var_smtp_helo_name);
@@ -622,8 +622,8 @@ int smtp_helo(SMTP_STATE *state)
}
if (msg_verbose)
msg_info("Using %s PIPELINING, TCP send buffer size is %d, "
- "PIPELINING buffer size is %d", (state->misc_flags &
- SMTP_MISC_FLAG_USE_LMTP) ? "LMTP" : "ESMTP",
+ "PIPELINING buffer size is %d",
+ smtp_mode ? "ESMTP" : "LMTP",
tcp_bufsize, PIPELINING_BUFSIZE);
}
#ifdef USE_TLS
@@ -1662,7 +1662,7 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
"unexpected server message");
msg_warn("server %s violates %s policy",
session->namaddr,
- VAR_SMTP_TLS_BLK_EARLY_MAIL_REPLY);
+ SMTP_X(TLS_BLK_EARLY_MAIL_REPLY));
mail_from_rejected = 1;
}
#endif
@@ -1695,7 +1695,7 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
#endif
rcpt = request->rcpt_list.info + recv_rcpt;
if (resp->code / 100 == 2) {
- if (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) {
+ if (!smtp_mode) {
if (survivors == 0)
survivors = (int *)
mymalloc(request->rcpt_list.len
@@ -1752,7 +1752,7 @@ static int smtp_loop(SMTP_STATE *state, NOCLOBBER int send_state,
*/
case SMTP_STATE_DOT:
GETTIMEOFDAY(&request->msg_stats.deliver_done);
- if ((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0) {
+ if (smtp_mode) {
if (nrcpt > 0) {
if (resp->code / 100 != 2) {
smtp_mesg_fail(state, session->host, resp,
diff --git a/postfix/src/smtp/smtp_rcpt.c b/postfix/src/smtp/smtp_rcpt.c
index ebfb5e328..ec6d2a47c 100644
--- a/postfix/src/smtp/smtp_rcpt.c
+++ b/postfix/src/smtp/smtp_rcpt.c
@@ -152,7 +152,7 @@ void smtp_rcpt_done(SMTP_STATE *state, SMTP_RESP *resp, RECIPIENT *rcpt)
* the sake of "performance".
*/
if ((session->features & SMTP_FEATURE_DSN) == 0
- && (state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) != 0
+ && !smtp_mode
&& var_lmtp_assume_final != 0)
dsn_action = "delivered";
diff --git a/postfix/src/smtp/smtp_sasl_glue.c b/postfix/src/smtp/smtp_sasl_glue.c
index 7ba70bb1d..1cf6adac9 100644
--- a/postfix/src/smtp/smtp_sasl_glue.c
+++ b/postfix/src/smtp/smtp_sasl_glue.c
@@ -181,7 +181,7 @@ int smtp_sasl_passwd_lookup(SMTP_SESSION *session)
* the MX hostname.
*/
smtp_sasl_passwd_map->error = 0;
- if (((state->misc_flags & SMTP_MISC_FLAG_USE_LMTP) == 0
+ if ((smtp_mode
&& var_smtp_sender_auth && state->request->sender[0]
&& (value = mail_addr_find(smtp_sasl_passwd_map,
state->request->sender, (char **) 0)) != 0)
@@ -205,7 +205,7 @@ int smtp_sasl_passwd_lookup(SMTP_SESSION *session)
return (1);
} else if (smtp_sasl_passwd_map->error) {
msg_warn("%s: %s lookup error",
- state->request->queue_id, smtp_sasl_passwd_map->title);
+ state->request->queue_id, smtp_sasl_passwd_map->title);
vstream_longjmp(session->stream, SMTP_ERR_DATA);
} else {
if (msg_verbose)
@@ -227,7 +227,7 @@ void smtp_sasl_initialize(void)
msg_panic("smtp_sasl_initialize: repeated call");
if (*var_smtp_sasl_passwd == 0)
msg_fatal("specify a password table via the `%s' configuration parameter",
- VAR_SMTP_SASL_PASSWD);
+ SMTP_X(SASL_PASSWD));
/*
* Open the per-host password table and initialize the SASL library. Use
@@ -257,7 +257,7 @@ void smtp_sasl_initialize(void)
var_smtp_sasl_auth_cache_time);
#else
msg_warn("not compiled with TLS support -- "
- "ignoring the " VAR_SMTP_SASL_AUTH_CACHE_NAME " setting");
+ "ignoring the %s setting", SMTP_X(SASL_AUTH_CACHE_NAME));
#endif
}
}
diff --git a/postfix/src/smtp/smtp_sasl_proto.c b/postfix/src/smtp/smtp_sasl_proto.c
index 91e8c964b..7676f3334 100644
--- a/postfix/src/smtp/smtp_sasl_proto.c
+++ b/postfix/src/smtp/smtp_sasl_proto.c
@@ -177,17 +177,15 @@ int smtp_sasl_helo_login(SMTP_STATE *state)
/* Session reuse is disabled. */
} else {
#ifndef USE_TLS
- smtp_sasl_start(session, VAR_SMTP_SASL_OPTS,
- var_smtp_sasl_opts);
+ smtp_sasl_start(session, SMTP_X(SASL_OPTS), var_smtp_sasl_opts);
#else
if (session->tls_context == 0)
- smtp_sasl_start(session, VAR_SMTP_SASL_OPTS,
- var_smtp_sasl_opts);
+ smtp_sasl_start(session, SMTP_X(SASL_OPTS), var_smtp_sasl_opts);
else if (TLS_CERT_IS_MATCHED(session->tls_context))
- smtp_sasl_start(session, VAR_SMTP_SASL_TLSV_OPTS,
+ smtp_sasl_start(session, SMTP_X(SASL_TLSV_OPTS),
var_smtp_sasl_tlsv_opts);
else
- smtp_sasl_start(session, VAR_SMTP_SASL_TLS_OPTS,
+ smtp_sasl_start(session, SMTP_X(SASL_TLS_OPTS),
var_smtp_sasl_tls_opts);
#endif
if (smtp_sasl_authenticate(session, why) <= 0) {
diff --git a/postfix/src/smtp/smtp_session.c b/postfix/src/smtp/smtp_session.c
index e476ee07b..5b72402f5 100644
--- a/postfix/src/smtp/smtp_session.c
+++ b/postfix/src/smtp/smtp_session.c
@@ -66,6 +66,8 @@
/* .IP flags
/* Zero or more of the following:
/* .RS
+/* .IP SMTP_MISC_FLAG_TLSA_HOST
+/* The hostname is DNSSEC-validated.
/* .IP SMTP_MISC_FLAG_CONN_LOAD
/* Enable re-use of cached SMTP or LMTP connections.
/* .IP SMTP_MISC_FLAG_CONN_STORE
@@ -140,15 +142,15 @@ static MAPS *tls_per_site; /* lookup table(s) */
void smtp_tls_list_init(void)
{
if (*var_smtp_tls_policy) {
- tls_policy = maps_create(VAR_SMTP_TLS_POLICY, var_smtp_tls_policy,
+ tls_policy = maps_create(SMTP_X(TLS_POLICY), var_smtp_tls_policy,
DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
if (*var_smtp_tls_per_site)
msg_warn("%s ignored when %s is not empty.",
- VAR_SMTP_TLS_PER_SITE, VAR_SMTP_TLS_POLICY);
+ SMTP_X(TLS_PER_SITE), SMTP_X(TLS_POLICY));
return;
}
if (*var_smtp_tls_per_site) {
- tls_per_site = maps_create(VAR_SMTP_TLS_PER_SITE, var_smtp_tls_per_site,
+ tls_per_site = maps_create(SMTP_X(TLS_PER_SITE), var_smtp_tls_per_site,
DICT_FLAG_LOCK | DICT_FLAG_FOLD_FIX);
}
}
diff --git a/postfix/src/smtp/smtp_state.c b/postfix/src/smtp/smtp_state.c
index b396397a1..9699a053b 100644
--- a/postfix/src/smtp/smtp_state.c
+++ b/postfix/src/smtp/smtp_state.c
@@ -77,24 +77,6 @@ SMTP_STATE *smtp_state_alloc(void)
state->cache_used = 0;
}
state->why = dsb_create();
-
- /*
- * The process name, "smtp" or "lmtp", is also used as the DSN server
- * reply type and for SASL service information lookup. Since all three
- * external representations are identical there is no reason to transform
- * from some external form X to some Postfix-specific canonical internal
- * form, and then to transform from the internal form to external forms Y
- * and Z.
- */
- if (strcmp(var_procname, "lmtp") == 0) {
- state->misc_flags |= SMTP_MISC_FLAG_USE_LMTP;
- } else if (strcmp(var_procname, "smtp") == 0) {
- /* void */
- } else {
- msg_fatal("unexpected process name \"%s\" - "
- "specify \"smtp\" or \"lmtp\"",
- var_procname);
- }
return (state);
}
diff --git a/postfix/src/tls/tls_client.c b/postfix/src/tls/tls_client.c
index fc2684944..2252b00fa 100644
--- a/postfix/src/tls/tls_client.c
+++ b/postfix/src/tls/tls_client.c
@@ -994,7 +994,7 @@ TLS_SESS_STATE *tls_client_start(const TLS_CLIENT_START_PROPS *props)
if (TLScontext->log_mask &
(TLS_LOG_CERTMATCH | TLS_LOG_VERBOSE | TLS_LOG_PEERCERT))
msg_info("%s: subject_CN=%s, issuer_CN=%s, "
- "fingerprint %s, pkey_fingerprint=%s", props->namaddr,
+ "fingerprint=%s, pkey_fingerprint=%s", props->namaddr,
TLScontext->peer_CN, TLScontext->issuer_CN,
TLScontext->peer_fingerprint,
TLScontext->peer_pkey_fprint);
diff --git a/postfix/src/tls/tls_verify.c b/postfix/src/tls/tls_verify.c
index ea3bfb960..9d909fe63 100644
--- a/postfix/src/tls/tls_verify.c
+++ b/postfix/src/tls/tls_verify.c
@@ -58,7 +58,7 @@
/* other respects the function behaves as tls_fingerprint().
/* The var_tls_bc_pkey_fprint variable enables an incorrect
/* algorithm that was used in Postfix versions 2.9.[0-5].
-/*
+/*
/* tls_verify_callback() is called several times (directly or
/* indirectly) from crypto/x509/x509_vfy.c. It is called as
/* a final check, and if it returns "0", the handshake is
@@ -479,7 +479,7 @@ char *tls_peer_CN(X509 *peercert, const TLS_SESS_STATE *TLScontext)
char *cn;
cn = tls_text_name(X509_get_subject_name(peercert), NID_commonName,
- "subject CN", TLScontext, DO_GRIPE);
+ "subject CN", TLScontext, DONT_GRIPE);
return (cn ? cn : mystrdup(""));
}
@@ -499,7 +499,7 @@ char *tls_issuer_CN(X509 *peer, const TLS_SESS_STATE *TLScontext)
if ((cn = tls_text_name(name, NID_commonName,
"issuer CN", TLScontext, DONT_GRIPE)) == 0)
cn = tls_text_name(name, NID_organizationName,
- "issuer Organization", TLScontext, DO_GRIPE);
+ "issuer Organization", TLScontext, DONT_GRIPE);
return (cn ? cn : mystrdup(""));
}
@@ -521,9 +521,9 @@ static char *tls_fprint(const char *buf, int len, const char *dgst)
mdctx = EVP_MD_CTX_create();
if (EVP_DigestInit_ex(mdctx, md_alg, NULL) == 0
- || EVP_DigestUpdate(mdctx, buf, len) == 0
- || EVP_DigestFinal_ex(mdctx, md_buf, &md_len) == 0)
- msg_fatal("%s: error computing %s message digest", myname, dgst);
+ || EVP_DigestUpdate(mdctx, buf, len) == 0
+ || EVP_DigestFinal_ex(mdctx, md_buf, &md_len) == 0)
+ msg_fatal("%s: error computing %s message digest", myname, dgst);
EVP_MD_CTX_destroy(mdctx);
/* Check for OpenSSL contract violation */
@@ -551,9 +551,9 @@ char *tls_fingerprint(X509 *peercert, const char *dgst)
len = i2d_X509(peercert, NULL);
buf2 = buf = mymalloc(len);
- i2d_X509(peercert, (unsigned char **)&buf2);
+ i2d_X509(peercert, (unsigned char **) &buf2);
if (buf2 - buf != len)
- msg_panic("i2d_X509 invalid result length");
+ msg_panic("i2d_X509 invalid result length");
result = tls_fprint(buf, len, dgst);
myfree(buf);
diff --git a/postfix/src/util/open_limit.c b/postfix/src/util/open_limit.c
index fa08b762b..7aec951b9 100644
--- a/postfix/src/util/open_limit.c
+++ b/postfix/src/util/open_limit.c
@@ -34,6 +34,11 @@
#include
#include
+#ifdef MACOSX
+#include
+#define MAX_FILES_PER_PROC "kern.maxfilesperproc"
+#endif
+
/* Application-specific. */
#include "iostuff.h"
@@ -63,6 +68,21 @@ int open_limit(int limit)
if (getrlimit(RLIMIT_NOFILE, &rl) < 0)
return (-1);
if (limit > 0) {
+
+ /*
+ * MacOSX incorrectly reports rlim_max as RLIM_INFINITY. The true
+ * hard limit is finite and equals the kern.maxfilesperproc value.
+ */
+#ifdef MACOSX
+ int max_files_per_proc;
+ size_t len = sizeof(max_files_per_proc);
+
+ if (sysctlbyname(MAX_FILES_PER_PROC, &max_files_per_proc, &len,
+ (void *) 0, (size_t) 0) < 0)
+ return (-1);
+ if (limit > max_files_per_proc)
+ limit = max_files_per_proc;
+#endif
if (limit > rl.rlim_max)
rl.rlim_cur = rl.rlim_max;
else