20141130
Cleanup: when searching multiple DNS record types for a
- specific name, and the result status is not DNS_OK, return
- the rcode and diagnostic text for that status instead of
- the last rcode and last diagnostic text.
+ specific name, and not all queries return the same result
+ status, do not blindly return the last query's rcode and
+ diagnostic text. Instead, return rcode and text that is
+ consistent with the aggregate result status.
Cleanup: un-broke several smtpd regression tests (work in
progress, with three more to go). Files: smtpd/smtpd_check.c,
smtpd/smtpd_server.{in,ref}, smtpd/smtpd_exp.{in,ref}.
smtpd/smtpd_dnswl.{in,ref}.
+
+ Documentation: added note on Milter-signing bounces.
+
+20141201
+
+ Bugfix (introduced: 20141130): memory leak. File: dns_lookup.c.
+
+ Cleanup: un-broke several dns regression tests by sorting
+ getaddrinfo() results by address family. Files: dns/dns_rr_eq_sa.c,
+ dns/dns_rr_eq_sa.ref, dns/dns_sa_to_rr.c, dns/dns_sa_to_rr.ref.
+
+ Cleanup: missing #ifdef in smtpd_check test driver. File:
+ smtpd/smtpd_check.c.
non_smtpd_milters application REJECTs or TEMPFAILs a recipient, Postfix will
report a configuration error, and mail will stay in the queue.
-None of this is a problem for mail filters that digitally sign mail.
+S\bSi\big\bgn\bni\bin\bng\bg i\bin\bnt\bte\ber\brn\bna\bal\bll\bly\by-\b-g\bge\ben\bne\ber\bra\bat\bte\bed\bd b\bbo\bou\bun\bnc\bce\be m\bme\bes\bss\bsa\bag\bge\bes\bs
+
+Postfix normally does not apply content filters to mail that is generated
+internally such as bounces or Postmaster notifications. Filtering internally-
+generated bounces would result in loss of mail when a filter rejects a message,
+as the resulting double-bounce message would almost certainly also be blocked.
+
+To sign Postfix's own bounce messages, enable filtering of internally-generated
+bounces (line 2 below), and don't reject any internally-generated bounces with
+non_smtpd_milters, header_checks or body_checks (lines 3-5 below).
+
+ 1 /etc/postfix/main.cf:
+ 2 internal_mail_filter_classes = bounce
+ 3 non_smtpd_milters = don't reject internally-generated bounces
+ 4 header_checks = don't reject internally-generated bounces
+ 5 body_checks = don't reject internally-generated bounces
M\bMi\bil\blt\bte\ber\br e\ber\brr\bro\bor\br h\bha\ban\bnd\bdl\bli\bin\bng\bg
commands. When this rule is violated, Postfix will report a configuration
error, and mail will stay in the queue.
- * Postfix currently does not apply content filters to mail that is forwarded
- or aliased internally, or to mail that is generated internally such as
- bounces or Postmaster notifications. This may be a problem when you want to
- apply a signing Milter to such mail.
-
* When you use the before-queue content filter for incoming SMTP mail (see
SMTPD_PROXY_README), Milter applications have access only to the SMTP
command information; they have no access to the message header or body, and
a recipient, Postfix will report a configuration error, and mail
will stay in the queue. </p>
-<p> None of this is a problem for mail filters that digitally sign
-mail. </p>
+<h4> Signing internally-generated bounce messages </h4>
+
+<li> <p> Postfix normally does not apply content filters to mail
+that is generated internally such as bounces or Postmaster
+notifications. Filtering internally-generated bounces would result
+in loss of mail when a filter rejects a message, as the resulting
+double-bounce message would almost certainly also be blocked. </p>
+
+<p> To sign Postfix's own bounce messages, enable filtering of
+internally-generated bounces (line 2 below), and don't reject any
+internally-generated bounces with <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a>, <a href="postconf.5.html#header_checks">header_checks</a>
+or <a href="postconf.5.html#body_checks">body_checks</a> (lines 3-5 below). </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/<a href="postconf.5.html">main.cf</a>:
+2 <a href="postconf.5.html#internal_mail_filter_classes">internal_mail_filter_classes</a> = bounce
+3 <a href="postconf.5.html#non_smtpd_milters">non_smtpd_milters</a> = <i>don't reject internally-generated bounces</i>
+4 <a href="postconf.5.html#header_checks">header_checks</a> = <i>don't reject internally-generated bounces</i>
+5 <a href="postconf.5.html#body_checks">body_checks</a> = <i>don't reject internally-generated bounces</i>
+</pre>
+</blockquote>
<h3><a name="errors">Milter error handling</a></h3>
Postfix will report a configuration error, and mail will stay in
the queue. </p>
-<li> <p> Postfix currently does not apply content filters to mail
-that is forwarded or aliased internally, or to mail that is generated
-internally such as bounces or Postmaster notifications. This may
-be a problem when you want to apply a signing Milter to such mail.
-</p>
-
<li> <p> When you use the before-queue content filter for incoming
SMTP mail (see <a href="SMTPD_PROXY_README.html">SMTPD_PROXY_README</a>), Milter applications have access
only to the SMTP command information; they have no access to the
<ul>
-<li> <p> The <a href="postconf.5.html#smtp_dns_reply_filter">smtp_dns_reply_filter</a> and <a href="postconf.5.html#lmtp_dns_reply_filter">lmtp_dns_reply_filter</a> features
-are used only for Postfix SMTP or LMTP client DNS lookups of MX,
-A, and AAAAA records to locate a remote SMTP or LMTP server, including
-lookups that are made to implement the features <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a>
-and <a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a>. </p>
+<li> <p> Postfix DNS reply filters have no effect on implicit DNS
+lookups through nsswitch.conf or equivalent mechanisms. </p>
-<li> <p> The Postfix SMTP or LMTP client defers mail delivery when
+<li> <p> The Postfix SMTP and LMTP client use <a href="postconf.5.html#smtp_dns_reply_filter">smtp_dns_reply_filter</a>
+and <a href="postconf.5.html#lmtp_dns_reply_filter">lmtp_dns_reply_filter</a> only to locate a remote SMTP or LMTP
+server (record types MX, A, and AAAAA). These lookups are also
+made to implement the features <a href="postconf.5.html#reject_unverified_sender">reject_unverified_sender</a> and
+<a href="postconf.5.html#reject_unverified_recipient">reject_unverified_recipient</a>. </p>
+
+<li> <p> The Postfix SMTP and LMTP client defer mail delivery when
a filter removes all lookup results from a successful query. </p>
-<li> <p> The <a href="postconf.5.html#smtpd_dns_reply_filter">smtpd_dns_reply_filter</a> feature is used only for Postfix
-SMTP server DNS lookups of MX, A, AAAAA, and TXT records to implement
-the features <a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a>, <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>,
+<li> <p> Postfix SMTP server uses <a href="postconf.5.html#smtpd_dns_reply_filter">smtpd_dns_reply_filter</a> only to
+look up MX, A, AAAAA, and TXT records to implement the features
+<a href="postconf.5.html#reject_unknown_helo_hostname">reject_unknown_helo_hostname</a>, <a href="postconf.5.html#reject_unknown_sender_domain">reject_unknown_sender_domain</a>,
<a href="postconf.5.html#reject_unknown_recipient_domain">reject_unknown_recipient_domain</a>, reject_rbl_*, and reject_rhsbl_*.
</p>
delivery when a filter removes all lookup results from a successful
query. </p>
-<li> <p> Implicit DNS lookups through nsswitch.conf or equivalent
-mechanisms are not filtered. </p>
-
</ul>
<p> Example: ignore Google AAAA records in Postfix SMTP client DNS
.PP
Notes:
.IP \(bu
-The smtp_dns_reply_filter and lmtp_dns_reply_filter features
-are used only for Postfix SMTP or LMTP client DNS lookups of MX,
-A, and AAAAA records to locate a remote SMTP or LMTP server, including
-lookups that are made to implement the features reject_unverified_sender
-and reject_unverified_recipient.
+Postfix DNS reply filters have no effect on implicit DNS
+lookups through nsswitch.conf or equivalent mechanisms.
.IP \(bu
-The Postfix SMTP or LMTP client defers mail delivery when
+The Postfix SMTP and LMTP client use smtp_dns_reply_filter
+and lmtp_dns_reply_filter only to locate a remote SMTP or LMTP
+server (record types MX, A, and AAAAA). These lookups are also
+made to implement the features reject_unverified_sender and
+reject_unverified_recipient.
+.IP \(bu
+The Postfix SMTP and LMTP client defer mail delivery when
a filter removes all lookup results from a successful query.
.IP \(bu
-The smtpd_dns_reply_filter feature is used only for Postfix
-SMTP server DNS lookups of MX, A, AAAAA, and TXT records to implement
-the features reject_unknown_helo_hostname, reject_unknown_sender_domain,
+Postfix SMTP server uses smtpd_dns_reply_filter only to
+look up MX, A, AAAAA, and TXT records to implement the features
+reject_unknown_helo_hostname, reject_unknown_sender_domain,
reject_unknown_recipient_domain, reject_rbl_*, and reject_rhsbl_*.
.IP \(bu
The Postfix SMTP server logs a warning or defers mail
delivery when a filter removes all lookup results from a successful
query.
-.IP \(bu
-Implicit DNS lookups through nsswitch.conf or equivalent
-mechanisms are not filtered.
.br
.PP
Example: ignore Google AAAA records in Postfix SMTP client DNS
a recipient, Postfix will report a configuration error, and mail
will stay in the queue. </p>
-<p> None of this is a problem for mail filters that digitally sign
-mail. </p>
+<h4> Signing internally-generated bounce messages </h4>
+
+<li> <p> Postfix normally does not apply content filters to mail
+that is generated internally such as bounces or Postmaster
+notifications. Filtering internally-generated bounces would result
+in loss of mail when a filter rejects a message, as the resulting
+double-bounce message would almost certainly also be blocked. </p>
+
+<p> To sign Postfix's own bounce messages, enable filtering of
+internally-generated bounces (line 2 below), and don't reject any
+internally-generated bounces with non_smtpd_milters, header_checks
+or body_checks (lines 3-5 below). </p>
+
+<blockquote>
+<pre>
+1 /etc/postfix/main.cf:
+2 internal_mail_filter_classes = bounce
+3 non_smtpd_milters = <i>don't reject internally-generated bounces</i>
+4 header_checks = <i>don't reject internally-generated bounces</i>
+5 body_checks = <i>don't reject internally-generated bounces</i>
+</pre>
+</blockquote>
<h3><a name="errors">Milter error handling</a></h3>
Postfix will report a configuration error, and mail will stay in
the queue. </p>
-<li> <p> Postfix currently does not apply content filters to mail
-that is forwarded or aliased internally, or to mail that is generated
-internally such as bounces or Postmaster notifications. This may
-be a problem when you want to apply a signing Milter to such mail.
-</p>
-
<li> <p> When you use the before-queue content filter for incoming
SMTP mail (see SMTPD_PROXY_README), Milter applications have access
only to the SMTP command information; they have no access to the
<ul>
-<li> <p> The smtp_dns_reply_filter and lmtp_dns_reply_filter features
-are used only for Postfix SMTP or LMTP client DNS lookups of MX,
-A, and AAAAA records to locate a remote SMTP or LMTP server, including
-lookups that are made to implement the features reject_unverified_sender
-and reject_unverified_recipient. </p>
+<li> <p> Postfix DNS reply filters have no effect on implicit DNS
+lookups through nsswitch.conf or equivalent mechanisms. </p>
-<li> <p> The Postfix SMTP or LMTP client defers mail delivery when
+<li> <p> The Postfix SMTP and LMTP client use smtp_dns_reply_filter
+and lmtp_dns_reply_filter only to locate a remote SMTP or LMTP
+server (record types MX, A, and AAAAA). These lookups are also
+made to implement the features reject_unverified_sender and
+reject_unverified_recipient. </p>
+
+<li> <p> The Postfix SMTP and LMTP client defer mail delivery when
a filter removes all lookup results from a successful query. </p>
-<li> <p> The smtpd_dns_reply_filter feature is used only for Postfix
-SMTP server DNS lookups of MX, A, AAAAA, and TXT records to implement
-the features reject_unknown_helo_hostname, reject_unknown_sender_domain,
+<li> <p> Postfix SMTP server uses smtpd_dns_reply_filter only to
+look up MX, A, AAAAA, and TXT records to implement the features
+reject_unknown_helo_hostname, reject_unknown_sender_domain,
reject_unknown_recipient_domain, reject_rbl_*, and reject_rhsbl_*.
</p>
delivery when a filter removes all lookup results from a successful
query. </p>
-<li> <p> Implicit DNS lookups through nsswitch.conf or equivalent
-mechanisms are not filtered. </p>
-
</ul>
<p> Example: ignore Google AAAA records in Postfix SMTP client DNS
hpref_rcode = *rcode; \
if (why && status != DNS_OK) \
vstring_strcpy(hpref_rtext ? hpref_rtext : \
- vstring_alloc(VSTRING_LEN(why)), \
+ (hpref_rtext = vstring_alloc(VSTRING_LEN(why))), \
vstring_str(why)); \
} while (0)
* Stand-alone test program.
*/
#ifdef TEST
+#include <stdlib.h>
#include <vstream.h>
#include <myaddrinfo.h>
#include <inet_proto.h>
+#include <mymalloc.h>
static const char *myname;
msg_fatal("usage: %s hostname address", myname);
}
+static int compare_family(const void *a, const void *b)
+{
+ struct addrinfo *resa = *(struct addrinfo **) a;
+ struct addrinfo *resb = *(struct addrinfo **) b;
+
+ return (resa->ai_family - resb->ai_family);
+}
+
int main(int argc, char **argv)
{
MAI_HOSTADDR_STR hostaddr;
struct addrinfo *res0;
struct addrinfo *res1;
struct addrinfo *res;
+ struct addrinfo **resv;
+ size_t len, n;
int aierr;
myname = argv[0];
if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0)
msg_fatal("host name %s: %s", argv[0], MAI_STRERROR(aierr));
- for (res = res0; res != 0; res = res->ai_next) {
- SOCKADDR_TO_HOSTADDR(res->ai_addr, res->ai_addrlen,
+ for (len = 0, res = res0; res != 0; res = res->ai_next)
+ len += 1;
+ resv = (struct addrinfo **) mymalloc(len * sizeof(*resv));
+ for (len = 0, res = res0; res != 0; res = res->ai_next)
+ resv[len++] = res;
+ qsort((void *) resv, len, sizeof(*resv), compare_family);
+ for (n = 0; n < len; n++) {
+ SOCKADDR_TO_HOSTADDR(resv[n]->ai_addr, resv[n]->ai_addrlen,
&hostaddr, (MAI_SERVPORT_STR *) 0, 0);
vstream_printf("%s =?= %s\n", hostaddr.buf, argv[1]);
vstream_printf("tested by function: %s\n",
- dns_rr_eq_sa(rr, res->ai_addr) ?
+ dns_rr_eq_sa(rr, resv[n]->ai_addr) ?
"yes" : "no");
vstream_printf("tested by macro: %s\n",
- DNS_RR_EQ_SA(rr, res->ai_addr) ?
+ DNS_RR_EQ_SA(rr, resv[n]->ai_addr) ?
"yes" : "no");
}
dns_rr_free(rr);
freeaddrinfo(res0);
+ myfree((void *) resv);
vstream_fflush(VSTREAM_OUT);
argv += 1;
}
-2604:8d00:189::2 =?= 168.100.189.2
-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
+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
+2604:8d00:189::2 =?= 168.100.189.3
+tested by function: no
+tested by macro: no
+168.100.189.2 =?= 2604:8d00:189::2
+tested by function: no
+tested by macro: no
2604:8d00:189::2 =?= 2604:8d00:189::2
tested by function: yes
tested by macro: yes
-168.100.189.2 =?= 2604:8d00:189::2
+168.100.189.2 =?= 2604:8d00:189::3
tested by function: no
tested by macro: no
2604:8d00:189::2 =?= 2604:8d00:189::3
tested by function: no
tested by macro: no
-168.100.189.2 =?= 2604:8d00:189::3
-tested by function: no
-tested by macro: no
/* dns_sa_to_rr - socket address to resource record */
-DNS_RR *dns_sa_to_rr(const char *hostname, unsigned pref, struct sockaddr * sa)
+DNS_RR *dns_sa_to_rr(const char *hostname, unsigned pref, struct sockaddr *sa)
{
#define DUMMY_TTL 0
* Stand-alone test program.
*/
#ifdef TEST
+#include <stdlib.h>
#include <vstream.h>
#include <myaddrinfo.h>
#include <inet_proto.h>
+#include <mymalloc.h>
static const char *myname;
msg_fatal("usage: %s hostname", myname);
}
+static int compare_family(const void *a, const void *b)
+{
+ struct addrinfo *resa = *(struct addrinfo **) a;
+ struct addrinfo *resb = *(struct addrinfo **) b;
+
+ return (resa->ai_family - resb->ai_family);
+}
+
int main(int argc, char **argv)
{
MAI_HOSTADDR_STR hostaddr;
struct addrinfo *res0;
struct addrinfo *res;
+ struct addrinfo **resv;
+ size_t len, n;
DNS_RR *rr;
int aierr;
while (*++argv) {
if ((aierr = hostname_to_sockaddr(argv[0], (char *) 0, 0, &res0)) != 0)
msg_fatal("%s: %s", argv[0], MAI_STRERROR(aierr));
- for (res = res0; res != 0; res = res->ai_next) {
- if ((rr = dns_sa_to_rr(argv[0], 0, res->ai_addr)) == 0)
+ for (len = 0, res = res0; res != 0; res = res->ai_next)
+ len += 1;
+ resv = (struct addrinfo **) mymalloc(len * sizeof(*resv));
+ for (len = 0, res = res0; res != 0; res = res->ai_next)
+ resv[len++] = res;
+ qsort((void *) resv, len, sizeof(*resv), compare_family);
+ for (n = 0; n < len; n++) {
+ if ((rr = dns_sa_to_rr(argv[0], 0, resv[n]->ai_addr)) == 0)
msg_fatal("dns_sa_to_rr: %m");
if (dns_rr_to_pa(rr, &hostaddr) == 0)
msg_fatal("dns_rr_to_pa: %m");
dns_rr_free(rr);
}
freeaddrinfo(res0);
+ myfree((void *) resv);
}
return (0);
}
-spike.porcupine.org -> 2604:8d00:189::2
spike.porcupine.org -> 168.100.189.2
+spike.porcupine.org -> 2604:8d00:189::2
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
-#define MAIL_RELEASE_DATE "20141130"
+#define MAIL_RELEASE_DATE "20141201"
#define MAIL_VERSION_NUMBER "2.12"
#ifdef SNAPSHOT
#define FREE_STRING(s) { if (s) myfree(s); }
FREE_STRING(state.helo_name);
FREE_STRING(state.sender);
+#ifdef USE_TLS
if (state.tls_context) {
FREE_STRING(state.tls_context->peer_cert_fprint);
myfree((char *) state.tls_context);
}
+#endif
exit(0);
}