20130319
- Postfix support for LMDB databases is withdrawn due to the
+ Postfix support for LMDB databases 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 exceptions all
- "out of storage" failure modes are resolved by increasing
- the 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.
+
+20130322
+
+ Documentation: smtp_skip_5xx_greeting wording updated to
+ reflect text in RFC 2821, which appears to say that a 554
+ greeting is not a hard delivery error (note that RFC 2821
+ was published later than smtp_skip_5xx_greeting). File:
+ proto/postconf.proto.
+
+20130324
+
+ Workaround: MacOS 10.8 (Darwin 12) getrlimit(RLIMIT_NOFILE)
+ incorrectly reports that rlim_max, the hard limit on the
+ number of open files per process, is equal to RLIM_INFINITY
+ (i.e. no limit is enforced). In reality, setrlimit(RLIMIT_NOFILE)
+ rejects requests where rlim_cur, the current limit, contains
+ any value > kern.maxfilesperproc. Axel Luttgens. File:
+ util/open_limit.c.
+
+ Portability: MacOS 10.8 (Darwin 12) kqueue support works.
+ Axel Luttgens. Files: makedefs.
+
+20130324
+
+ Support for anonymous certificates. Viktor Dukhovni. File:
+ tls/tls_verify.c.
+
+ Feature: support for DNSSEC-validated lookups and TLSA
+ RRsets. Viktor Dukhovni. Files: src/dns/Makefile.in,
+ src/dns/dns.h, src/dns/dns_lookup.c, src/dns/dns_rr.c,
+ src/dns/dns_strtype.c, src/dns/test_dns_lookup.c,
+
+ Cleanup: the personality switch between "smtp" and "lmtp".
+ This streamlies the swicth in the SMTP/LMTP protocol, DNS
+ MX lookups, and configuration parameter names in error
+ messages. Viktor Dukhovni. Files: src/smtp/smtp.c,
+ src/smtp/smtp.h, src/smtp/smtp_chat.c, src/smtp/smtp_connect.c,
+ src/smtp/smtp_proto.c, src/smtp/smtp_rcpt.c,
+ src/smtp/smtp_sasl_glue.c, src/smtp/smtp_sasl_proto.c,
+ src/smtp/smtp_session.c, src/smtp/smtp_state.c.
+
+ Feature: replace disable_dns_lookups with smtp_dns_support_level,
+ enable secure DNSSEC lookups in the Postfix SMTP client, and use
+ the DNSSEC-validated remote SMTP server name to select the SMTP
+ and TLS policies. Viktor Dukhovni. Files: src/dns/Makefile.in,
+ src/dns/dns.h, src/dns/dns_lookup.c, src/dns/dns_rr.c,
+ src/dns/dns_strtype.c, src/dns/test_dns_lookup.c.
I\bIn\bnt\btr\bro\bod\bdu\buc\bct\bti\bio\bon\bn
Note:
- Postfix support for LMDB databases is withdrawn due to the existence of a
+ Postfix support for LMDB databases 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.
+ 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". OpenLDAP LMDB implements the
3. Missing pthread library trouble.
-Note:
- The Postfix LMDB client implementation introduces unexpected failure modes
- that don't exist with other Postfix databases. Don't just yet abandon CDB.
+ 4. Unexpected failure modes that don't exist with other Postfix databases.
B\bBu\bui\bil\bld\bdi\bin\bng\bg P\bPo\bos\bst\btf\bfi\bix\bx w\bwi\bit\bth\bh O\bOp\bpe\ben\bnL\bLD\bDA\bAP\bP L\bLM\bMD\bDB\bB s\bsu\bup\bpp\bpo\bor\brt\bt
Major changes with snapshot 20130319
====================================
-Postfix support for LMDB databases is withdrawn due to the existence
+Postfix support for LMDB databases 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.
+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.
Major changes with snapshot 20130315
====================================
Spellcheck and double-word check.
+ We have smtp_host_lookup, smtp_dns_resolver_options, and
+ now smtp_dns_support_level. Of these, smtp_dns_resolver_options
+ is orthogonal but the rest has overlap.
+
+ There needs to be support for automatic migration from the
+ deprecated disable_dns_lookups feature to the preferred
+ smtp_dns_support_level feature. This support needs to exist
+ for several releases before the deprecated feature can be
+ removed.
+
It would be nice if the result from one table lookup could
serve as input for another (e.g. virtual aliases before the
list of valid recipients). For this to work the magical
<h2>Introduction</h2>
<dl> <dt> Note: </dt> <dd> <p> 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). </p> <p> Postfix may support LMDB again when without
-exception all "out of storage" failure modes are resolved by
-increasing the database size. </p> </dd> </dl>
+database size). </p> <p> 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. </p> </dd> </dl>
<p> Postfix uses databases of various kinds to store and look up
information. Postfix databases are specified as "type:name".
<li> <p> Missing <a href="#pthread">pthread</a> library trouble. </p>
-</ol>
+<li> <p> Unexpected <a href="#limitations">failure modes</a> that
+don't exist with other Postfix databases. </p>
-<dl> <dt> Note: </dt> <dd> <p> The Postfix LMDB client implementation
-introduces <a href="#limitations">unexpected failure modes</a> that
-don't exist with other Postfix databases. Don't just yet abandon
-CDB. </p> </dd> </dl>
+</ol>
<h2><a name="with_lmdb">Building Postfix with OpenLDAP LMDB support</a></h2>
<b><a href="postconf.5.html#smtp_skip_5xx_greeting">smtp_skip_5xx_greeting</a> (yes)</b>
Skip remote SMTP servers that greet with a 5XX sta-
- tus code (go away, do not try again later).
+ tus code.
<b><a href="postconf.5.html#smtp_skip_quit_response">smtp_skip_quit_response</a> (yes)</b>
Do not wait for the response to the SMTP QUIT com-
the MAIL FROM command in SASL-authenticated SMTP
sessions.
+ Available in Postfix version 2.11 and later:
+
+ <b><a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a> (empty)</b>
+ Level of DNS support in the Postfix SMTP client.
+
<b>MIME PROCESSING CONTROLS</b>
Available in Postfix version 2.0 and later:
<p>
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.
</p>
<p>
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 <a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a>
+instead.
</p>
<p>
<p> This feature is available in Postfix 2.8 and later. </p>
+</DD>
+
+<DT><b><a name="lmtp_dns_support_level">lmtp_dns_support_level</a>
+(default: empty)</b></DT><DD>
+
+<p> The LMTP-specific version of the <a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a>
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+
</DD>
<DT><b><a name="lmtp_enforce_tls">lmtp_enforce_tls</a>
password file lookups more predictable. This is the default setting
as of Postfix 2.3. </p>
+<p> When DNS CNAME records are validated with secure DNS lookups
+(<a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a> = dnssec), they are always allowed to
+override the above servername (Postfix 2.11 and later). </p>
+
<p> This feature is available in Postfix 2.2.9 and later. </p>
<p> This feature is available in Postfix 2.8 and later. </p>
+</DD>
+
+<DT><b><a name="smtp_dns_support_level">smtp_dns_support_level</a>
+(default: empty)</b></DT><DD>
+
+<p> Level of DNS support in the Postfix SMTP client. With
+"<a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a>" left at its empty default value, the legacy
+"<a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a>" parameter controls whether DNS is enabled in
+the Postfix SMTP client, otherwise the legacy parameter is ignored.
+</p>
+
+<p> Specify one of the following: </p>
+
+<dl>
+
+<dt><b>disabled</b></dt>
+
+<dd>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. </dd>
+
+<dt><b>enabled</b></dt>
+
+<dd>Enable DNS lookups. Nexthop destination domains not enclosed
+in "[]" will be subject to MX lookups. If "dns" and "native" are
+included in the "<a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a>" parameter value, DNS will be
+queried first to resolve MX-host A records, followed by "native"
+lookups if no answer is found in DNS. </dd>
+
+<dt><b>dnssec</b></dt>
+
+<dd>Enable <a href="https://tools.ietf.org/html/rfc4033">DNSSEC</a>
+lookups. The "dnssec" setting differs from the "enabled" setting
+above in the following ways: <ul> <li>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. <li> The address lookups of
+validated hostnames are also validated, (provided of course
+"<a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a>" includes "dns", see below). <li>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). </ul> </dd>
+
+</dl>
+
+<p> 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. </p>
+
+<p>The "dnssec" setting is recommended only if you plan to use the
+"<a href="TLS_README.html#client_tls_dane">dane</a>" 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. </p>
+
+<p> When using Postfix DANE support the "<a href="postconf.5.html#smtp_host_lookup">smtp_host_lookup</a>" parameter
+should include "dns", as <a
+href="https://tools.ietf.org/html/rfc6698">DANE</a> is not applicable
+to hosts resolved via "native" lookups. </p>
+
+<p> As mentioned above, Postfix is not a validating <a
+href="https://tools.ietf.org/html/rfc4035#section-4.9">stub
+resolver</a>; it relies on the system's configured DNSSEC-validating
+<a href="https://tools.ietf.org/html/rfc4035#section-3.2">recursive
+nameserver</a> 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</p>
+
+<p>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. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+
</DD>
<DT><b><a name="smtp_enforce_tls">smtp_enforce_tls</a>
(default: dns)</b></DT><DD>
<p>
-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: <a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a>).
+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: <a href="postconf.5.html#disable_dns_lookups">disable_dns_lookups</a> and <a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a>). The "dns"
+mechanism is always tried before "native" if both are listed.
</p>
<p>
(default: yes)</b></DT><DD>
<p>
-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.
</p>
<p> By default, the Postfix SMTP client moves on the next mail
exchanger. Specify "<a href="postconf.5.html#smtp_skip_5xx_greeting">smtp_skip_5xx_greeting</a> = no" if Postfix should
-bounce the mail immediately. The default setting is incorrect, but
-it is what a lot of people expect to happen. </p>
+bounce the mail immediately. Caution: the latter behavior appears
+to contradict <a href="http://tools.ietf.org/html/rfc2821">RFC 2821</a>. </p>
</DD>
(default: nexthop, dot-nexthop)</b></DT><DD>
<p> 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
($<a href="postconf.5.html#smtp_tls_policy_maps">smtp_tls_policy_maps</a>) entry the optional "match" attribute
overrides this <a href="postconf.5.html">main.cf</a> setting. </p>
<dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
-<dd>Reject the request when the HELO or EHLO hostname hostname is
+<dd>Reject the request when the HELO or EHLO hostname is
listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
(Postfix version 2.1 and later only). Each "<i>d</i>" is a number,
or a pattern inside "[]" that contains one or more ";"-separated
numerical response code when an address probe failed due to a
temporary problem (default: 450). <br> The
<a href="postconf.5.html#unverified_recipient_tempfail_action">unverified_recipient_tempfail_action</a> parameter specifies the action
-after addres probe failure due to a temporary problem (default:
+after address probe failure due to a temporary problem (default:
<a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). <br> This feature is available in Postfix 2.1
and later. </dd>
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 <a href="postconf.5.html#unverified_sender_defer_code">unverified_sender_defer_code</a> 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 <a href="postconf.5.html#unverified_sender_tempfail_action">unverified_sender_tempfail_action</a> parameter
specifies the action after address probe failure due to a temporary
problem (default: <a href="postconf.5.html#defer_if_permit">defer_if_permit</a>). <br> This feature is available
<b><a href="postconf.5.html#smtp_skip_5xx_greeting">smtp_skip_5xx_greeting</a> (yes)</b>
Skip remote SMTP servers that greet with a 5XX sta-
- tus code (go away, do not try again later).
+ tus code.
<b><a href="postconf.5.html#smtp_skip_quit_response">smtp_skip_quit_response</a> (yes)</b>
Do not wait for the response to the SMTP QUIT com-
the MAIL FROM command in SASL-authenticated SMTP
sessions.
+ Available in Postfix version 2.11 and later:
+
+ <b><a href="postconf.5.html#smtp_dns_support_level">smtp_dns_support_level</a> (empty)</b>
+ Level of DNS support in the Postfix SMTP client.
+
<b>MIME PROCESSING CONTROLS</b>
Available in Postfix version 2.0 and later:
# 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 <sys/types.h>
done
;;
GNU.0*|GNU/kFreeBSD.[567]*)
- SYSTYPE=GNU0
+ SYSTYPE=GNU0
case "$CCARGS" in
*-DNO_DB*) ;;
*) if [ -f /usr/include/db.h ]
?.*) 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 <sys/types.h>
-##include <sys/event.h>
-##include <sys/time.h>
-##include <string.h>
-##include <stdlib.h>
-##include <stdio.h>
-#
-##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
#
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 <setjmp.h>
#include <stdlib.h>
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"
"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
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:
.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)
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.
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
.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
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"
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)
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
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
.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
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
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
.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
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.
.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"
$block =~ tr/a-z/A-Z/;
}
$block =~ s/<DT><b><a[^>]+>([^<]+)<\/a>\n(.*)<\/b><\/DT><DD>/\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/<DL>/\n/g;
s;\bipc_ttl\b;<a href="postconf.5.html#ipc_ttl">$&</a>;g;
s;\bline_length_limit\b;<a href="postconf.5.html#line_length_limit">$&</a>;g;
s;\blmdb_map_size\b;<a href="postconf.5.html#lmdb_map_size">$&</a>;g;
+ s;\blmtp_address_preference\b;<a href="postconf.5.html#lmtp_address_preference">$&</a>;g;
+ s;\blmtp_body_checks\b;<a href="postconf.5.html#lmtp_body_checks">$&</a>;g;
+ s;\blmtp_cname_overrides_servername\b;<a href="postconf.5.html#lmtp_cname_overrides_servername">$&</a>;g;
+ s;\blmtp_dns_resolver_options\b;<a href="postconf.5.html#lmtp_dns_resolver_options">$&</a>;g;
+ s;\blmtp_dns_support_level\b;<a href="postconf.5.html#lmtp_dns_support_level">$&</a>;g;
+ s;\blmtp_header_checks\b;<a href="postconf.5.html#lmtp_header_checks">$&</a>;g;
+ s;\blmtp_mime_header_checks\b;<a href="postconf.5.html#lmtp_mime_header_checks">$&</a>;g;
+ s;\blmtp_nested_header_checks\b;<a href="postconf.5.html#lmtp_nested_header_checks">$&</a>;g;
+ s;\blmtp_per_record_deadline\b;<a href="postconf.5.html#lmtp_per_record_deadline">$&</a>;g;
+ s;\blmtp_reply_filter\b;<a href="postconf.5.html#lmtp_reply_filter">$&</a>;g;
+ s;\blmtp_sasl_password_maps\b;<a href="postconf.5.html#lmtp_sasl_password_maps">$&</a>;g;
+ s;\blmtp_send_dummy_mail_auth\b;<a href="postconf.5.html#lmtp_send_dummy_mail_auth">$&</a>;g;
+ s;\blmtp_sender_dependent_authentication\b;<a href="postconf.5.html#lmtp_sender_dependent_authentication">$&</a>;g;
s;\blmtp_bind_address\b;<a href="postconf.5.html#lmtp_bind_address">$&</a>;g;
s;\blmtp_bind_address6\b;<a href="postconf.5.html#lmtp_bind_address6">$&</a>;g;
s;\blmtp_assume_final\b;<a href="postconf.5.html#lmtp_assume_final">$&</a>;g;
s;\bsmtp_discard_ehlo_keyword_address_maps\b;<a href="postconf.5.html#smtp_discard_ehlo_keyword_address_maps">$&</a>;g;
s;\bsmtp_discard_ehlo_keywords\b;<a href="postconf.5.html#smtp_discard_ehlo_keywords">$&</a>;g;
s;\bsmtp_dns_resolver_options\b;<a href="postconf.5.html#smtp_dns_resolver_options">$&</a>;g;
+ s;\bsmtp_dns_support_level\b;<a href="postconf.5.html#smtp_dns_support_level">$&</a>;g;
s;\bsmtp_helo_name\b;<a href="postconf.5.html#smtp_helo_name">$&</a>;g;
s;\bsmtp_helo_timeout\b;<a href="postconf.5.html#smtp_helo_timeout">$&</a>;g;
s;\bsmtp_host_lookup\b;<a href="postconf.5.html#smtp_host_lookup">$&</a>;g;
<h2>Introduction</h2>
<dl> <dt> Note: </dt> <dd> <p> 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). </p> <p> Postfix may support LMDB again when without
-exception all "out of storage" failure modes are resolved by
-increasing the database size. </p> </dd> </dl>
+database size). </p> <p> 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. </p> </dd> </dl>
<p> Postfix uses databases of various kinds to store and look up
information. Postfix databases are specified as "type:name".
<li> <p> Missing <a href="#pthread">pthread</a> library trouble. </p>
-</ol>
+<li> <p> Unexpected <a href="#limitations">failure modes</a> that
+don't exist with other Postfix databases. </p>
-<dl> <dt> Note: </dt> <dd> <p> The Postfix LMDB client implementation
-introduces <a href="#limitations">unexpected failure modes</a> that
-don't exist with other Postfix databases. Don't just yet abandon
-CDB. </p> </dd> </dl>
+</ol>
<h2><a name="with_lmdb">Building Postfix with OpenLDAP LMDB support</a></h2>
%PARAM smtp_host_lookup dns
<p>
-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.
</p>
<p>
%PARAM smtp_skip_5xx_greeting yes
<p>
-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.
</p>
<p> 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. </p>
+bounce the mail immediately. Caution: the latter behavior appears
+to contradict RFC 2821. </p>
%PARAM smtp_skip_quit_response yes
<dt><b><a name="reject_rhsbl_helo">reject_rhsbl_helo <i>rbl_domain=d.d.d.d</i></a></b></dt>
-<dd>Reject the request when the HELO or EHLO hostname hostname is
+<dd>Reject the request when the HELO or EHLO hostname is
listed with the A record "<i>d.d.d.d</i>" under <i>rbl_domain</i>
(Postfix version 2.1 and later only). Each "<i>d</i>" is a number,
or a pattern inside "[]" that contains one or more ";"-separated
numerical response code when an address probe failed due to a
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
and later. </dd>
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
specifies the action after address probe failure due to a temporary
problem (default: defer_if_permit). <br> This feature is available
<p>
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.
</p>
<p>
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.
</p>
<p>
password file lookups more predictable. This is the default setting
as of Postfix 2.3. </p>
+<p> 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). </p>
+
<p> This feature is available in Postfix 2.2.9 and later. </p>
%PARAM lmtp_cname_overrides_servername yes
%PARAM smtp_tls_secure_cert_match nexthop, dot-nexthop
<p> 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. </p>
</pre>
<p> This feature is available in Postfix 2.10 and later. </p>
+
+%PARAM smtp_dns_support_level
+
+<p> 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.
+</p>
+
+<p> Specify one of the following: </p>
+
+<dl>
+
+<dt><b>disabled</b></dt>
+
+<dd>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. </dd>
+
+<dt><b>enabled</b></dt>
+
+<dd>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. </dd>
+
+<dt><b>dnssec</b></dt>
+
+<dd>Enable <a href="https://tools.ietf.org/html/rfc4033">DNSSEC</a>
+lookups. The "dnssec" setting differs from the "enabled" setting
+above in the following ways: <ul> <li>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. <li> The address lookups of
+validated hostnames are also validated, (provided of course
+"smtp_host_lookup" includes "dns", see below). <li>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). </ul> </dd>
+
+</dl>
+
+<p> 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. </p>
+
+<p>The "dnssec" setting is recommended only if you plan to use the
+"<a href="TLS_README.html#client_tls_dane">dane</a>" 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. </p>
+
+<p> When using Postfix DANE support the "smtp_host_lookup" parameter
+should include "dns", as <a
+href="https://tools.ietf.org/html/rfc6698">DANE</a> is not applicable
+to hosts resolved via "native" lookups. </p>
+
+<p> As mentioned above, Postfix is not a validating <a
+href="https://tools.ietf.org/html/rfc4035#section-4.9">stub
+resolver</a>; it relies on the system's configured DNSSEC-validating
+<a href="https://tools.ietf.org/html/rfc4035#section-3.2">recursive
+nameserver</a> 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</p>
+
+<p>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. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
+
+%PARAM lmtp_dns_support_level
+
+<p> The LMTP-specific version of the smtp_dns_support_level
+configuration parameter. See there for details. </p>
+
+<p> This feature is available in Postfix 2.11 and later. </p>
ul
whitelisted
whitelists
-=== proto/POSTSCREEN_README.html ===
Amavisd
MUA
Mailserver
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
#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.
*/
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 */
/* 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().
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 */
* 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
* 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;
DNS_FIXED *fixed)
{
char temp[DNS_NAME_LEN];
+ char *tempbuf = temp;
ssize_t data_len;
unsigned pref = 0;
unsigned char *src;
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);
}
*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);
}
/* 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;
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;
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;
}
static DNS_REPLY reply;
int count;
int status;
+ int validate_mask = 1; /* May reset to 0 via CNAME expansion */
const char *orig_name = name;
/*
/*
* 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)
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);
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
-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
#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
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
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));
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));
#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"
* 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
/*
* 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
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,
/* 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
/* .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
/* 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.
/* .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"
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;
/*
* 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;
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));
/*
/*
* 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);
}
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)
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
*/
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,
* 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);
* 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);
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);
/*
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);
}
}
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.
/*
* 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.
*/
#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)
#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 = <bogus> */
+#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 */
#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
#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
/* 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";
* 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:
{
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
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);
}
DNS_RR *self = 0;
unsigned best_pref;
unsigned best_found;
+ int r = 0; /* Resolver flags */
dsb_reset(why); /* Paranoia */
/*
* 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
* 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)
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) {
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));
}
}
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.",
#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) {
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));
}
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");
/*
*/
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) {
* 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
* 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 {
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,
&& (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,
} 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;
* 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);
}
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
"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
#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
*/
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,
* 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";
* 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)
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)
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
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
}
}
/* 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) {
/* .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
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);
}
}
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);
}
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);
/* 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
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(""));
}
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(""));
}
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 */
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);
#include <sys/resource.h>
#include <errno.h>
+#ifdef MACOSX
+#include <sys/sysctl.h>
+#define MAX_FILES_PER_PROC "kern.maxfilesperproc"
+#endif
+
/* Application-specific. */
#include "iostuff.h"
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