mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 21:55:20 +00:00
postfix-1.1.11-20020823
This commit is contained in:
committed by
Viktor Dukhovni
parent
5958ff9688
commit
b464831bbc
@@ -6867,6 +6867,27 @@ Apologies for any names omitted.
|
||||
Patches by Will Day, Georgia Tech, and Carsten Hoeger,
|
||||
SUSE. File: util/dict_ldap.c.
|
||||
|
||||
20020823
|
||||
|
||||
Bugfix: added a missing memset() call to wipe the lookup
|
||||
key in dict_db_delete(). This is needed by some Berkeley
|
||||
DB implementations. Patch by Katsu Yamamoto, Fujitsu.
|
||||
|
||||
Bugfix: when permit_mx_backup is unable to make a decision
|
||||
due to DNS problems, set the "defer if reject" flag so that
|
||||
other restrictions will not cause mail to be rejected.
|
||||
File: smtpd/smtpd_check.c.
|
||||
|
||||
Feature: instead of giving up immediately after DNS failure,
|
||||
turn on the "defer_if_permit" flag when reject_unknown_hostname,
|
||||
reject_unknown_sender_domain or reject_unknown_recipient_domain
|
||||
are unable to make a decision, and see if any subsequent
|
||||
restrictions would still cause the mail to be rejected.
|
||||
File: smtpd/smtpd_check.c.
|
||||
|
||||
Feature: "FILTER transport:nexthop" is now also available
|
||||
in SMTPD access tables.
|
||||
|
||||
Open problems:
|
||||
|
||||
Low: smtpd should log queue ID with reject/warn/hold/discard
|
||||
|
@@ -12,6 +12,21 @@ snapshot release). Patches change the patchlevel and the release
|
||||
date. Snapshots change only the release date, unless they include
|
||||
the same bugfixes as a patch release.
|
||||
|
||||
Major changes with Postfix snapshot 1.1.11-20020823
|
||||
===================================================
|
||||
|
||||
More sophisticated handling of UCE-related DNS lookup errors.
|
||||
These cause Postfix to not give up so easily, so that some deliveries
|
||||
will not have to be deferred after all. This affects the following
|
||||
restrictions: permit_mx_backup (defer the request if any subsequent
|
||||
restriction would cause the request to be rejected, accept the
|
||||
request if any subsequent restriction would cause the request to
|
||||
be accepted); reject_unknown_hostname, reject_unknown_sender_domain
|
||||
and reject_unknown_recipient_domain (defer the request if any
|
||||
subsequent restriction would cause the request to be accepted,
|
||||
reject the request if any subsequent restriction would cause the
|
||||
request to be rejected).
|
||||
|
||||
Incompatible changes with Postfix snapshot 1.1.11-20020819
|
||||
==========================================================
|
||||
|
||||
@@ -38,7 +53,7 @@ rather than $myhostname. This seems to work better with Cyrus SASL
|
||||
version 2. This change may cause incompatibility with the saslpasswd2
|
||||
command.
|
||||
|
||||
Major changes with Postfix snapshot 1.1.11-20020818
|
||||
Major changes with Postfix snapshot 1.1.11-20020819
|
||||
===================================================
|
||||
|
||||
When the Postfix local delivery agent detects a mail delivery loop
|
||||
|
@@ -131,35 +131,41 @@
|
||||
# Claim successful delivery and silently discard the
|
||||
# message.
|
||||
#
|
||||
# FILTER transport:destination
|
||||
# After the message is queued, send the entire mes-
|
||||
# sage through a content filter. More information
|
||||
# about content filters is in the Postfix FIL-
|
||||
# TER_README file.
|
||||
#
|
||||
# restriction...
|
||||
# Apply the named UCE restriction(s) (permit, reject,
|
||||
# reject_unauth_destination, and so on).
|
||||
#
|
||||
# REGULAR EXPRESSION TABLES
|
||||
# This section describes how the table lookups change when
|
||||
# This section describes how the table lookups change when
|
||||
# the table is given in the form of regular expressions. For
|
||||
# a description of regular expression lookup table syntax,
|
||||
# a description of regular expression lookup table syntax,
|
||||
# see regexp_table(5) or pcre_table(5).
|
||||
#
|
||||
# Each pattern is a regular expression that is applied to
|
||||
# Each pattern is a regular expression that is applied to
|
||||
# the entire string being looked up. Depending on the appli-
|
||||
# cation, that string is an entire client hostname, an
|
||||
# cation, that string is an entire client hostname, an
|
||||
# entire client IP address, or an entire mail address. Thus,
|
||||
# no parent domain or parent network search is done,
|
||||
# user@domain mail addresses are not broken up into their
|
||||
# user@domain mail addresses are not broken up into their
|
||||
# user@ and domain constituent parts, nor is user+foo broken
|
||||
# up into user and foo.
|
||||
#
|
||||
# Patterns are applied in the order as specified in the
|
||||
# table, until a pattern is found that matches the search
|
||||
# Patterns are applied in the order as specified in the
|
||||
# table, until a pattern is found that matches the search
|
||||
# string.
|
||||
#
|
||||
# Actions are the same as with indexed file lookups, with
|
||||
# the additional feature that parenthesized substrings from
|
||||
# Actions are the same as with indexed file lookups, with
|
||||
# the additional feature that parenthesized substrings from
|
||||
# the pattern can be interpolated as $1, $2 and so on.
|
||||
#
|
||||
# BUGS
|
||||
# The table format does not understand quoting conventions.
|
||||
# The table format does not understand quoting conventions.
|
||||
#
|
||||
# SEE ALSO
|
||||
# postmap(1) create mapping table
|
||||
@@ -168,7 +174,7 @@
|
||||
# regexp_table(5) format of POSIX regular expression tables
|
||||
#
|
||||
# LICENSE
|
||||
# The Secure Mailer license must be distributed with this
|
||||
# The Secure Mailer license must be distributed with this
|
||||
# software.
|
||||
#
|
||||
# AUTHOR(S)
|
||||
|
@@ -132,35 +132,41 @@ ACCESS(5) ACCESS(5)
|
||||
Claim successful delivery and silently discard the
|
||||
message.
|
||||
|
||||
<b>FILTER</b> <i>transport:destination</i>
|
||||
After the message is queued, send the entire mes-
|
||||
sage through a content filter. More information
|
||||
about content filters is in the Postfix FIL-
|
||||
TER_README file.
|
||||
|
||||
<i>restriction...</i>
|
||||
Apply the named UCE restriction(s) (<b>permit</b>, <b>reject</b>,
|
||||
<b>reject</b><i>_</i><b>unauth</b><i>_</i><b>destination</b>, and so on).
|
||||
|
||||
<b>REGULAR</b> <b>EXPRESSION</b> <b>TABLES</b>
|
||||
This section describes how the table lookups change when
|
||||
This section describes how the table lookups change when
|
||||
the table is given in the form of regular expressions. For
|
||||
a description of regular expression lookup table syntax,
|
||||
a description of regular expression lookup table syntax,
|
||||
see <a href="regexp_table.5.html"><b>regexp</b><i>_</i><b>table</b>(5)</a> or <a href="pcre_table.5.html"><b>pcre</b><i>_</i><b>table</b>(5)</a>.
|
||||
|
||||
Each pattern is a regular expression that is applied to
|
||||
Each pattern is a regular expression that is applied to
|
||||
the entire string being looked up. Depending on the appli-
|
||||
cation, that string is an entire client hostname, an
|
||||
cation, that string is an entire client hostname, an
|
||||
entire client IP address, or an entire mail address. Thus,
|
||||
no parent domain or parent network search is done,
|
||||
<i>user@domain</i> mail addresses are not broken up into their
|
||||
<i>user@domain</i> mail addresses are not broken up into their
|
||||
<i>user@</i> and <i>domain</i> constituent parts, nor is <i>user+foo</i> broken
|
||||
up into <i>user</i> and <i>foo</i>.
|
||||
|
||||
Patterns are applied in the order as specified in the
|
||||
table, until a pattern is found that matches the search
|
||||
Patterns are applied in the order as specified in the
|
||||
table, until a pattern is found that matches the search
|
||||
string.
|
||||
|
||||
Actions are the same as with indexed file lookups, with
|
||||
the additional feature that parenthesized substrings from
|
||||
Actions are the same as with indexed file lookups, with
|
||||
the additional feature that parenthesized substrings from
|
||||
the pattern can be interpolated as <b>$1</b>, <b>$2</b> and so on.
|
||||
|
||||
<b>BUGS</b>
|
||||
The table format does not understand quoting conventions.
|
||||
The table format does not understand quoting conventions.
|
||||
|
||||
<b>SEE</b> <b>ALSO</b>
|
||||
<a href="postmap.1.html">postmap(1)</a> create mapping table
|
||||
@@ -169,7 +175,7 @@ ACCESS(5) ACCESS(5)
|
||||
<a href="regexp_table.5.html">regexp_table(5)</a> format of POSIX regular expression tables
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
||||
<b>AUTHOR(S)</b>
|
||||
|
@@ -126,6 +126,10 @@ POSTCONF(1) POSTCONF(1)
|
||||
<b>DIAGNOSTICS</b>
|
||||
Problems are reported to the standard error stream.
|
||||
|
||||
<b>ENVIRONMENT</b>
|
||||
<b>MAIL</b><i>_</i><b>CONFIG</b>
|
||||
Directory with Postfix configuration files.
|
||||
|
||||
<b>LICENSE</b>
|
||||
The Secure Mailer license must be distributed with this
|
||||
software.
|
||||
|
@@ -109,6 +109,13 @@ options make the software increasingly verbose.
|
||||
.ad
|
||||
.fi
|
||||
Problems are reported to the standard error stream.
|
||||
.SH ENVIRONMENT
|
||||
.na
|
||||
.nf
|
||||
.ad
|
||||
.fi
|
||||
.IP \fBMAIL_CONFIG\fR
|
||||
Directory with Postfix configuration files.
|
||||
.SH LICENSE
|
||||
.na
|
||||
.nf
|
||||
|
@@ -126,6 +126,10 @@ Mail that is placed on hold can be examined with the
|
||||
the \fBpostsuper\fR(1) command.
|
||||
.IP \fBDISCARD\fR
|
||||
Claim successful delivery and silently discard the message.
|
||||
.IP "\fBFILTER \fItransport:destination\fR"
|
||||
After the message is queued, send the entire message through
|
||||
a content filter. More information about content filters
|
||||
is in the Postfix FILTER_README file.
|
||||
.IP \fIrestriction...\fR
|
||||
Apply the named UCE restriction(s) (\fBpermit\fR, \fBreject\fR,
|
||||
\fBreject_unauth_destination\fR, and so on).
|
||||
|
@@ -110,6 +110,10 @@
|
||||
# the \fBpostsuper\fR(1) command.
|
||||
# .IP \fBDISCARD\fR
|
||||
# Claim successful delivery and silently discard the message.
|
||||
# .IP "\fBFILTER \fItransport:destination\fR"
|
||||
# After the message is queued, send the entire message through
|
||||
# a content filter. More information about content filters
|
||||
# is in the Postfix FILTER_README file.
|
||||
# .IP \fIrestriction...\fR
|
||||
# Apply the named UCE restriction(s) (\fBpermit\fR, \fBreject\fR,
|
||||
# \fBreject_unauth_destination\fR, and so on).
|
||||
|
@@ -20,7 +20,7 @@
|
||||
* Patches change the patchlevel and the release date. Snapshots change the
|
||||
* release date only, unless they include the same bugfix as a patch release.
|
||||
*/
|
||||
#define MAIL_RELEASE_DATE "20020822"
|
||||
#define MAIL_RELEASE_DATE "20020823"
|
||||
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "1.1.11-" MAIL_RELEASE_DATE
|
||||
|
@@ -101,6 +101,11 @@
|
||||
/* options make the software increasingly verbose.
|
||||
/* DIAGNOSTICS
|
||||
/* Problems are reported to the standard error stream.
|
||||
/* ENVIRONMENT
|
||||
/* .ad
|
||||
/* .fi
|
||||
/* .IP \fBMAIL_CONFIG\fR
|
||||
/* Directory with Postfix configuration files.
|
||||
/* LICENSE
|
||||
/* .ad
|
||||
/* .fi
|
||||
|
@@ -81,6 +81,10 @@ typedef struct SMTPD_STATE {
|
||||
VSTRING *sasl_decoded;
|
||||
#endif
|
||||
int warn_if_reject;
|
||||
int defer_if_reject; /* force reject into deferral */
|
||||
int defer_if_permit; /* force permit into deferral */
|
||||
VSTRING *defer_reason; /* reason why we force deferral */
|
||||
int defer_class; /* forced deferral error class */
|
||||
} SMTPD_STATE;
|
||||
|
||||
extern void smtpd_state_init(SMTPD_STATE *, VSTREAM *);
|
||||
|
@@ -315,11 +315,6 @@ static jmp_buf smtpd_check_buf;
|
||||
#define SMTPD_CHECK_OK 1 /* explicitly permit */
|
||||
#define SMTPD_CHECK_REJECT 2 /* explicitly reject */
|
||||
|
||||
/*
|
||||
* XXX For now define SMTPD_CHECK_TRYAGAIN as SMTPD_CHECK_OK.
|
||||
*/
|
||||
#define SMTPD_CHECK_TRYAGAIN 1 /* return 4xx try again */
|
||||
|
||||
/*
|
||||
* Intermediate results. These are static to avoid unnecessary stress on the
|
||||
* memory manager routines.
|
||||
@@ -387,6 +382,13 @@ static int generic_checks(SMTPD_STATE *, ARGV *, const char *, const char *, con
|
||||
#define STR vstring_str
|
||||
#define CONST_STR(x) ((const char *) vstring_str(x))
|
||||
|
||||
/*
|
||||
* If some decision can't be made due to a temporary error, then change
|
||||
* other decisions in to deferrals.
|
||||
*/
|
||||
static void PRINTFLIKE(3, 4) defer_if_reject(SMTPD_STATE *, int, const char *, ...);
|
||||
static void PRINTFLIKE(3, 4) defer_if_permit(SMTPD_STATE *, int, const char *, ...);
|
||||
|
||||
/* resolve_pagein - page in an address resolver result */
|
||||
|
||||
static void *resolve_pagein(const char *addr, void *unused_context)
|
||||
@@ -622,6 +624,11 @@ void smtpd_check_init(void)
|
||||
static void log_whatsup(SMTPD_STATE *state, const char *whatsup,
|
||||
const char *text)
|
||||
{
|
||||
|
||||
/*
|
||||
* XXX should include queue ID but that will break all existing logfile
|
||||
* parsers.
|
||||
*/
|
||||
if (state->recipient && state->sender) {
|
||||
msg_info("%s: %s from %s: %s; from=<%s> to=<%s>",
|
||||
whatsup, state->where, state->namaddr, text,
|
||||
@@ -700,8 +707,15 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
|
||||
* the UCE restrictions only. This would be at odds with documentation
|
||||
* which says soft_bounce changes all 5xx replies into 4xx ones.
|
||||
*/
|
||||
if (var_soft_bounce && STR(error_text)[0] == '5')
|
||||
STR(error_text)[0] = '4';
|
||||
if (STR(error_text)[0] == '5') {
|
||||
if (state->defer_if_reject) {
|
||||
state->defer_if_reject = 0;
|
||||
return (smtpd_check_reject(state, state->defer_class,
|
||||
"%s", STR(state->defer_reason)));
|
||||
}
|
||||
if (var_soft_bounce)
|
||||
STR(error_text)[0] = '4';
|
||||
}
|
||||
|
||||
/*
|
||||
* Log what is happening. When the sysadmin discards policy violation
|
||||
@@ -713,6 +727,38 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
|
||||
return (warn_if_reject ? 0 : SMTPD_CHECK_REJECT);
|
||||
}
|
||||
|
||||
/* defer_if_reject - prepare to change our mind */
|
||||
|
||||
static void defer_if_reject(SMTPD_STATE *state, int error_class,
|
||||
const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (state->defer_reason == 0)
|
||||
state->defer_reason = vstring_alloc(10);
|
||||
state->defer_class = error_class;
|
||||
va_start(ap, fmt);
|
||||
vstring_vsprintf(state->defer_reason, fmt, ap);
|
||||
va_end(ap);
|
||||
state->defer_if_reject = 1;
|
||||
}
|
||||
|
||||
/* defer_if_permit - prepare to change our mind */
|
||||
|
||||
static void defer_if_permit(SMTPD_STATE *state, int error_class,
|
||||
const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
if (state->defer_reason == 0)
|
||||
state->defer_reason = vstring_alloc(10);
|
||||
state->defer_class = error_class;
|
||||
va_start(ap, fmt);
|
||||
vstring_vsprintf(state->defer_reason, fmt, ap);
|
||||
va_end(ap);
|
||||
state->defer_if_permit = 1;
|
||||
}
|
||||
|
||||
/* reject_dict_retry - reject with temporary failure if dict lookup fails */
|
||||
|
||||
static void reject_dict_retry(SMTPD_STATE *state, const char *reply_name)
|
||||
@@ -980,12 +1026,15 @@ static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
|
||||
|
||||
dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
|
||||
(VSTRING *) 0, RR_ADDR_TYPES, T_MX, 0);
|
||||
if (dns_status != DNS_OK)
|
||||
if (dns_status == DNS_NOTFOUND)
|
||||
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
"%d <%s>: %s rejected: Host not found",
|
||||
dns_status == DNS_NOTFOUND ?
|
||||
var_unk_name_code : 450,
|
||||
var_unk_name_code,
|
||||
reply_name, reply_class));
|
||||
else if (dns_status != DNS_OK)
|
||||
defer_if_permit(state, MAIL_ERROR_POLICY,
|
||||
"450 <%s>: %s rejected: Host not found",
|
||||
reply_name, reply_class);
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
@@ -1002,12 +1051,15 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, const char *name,
|
||||
|
||||
dns_status = dns_lookup_types(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
|
||||
(VSTRING *) 0, RR_ADDR_TYPES, T_MX, 0);
|
||||
if (dns_status != DNS_OK)
|
||||
if (dns_status == DNS_NOTFOUND)
|
||||
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
"%d <%s>: %s rejected: Domain not found",
|
||||
dns_status == DNS_NOTFOUND ?
|
||||
var_unk_addr_code : 450,
|
||||
var_unk_addr_code,
|
||||
reply_name, reply_class));
|
||||
else if (dns_status != DNS_OK)
|
||||
defer_if_permit(state, MAIL_ERROR_POLICY,
|
||||
"450 <%s>: %s rejected: Domain not found",
|
||||
reply_name, reply_class);
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
@@ -1136,7 +1188,7 @@ static int reject_unauth_pipelining(SMTPD_STATE *state)
|
||||
|
||||
/* all_auth_mx_addr - match host addresses against permit_mx_backup_networks */
|
||||
|
||||
static int all_auth_mx_addr(char *host)
|
||||
static int all_auth_mx_addr(SMTPD_STATE *state, char *host)
|
||||
{
|
||||
char *myname = "all_auth_mx_addr";
|
||||
struct in_addr addr;
|
||||
@@ -1148,23 +1200,25 @@ static int all_auth_mx_addr(char *host)
|
||||
msg_info("%s: host %s", myname, host);
|
||||
|
||||
/*
|
||||
* If we can't lookup the host, try again.
|
||||
* If we can't lookup the host, defer.
|
||||
*/
|
||||
#define NOPE 0
|
||||
#define YUP 1
|
||||
#define TRYAGAIN 2
|
||||
|
||||
/*
|
||||
* Verify that all host addresses are within permit_mx_backup_networks.
|
||||
*/
|
||||
dns_status = dns_lookup(host, T_A, 0, &addr_list, (VSTRING *) 0, (VSTRING *) 0);
|
||||
if (dns_status != DNS_OK)
|
||||
return (TRYAGAIN);
|
||||
|
||||
if (dns_status != DNS_OK) {
|
||||
defer_if_reject(state, MAIL_ERROR_POLICY,
|
||||
"450 Unable to look up host %s as mail exchanger: %s",
|
||||
host, dns_strerror(h_errno));
|
||||
return (NOPE);
|
||||
}
|
||||
for (rr = addr_list; rr != 0; rr = rr->next) {
|
||||
if (rr->data_len > sizeof(addr)) {
|
||||
msg_warn("skipping address length %d for host %s",
|
||||
rr->data_len, host);
|
||||
msg_warn("%s: skipping address length %d for host %s",
|
||||
state->queue_id, rr->data_len, host);
|
||||
continue;
|
||||
}
|
||||
memcpy((char *) &addr, rr->data, sizeof(addr));
|
||||
@@ -1190,7 +1244,7 @@ static int all_auth_mx_addr(char *host)
|
||||
|
||||
/* has_my_addr - see if this host name lists one of my network addresses */
|
||||
|
||||
static int has_my_addr(const char *host)
|
||||
static int has_my_addr(SMTPD_STATE *state, const char *host)
|
||||
{
|
||||
char *myname = "has_my_addr";
|
||||
struct in_addr addr;
|
||||
@@ -1201,20 +1255,21 @@ static int has_my_addr(const char *host)
|
||||
msg_info("%s: host %s", myname, host);
|
||||
|
||||
/*
|
||||
* If we can't lookup the host, play safe and assume it is OK.
|
||||
* If we can't lookup the host, defer rather than reject.
|
||||
*/
|
||||
#define YUP 1
|
||||
#define NOPE 0
|
||||
|
||||
if ((hp = gethostbyname(host)) == 0) {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: host %s: not found", myname, host);
|
||||
return (YUP);
|
||||
defer_if_reject(state, MAIL_ERROR_POLICY,
|
||||
"450 Unable to look up host %s as mail exchanger: %s",
|
||||
host, dns_strerror(h_errno));
|
||||
return (NOPE);
|
||||
}
|
||||
if (hp->h_addrtype != AF_INET || hp->h_length != sizeof(addr)) {
|
||||
msg_warn("address type %d length %d for %s",
|
||||
hp->h_addrtype, hp->h_length, host);
|
||||
return (YUP);
|
||||
return (NOPE);
|
||||
}
|
||||
for (cpp = hp->h_addr_list; *cpp; cpp++) {
|
||||
memcpy((char *) &addr, *cpp, sizeof(addr));
|
||||
@@ -1231,7 +1286,7 @@ static int has_my_addr(const char *host)
|
||||
|
||||
/* i_am_mx - is this machine listed as MX relay */
|
||||
|
||||
static int i_am_mx(DNS_RR *mx_list)
|
||||
static int i_am_mx(SMTPD_STATE *state, DNS_RR *mx_list)
|
||||
{
|
||||
const char *myname = "permit_mx_backup";
|
||||
DNS_RR *mx;
|
||||
@@ -1253,7 +1308,7 @@ static int i_am_mx(DNS_RR *mx_list)
|
||||
for (mx = mx_list; mx != 0; mx = mx->next) {
|
||||
if (msg_verbose)
|
||||
msg_info("%s: address lookup: %s", myname, (char *) mx->data);
|
||||
if (has_my_addr((char *) mx->data))
|
||||
if (has_my_addr(state, (char *) mx->data))
|
||||
return (YUP);
|
||||
}
|
||||
|
||||
@@ -1267,11 +1322,10 @@ static int i_am_mx(DNS_RR *mx_list)
|
||||
|
||||
/* permit_mx_primary - authorize primary MX relays */
|
||||
|
||||
static int permit_mx_primary(DNS_RR *mx_list)
|
||||
static int permit_mx_primary(SMTPD_STATE *state, DNS_RR *mx_list)
|
||||
{
|
||||
DNS_RR *mx;
|
||||
unsigned int best_pref;
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Find the preference of the primary MX hosts.
|
||||
@@ -1287,18 +1341,15 @@ static int permit_mx_primary(DNS_RR *mx_list)
|
||||
for (mx = mx_list; mx != 0; mx = mx->next) {
|
||||
if (mx->pref != best_pref)
|
||||
continue;
|
||||
switch (status = all_auth_mx_addr((char *) mx->data)) {
|
||||
case TRYAGAIN:
|
||||
case NOPE:
|
||||
return (status);
|
||||
}
|
||||
if (!all_auth_mx_addr(state, (char *) mx->data))
|
||||
return (NOPE);
|
||||
}
|
||||
|
||||
/*
|
||||
* All IP addresses of the best MX hosts are within
|
||||
* permit_mx_backup_networks.
|
||||
*/
|
||||
return (YUP);
|
||||
return (mx_list ? YUP : NOPE);
|
||||
}
|
||||
|
||||
/* permit_mx_backup - permit use of me as MX backup for recipient domain */
|
||||
@@ -1355,19 +1406,23 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient)
|
||||
* Look up the list of MX host names for this domain. If no MX host is
|
||||
* found, perhaps it is a CNAME for the local machine. Clients aren't
|
||||
* supposed to send CNAMEs in SMTP commands, but it happens anyway. If we
|
||||
* can't look up the destination, play safe and assume it is OK.
|
||||
* can't look up the destination, play safe and turn reject into defer.
|
||||
*/
|
||||
dns_status = dns_lookup(domain, T_MX, 0, &mx_list,
|
||||
(VSTRING *) 0, (VSTRING *) 0);
|
||||
if (dns_status == DNS_NOTFOUND)
|
||||
return (has_my_addr(domain) ? SMTPD_CHECK_OK : SMTPD_CHECK_DUNNO);
|
||||
if (dns_status != DNS_OK)
|
||||
return (SMTPD_CHECK_TRYAGAIN);
|
||||
return (has_my_addr(state, domain) ? SMTPD_CHECK_OK : SMTPD_CHECK_DUNNO);
|
||||
if (dns_status != DNS_OK) {
|
||||
defer_if_reject(state, MAIL_ERROR_POLICY,
|
||||
"450 Unable to look up mail exchanger information: %s",
|
||||
dns_strerror(h_errno));
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
/*
|
||||
* First, see if we match any of the MX host names listed.
|
||||
*/
|
||||
if (!i_am_mx(mx_list)) {
|
||||
if (!i_am_mx(state, mx_list)) {
|
||||
dns_rr_free(mx_list);
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
@@ -1376,7 +1431,7 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient)
|
||||
* Optionally, see if the primary MX hosts are in a restricted list of
|
||||
* networks.
|
||||
*/
|
||||
if (*var_perm_mx_networks && !permit_mx_primary(mx_list)) {
|
||||
if (*var_perm_mx_networks && !permit_mx_primary(state, mx_list)) {
|
||||
dns_rr_free(mx_list);
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
@@ -1508,6 +1563,26 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
|
||||
"%d <%s>: %s rejected: Access denied",
|
||||
var_access_map_code, reply_name, reply_class));
|
||||
|
||||
/*
|
||||
* FILTER means deliver to content filter. But we may still change our
|
||||
* mind, and reject/discard the message for other reasons.
|
||||
*/
|
||||
#define FILTER_LEN (sizeof("FILTER") - 1)
|
||||
|
||||
if (strncasecmp(value, "FILTER", FILTER_LEN) == 0
|
||||
&& (value[FILTER_LEN] == 0 || ISSPACE(value[FILTER_LEN]))) {
|
||||
value += FILTER_LEN;
|
||||
while (ISSPACE(*value))
|
||||
value++;
|
||||
vstring_sprintf(error_text, "<%s>: %s triggers FILTER %s",
|
||||
reply_name, reply_class, value);
|
||||
log_whatsup(state, "hold", STR(error_text));
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FILT, "%s", value);
|
||||
#endif
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
/*
|
||||
* HOLD means deliver later. But we may still change our mind, and
|
||||
* reject/discard the message for other reasons.
|
||||
@@ -2292,6 +2367,10 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
|
||||
|
||||
state->recursion = saved_recursion;
|
||||
|
||||
if (status == SMTPD_CHECK_REJECT || status == SMTPD_CHECK_DUNNO)
|
||||
if (state->defer_if_permit)
|
||||
status = smtpd_check_reject(state, state->defer_class,
|
||||
"450 %s", STR(state->defer_reason));
|
||||
return (status);
|
||||
}
|
||||
|
||||
@@ -2311,6 +2390,9 @@ char *smtpd_check_client(SMTPD_STATE *state)
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
state->recursion = 1;
|
||||
state->warn_if_reject = 0;
|
||||
state->defer_if_reject = 0;
|
||||
state->defer_if_permit = 0;
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status == 0 && client_restrctions->argc)
|
||||
status = generic_checks(state, client_restrctions, state->namaddr,
|
||||
@@ -2357,6 +2439,9 @@ char *smtpd_check_helo(SMTPD_STATE *state, char *helohost)
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
state->recursion = 1;
|
||||
state->warn_if_reject = 0;
|
||||
state->defer_if_reject = 0;
|
||||
state->defer_if_permit = 0;
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status == 0 && helo_restrctions->argc)
|
||||
status = generic_checks(state, helo_restrctions, state->helo_name,
|
||||
@@ -2393,6 +2478,9 @@ char *smtpd_check_mail(SMTPD_STATE *state, char *sender)
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
state->recursion = 1;
|
||||
state->warn_if_reject = 0;
|
||||
state->defer_if_reject = 0;
|
||||
state->defer_if_permit = 0;
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status == 0 && mail_restrctions->argc)
|
||||
status = generic_checks(state, mail_restrctions, sender,
|
||||
@@ -2447,6 +2535,9 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
state->recursion = 1;
|
||||
state->warn_if_reject = 0;
|
||||
state->defer_if_reject = 0;
|
||||
state->defer_if_permit = 0;
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status == 0 && rcpt_restrctions->argc)
|
||||
status = generic_checks(state, rcpt_restrctions,
|
||||
@@ -2492,6 +2583,9 @@ char *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
|
||||
* Apply restrictions in the order as specified.
|
||||
*/
|
||||
state->recursion = 1;
|
||||
state->warn_if_reject = 0;
|
||||
state->defer_if_reject = 0;
|
||||
state->defer_if_permit = 0;
|
||||
status = setjmp(smtpd_check_buf);
|
||||
if (status == 0 && etrn_restrctions->argc)
|
||||
status = generic_checks(state, etrn_restrctions, domain,
|
||||
|
@@ -91,7 +91,7 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream)
|
||||
state->recursion = 0;
|
||||
state->msg_size = 0;
|
||||
state->junk_cmds = 0;
|
||||
state->warn_if_reject = 0;
|
||||
state->defer_reason = 0;
|
||||
|
||||
#ifdef USE_SASL_AUTH
|
||||
if (SMTPD_STAND_ALONE(state))
|
||||
@@ -124,6 +124,8 @@ void smtpd_state_reset(SMTPD_STATE *state)
|
||||
if (state->buffer)
|
||||
vstring_free(state->buffer);
|
||||
smtpd_peer_reset(state);
|
||||
if (state->defer_reason)
|
||||
vstring_free(state->defer_reason);
|
||||
|
||||
#ifdef USE_SASL_AUTH
|
||||
if (var_smtpd_sasl_enable)
|
||||
|
@@ -302,6 +302,8 @@ static int dict_db_delete(DICT *dict, const char *name)
|
||||
int status = 1;
|
||||
int flags = 0;
|
||||
|
||||
memset(&db_key, 0, sizeof(db_key));
|
||||
|
||||
/*
|
||||
* Acquire an exclusive lock.
|
||||
*/
|
||||
|
Reference in New Issue
Block a user