2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-30 05:38:06 +00:00

postfix-2.3-20051120

This commit is contained in:
Wietse Venema 2005-11-20 00:00:00 -05:00 committed by Viktor Dukhovni
parent 28a6e59d67
commit 9e9cfc29e9
15 changed files with 184 additions and 61 deletions

View File

@ -11405,6 +11405,25 @@ Apologies for any names omitted.
Bugfix: new bounce template code did not return after
template syntax error. File: bounce/bounce_template.c
Safety: permit_mx_backup now requires that the local MTA
is not listed as primary MX for the recipient domain. This
prevents mail loops when someone points the primary MX
record to Postfix.
20051119
Workaround: some SMTP servers announce multiple but different
lists of SASL methods. Postfix now concatenates the lists
instead of logging a warning and remembering only one. File:
smtp/smtp_sasl_proto.c.
Bugfix: the queue manager did not write a per-recipient
defer logfile record when the delivery agent crashed between
receiving a delivery request, and reporting the delivery
status to the queue manager. Found while redesigning the
code that handles unavailable transports or destinations.
Files: *qmgr/qmgr_deliver.c.
Open problems:
"postsuper -r" no longer resets the message arrival time,

View File

@ -17,6 +17,14 @@ Incompatibility with Postfix 2.1 and earlier
If you upgrade from Postfix 2.1 or earlier, read RELEASE_NOTES-2.2
before proceeding.
Incompatibility with snapshot 20051120
======================================
The permit_mx_backup feature now requires that the local MTA is not
listed as primary MX host for the recipient domain. This prevents
mail loop problems when someone points the primary MX record at
Postfix.
Major changes with snapshot 20051113
====================================

View File

@ -8305,9 +8305,16 @@ system is the final destination. However, the SMTP server will not
forward mail with addresses that have sender-specified routing
information (example: user@elsewhere@domain). Use the optional
<a href="postconf.5.html#permit_mx_backup_networks">permit_mx_backup_networks</a> parameter to require that the primary
MX hosts match a list of network blocks. <br> Note: prior to
MX hosts match a list of network blocks. <br> NOTE: prior to
Postfix version 2.0, use of <a href="postconf.5.html#permit_mx_backup">permit_mx_backup</a> is not recommended;
mail may be rejected in case of a temporary DNS lookup problem. </dd>
mail may be rejected in case of a temporary DNS lookup problem.
<br> NOTE: as of Postfix version 2.3, <a href="postconf.5.html#permit_mx_backup">permit_mx_backup</a> requires
that the local MTA is not listed as primary MX for the recipient
domain. This is for safety reasons.
<br> NOTE: use of <a href="postconf.5.html#permit_mx_backup">permit_mx_backup</a> is not recommended without
restricting its use with <a href="postconf.5.html#permit_mx_backup_networks">permit_mx_backup_networks</a>. </dd>
<dt><b><a name="reject_non_fqdn_recipient">reject_non_fqdn_recipient</a></b></dt>

View File

@ -4777,9 +4777,16 @@ information (example: user@elsewhere@domain). Use the optional
permit_mx_backup_networks parameter to require that the primary
MX hosts match a list of network blocks.
.br
Note: prior to
NOTE: prior to
Postfix version 2.0, use of permit_mx_backup is not recommended;
mail may be rejected in case of a temporary DNS lookup problem.
.br
NOTE: as of Postfix version 2.3, permit_mx_backup requires
that the local MTA is not listed as primary MX for the recipient
domain. This is for safety reasons.
.br
NOTE: use of permit_mx_backup is not recommended without
restricting its use with permit_mx_backup_networks.
.IP "\fBreject_non_fqdn_recipient\fR"
Reject the request when the RCPT TO address is not in
fully-qualified domain form, as required by the RFC.

View File

@ -5198,9 +5198,16 @@ system is the final destination. However, the SMTP server will not
forward mail with addresses that have sender-specified routing
information (example: user@elsewhere@domain). Use the optional
permit_mx_backup_networks parameter to require that the primary
MX hosts match a list of network blocks. <br> Note: prior to
MX hosts match a list of network blocks. <br> NOTE: prior to
Postfix version 2.0, use of permit_mx_backup is not recommended;
mail may be rejected in case of a temporary DNS lookup problem. </dd>
mail may be rejected in case of a temporary DNS lookup problem.
<br> NOTE: as of Postfix version 2.3, permit_mx_backup requires
that the local MTA is not listed as primary MX for the recipient
domain. This is for safety reasons.
<br> NOTE: use of permit_mx_backup is not recommended without
restricting its use with permit_mx_backup_networks. </dd>
<dt><b><a name="reject_non_fqdn_recipient">reject_non_fqdn_recipient</a></b></dt>

View File

@ -47,7 +47,9 @@
/* BOUNCE_TEMPLATE *template;
/* DESCRIPTION
/* This module implements the built-in and external bounce
/* message template support.
/* message template support. The content of a template are
/* private. To access information within a template, use
/* the API described in this document.
/*
/* bounce_template_create() creates a template, with the
/* specified default settings. The template defaults are not
@ -81,7 +83,7 @@
/* specified stream.
/*
/* The IS_MUMBLE_TEMPLATE() macros are predicates that
/* return when the template is of the specified type.
/* determine whether the template is of the specified type.
/* DIAGNOSTICS
/* Fatal error: out of memory, undefined macro name in template.
/* SEE ALSO
@ -136,9 +138,9 @@
* Ideally, the bounce template processor would strip the _days etc. suffix
* from the parameter name, and use the parameter name to look up the actual
* parameter value and its default value (the default value specifies the
* default time unit of that parameter (seconds, minutes, etc.), and allows
* us to convert the parameter string value into the corresponding number of
* seconds). The bounce template processor would then use the _hours etc.
* default time unit of that parameter (seconds, minutes, etc.)), and use
* this to convert the parameter string value into the corresponding number
* of seconds. The bounce template processor would then use the _hours etc.
* suffix from the bounce template to divide this number by the number of
* seconds in an hour, etc. and produce the number that is needed for the
* template.

View File

@ -6,6 +6,15 @@
/* SYNOPSIS
/* #include <bounce_template.h>
/*
/* typedef struct {
/* .in +4
/* BOUNCE_TEMPLATE *failure;
/* BOUNCE_TEMPLATE *delay;
/* BOUNCE_TEMPLATE *success;
/* BOUNCE_TEMPLATE *verify;
/* .in -4
/* } BOUNCE_TEMPLATES;
/*
/* BOUNCE_TEMPLATES *bounce_templates_create(void)
/*
/* void bounce_templates_free(templates)

View File

@ -111,6 +111,7 @@ extern void dns_rr_free(DNS_RR *);
extern DNS_RR *dns_rr_copy(DNS_RR *);
extern DNS_RR *dns_rr_append(DNS_RR *, DNS_RR *);
extern DNS_RR *dns_rr_sort(DNS_RR *, int (*) (DNS_RR *, DNS_RR *));
extern int dns_rr_compare_pref(DNS_RR *, DNS_RR *);
extern DNS_RR *dns_rr_shuffle(DNS_RR *);
extern DNS_RR *dns_rr_remove(DNS_RR *, DNS_RR *);

View File

@ -30,6 +30,10 @@
/* DNS_RR *list
/* int (*compar)(DNS_RR *, DNS_RR *);
/*
/* int dns_rr_compare_pref(DNS_RR *a, DNS_RR *b)
/* DNS_RR *list
/* DNS_RR *list
/*
/* DNS_RR *dns_rr_shuffle(list)
/* DNS_RR *list;
/*
@ -58,6 +62,9 @@
/* order according to a user-specified criterion. The result is the
/* sorted list.
/*
/* dns_rr_compare_pref() is a dns_rr_sort() helper to sort records
/* by their MX preference.
/*
/* dns_rr_shuffle() randomly permutes a list of resource records.
/*
/* dns_rr_remove() removes the specified record from the specified list.
@ -151,6 +158,23 @@ DNS_RR *dns_rr_append(DNS_RR *list, DNS_RR *rr)
return (list);
}
/* dns_rr_compare_pref - compare resource records by preference */
int dns_rr_compare_pref(DNS_RR *a, DNS_RR *b)
{
if (a->pref != b->pref)
return (a->pref - b->pref);
#ifdef HAS_IPV6
if (a->type == b->type) /* 200412 */
return 0;
if (a->type == T_AAAA)
return (-1);
if (b->type == T_AAAA)
return (+1);
#endif
return 0;
}
/* dns_rr_sort_callback - glue function */
static int (*dns_rr_sort_user) (DNS_RR *, DNS_RR *);

View File

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

View File

@ -219,6 +219,8 @@ static void qmgr_deliver_update(int unused_event, char *context)
static DSN_BUF *dsb;
int status;
DSN dsn;
RECIPIENT *recipient;
int nrcpt;
if (dsb == 0)
dsb = dsb_create();
@ -254,6 +256,21 @@ static void qmgr_deliver_update(int unused_event, char *context)
"unknown mail transport error"));
msg_warn("transport %s failure -- see a previous warning/fatal/panic logfile record for the problem description",
transport->name);
/*
* Assume the worst and write a defer logfile record for each
* recipient. This omission was already present in the first queue
* manager implementation of 199703, and was fixed 200511.
*
* Don't move this queue entry back to the todo queue so that
* qmgr_defer_transport() can update the defer log. The queue entry
* is still hot, and making it cold would involve duplicating most
* but not all code at the end of this routine. That's too tricky.
*/
for (nrcpt = 0; nrcpt < entry->rcpt_list.len; nrcpt++) {
recipient = entry->rcpt_list.info + nrcpt;
qmgr_defer_recipient(message, recipient, &dsn);
}
qmgr_defer_transport(transport, &dsn);
}
@ -287,7 +304,7 @@ static void qmgr_deliver_update(int unused_event, char *context)
* No problems detected. Mark the transport and queue as alive. The queue
* itself won't go away before we dispose of the current queue entry.
*/
if (VSTRING_LEN(dsb->reason) == 0) {
if (status != DELIVER_STAT_CRASH && VSTRING_LEN(dsb->reason) == 0) {
qmgr_transport_unthrottle(transport);
qmgr_queue_unthrottle(queue);
}

View File

@ -224,6 +224,8 @@ static void qmgr_deliver_update(int unused_event, char *context)
static DSN_BUF *dsb;
int status;
DSN dsn;
RECIPIENT *recipient;
int nrcpt;
if (dsb == 0)
dsb = dsb_create();
@ -259,6 +261,21 @@ static void qmgr_deliver_update(int unused_event, char *context)
"unknown mail transport error"));
msg_warn("transport %s failure -- see a previous warning/fatal/panic logfile record for the problem description",
transport->name);
/*
* Assume the worst and write a defer logfile record for each
* recipient. This omission was already present in the first queue
* manager implementation of 199703, and was fixed 200511.
*
* Don't move this queue entry back to the todo queue so that
* qmgr_defer_transport() can update the defer log. The queue entry
* is still hot, and making it cold would involve duplicating most
* but not all code at the end of this routine. That's too tricky.
*/
for (nrcpt = 0; nrcpt < entry->rcpt_list.len; nrcpt++) {
recipient = entry->rcpt_list.info + nrcpt;
qmgr_defer_recipient(message, recipient, &dsn);
}
qmgr_defer_transport(transport, &dsn);
}
@ -292,7 +309,7 @@ static void qmgr_deliver_update(int unused_event, char *context)
* No problems detected. Mark the transport and queue as alive. The queue
* itself won't go away before we dispose of the current queue entry.
*/
if (VSTRING_LEN(dsb->reason) == 0) {
if (status != DELIVER_STAT_CRASH && VSTRING_LEN(dsb->reason) == 0) {
qmgr_transport_unthrottle(transport);
qmgr_queue_unthrottle(queue);
}

View File

@ -338,23 +338,6 @@ static DNS_RR *smtp_truncate_self(DNS_RR *addr_list, unsigned pref)
return (addr_list);
}
/* smtp_compare_pref - compare resource records by preference */
static int smtp_compare_pref(DNS_RR *a, DNS_RR *b)
{
if (a->pref != b->pref)
return (a->pref - b->pref);
#ifdef HAS_IPV6
if (a->type == b->type) /* 200412 */
return 0;
if (a->type == T_AAAA)
return (-1);
if (b->type == T_AAAA)
return (+1);
#endif
return 0;
}
/* smtp_domain_addr - mail exchanger address lookup */
DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
@ -437,7 +420,7 @@ DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
addr_list = smtp_host_addr(name, misc_flags, why);
break;
case DNS_OK:
mx_names = dns_rr_sort(mx_names, smtp_compare_pref);
mx_names = dns_rr_sort(mx_names, dns_rr_compare_pref);
best_pref = (mx_names ? mx_names->pref : IMPOSSIBLE_PREFERENCE);
addr_list = smtp_addr_list(mx_names, why);
dns_rr_free(mx_names);
@ -472,7 +455,7 @@ DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
}
if (addr_list && addr_list->next && var_smtp_rand_addr) {
addr_list = dns_rr_shuffle(addr_list);
addr_list = dns_rr_sort(addr_list, smtp_compare_pref);
addr_list = dns_rr_sort(addr_list, dns_rr_compare_pref);
}
break;
case DNS_INVAL:
@ -521,7 +504,7 @@ DNS_RR *smtp_host_addr(char *host, int misc_flags, DSN_BUF *why)
addr_list = dns_rr_shuffle(addr_list);
/* The following changes the order of equal-preference hosts. */
if (inet_proto_info()->ai_family_list[1] != 0)
addr_list = dns_rr_sort(addr_list, smtp_compare_pref);
addr_list = dns_rr_sort(addr_list, dns_rr_compare_pref);
}
if (msg_verbose)
smtp_print_addr(host, addr_list);

View File

@ -115,18 +115,25 @@ static const char *smtp_sasl_compat_mechs(const char *words)
void smtp_sasl_helo_auth(SMTP_SESSION *session, const char *words)
{
const char *mech_list = smtp_sasl_compat_mechs(words);
char *junk;
/*
* XXX If the server offers no compatible authentication mechanisms, then
* pretend that the server doesn't support SASL authentication.
*
* XXX If the server offers multiple different lists, concatenate them. Let
* the SASL library worry about duplicates.
*/
if (session->sasl_mechanism_list) {
if (strcasecmp(session->sasl_mechanism_list, mech_list) == 0)
return;
if (strcasecmp(session->sasl_mechanism_list, mech_list) != 0
&& strlen(mech_list) > 0
&& strlen(session->sasl_mechanism_list) < var_line_limit) {
junk = concatenate(session->sasl_mechanism_list, " ", mech_list,
(char *) 0);
myfree(session->sasl_mechanism_list);
msg_warn("%s offered AUTH option multiple times", session->namaddr);
session->sasl_mechanism_list = 0;
session->features &= ~SMTP_FEATURE_AUTH;
session->sasl_mechanism_list = junk;
}
return;
}
if (strlen(mech_list) > 0) {
session->sasl_mechanism_list = mystrdup(mech_list);

View File

@ -1515,25 +1515,15 @@ static int permit_mx_primary(SMTPD_STATE *state, DNS_RR *mx_list,
{
const char *myname = "permit_mx_primary";
DNS_RR *mx;
unsigned int best_pref;
if (msg_verbose)
msg_info("%s", myname);
/*
* Find the preference of the primary MX hosts.
*/
for (best_pref = 0xffff, mx = mx_list; mx != 0; mx = mx->next)
if (mx->pref < best_pref)
best_pref = mx->pref;
/*
* See if each best MX host has all IP addresses in
* permit_mx_backup_networks.
*/
for (mx = mx_list; mx != 0; mx = mx->next) {
if (mx->pref != best_pref)
continue;
if (!all_auth_mx_addr(state, (char *) mx->data, reply_name, reply_class))
return (NOPE);
}
@ -1553,8 +1543,9 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient,
char *myname = "permit_mx_backup";
const RESOLVE_REPLY *reply;
const char *domain;
DNS_RR *mx_list;
DNS_RR *middle;
DNS_RR *rest;
int dns_status;
if (msg_verbose)
@ -1607,9 +1598,11 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient,
*/
dns_status = dns_lookup(domain, T_MX, 0, &mx_list,
(VSTRING *) 0, (VSTRING *) 0);
#if 0
if (dns_status == DNS_NOTFOUND)
return (has_my_addr(state, domain, reply_name, reply_class) ?
SMTPD_CHECK_OK : SMTPD_CHECK_DUNNO);
#endif
if (dns_status != DNS_OK) { /* incl. DNS_INVAL */
if (dns_status == DNS_RETRY)
DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
@ -1620,28 +1613,50 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient,
}
/*
* First, see if we match any of the MX host names listed.
* Separate MX list into primaries and backups.
*/
if (!i_am_mx(state, mx_list, reply_name, reply_class)) {
dns_rr_free(mx_list);
return (SMTPD_CHECK_DUNNO);
mx_list = dns_rr_sort(mx_list, dns_rr_compare_pref);
for (middle = mx_list; /* see below */ ; middle = rest) {
rest = middle->next;
if (rest == 0)
break;
if (rest->pref != mx_list->pref) {
middle->next = 0;
break;
}
}
/* postcondition: middle->next = 0, rest may be 0. */
#define PERMIT_MX_BACKUP_RETURN(x) do { \
middle->next = rest; \
dns_rr_free(mx_list); \
return (x); \
} while (0)
/*
* First, see if we match any of the primary MX servers.
*/
if (i_am_mx(state, mx_list, reply_name, reply_class))
PERMIT_MX_BACKUP_RETURN(SMTPD_CHECK_DUNNO);
/*
* Then, see if we match any of the backup MX servers.
*/
if (rest && !i_am_mx(state, rest, reply_name, reply_class))
PERMIT_MX_BACKUP_RETURN(SMTPD_CHECK_DUNNO);
/*
* Optionally, see if the primary MX hosts are in a restricted list of
* networks.
*/
if (*var_perm_mx_networks
&& !permit_mx_primary(state, mx_list, reply_name, reply_class)) {
dns_rr_free(mx_list);
return (SMTPD_CHECK_DUNNO);
}
&& !permit_mx_primary(state, mx_list, reply_name, reply_class))
PERMIT_MX_BACKUP_RETURN(SMTPD_CHECK_DUNNO);
/*
* The destination passed all requirements.
*/
dns_rr_free(mx_list);
return (SMTPD_CHECK_OK);
PERMIT_MX_BACKUP_RETURN(SMTPD_CHECK_OK);
}
/* reject_non_fqdn_address - fail if address is not in fqdn form */