mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 13:48:06 +00:00
postfix-2.3-20050726
This commit is contained in:
parent
01c5f58c4b
commit
3fb1ad8ad5
@ -11050,6 +11050,18 @@ Apologies for any names omitted.
|
||||
client IP address). Files: global/mail_params.h,
|
||||
smtpd/smtpd_peer.c, smtpd/smtpd.c, smtpd/smtpd_check.c.
|
||||
|
||||
20050726
|
||||
|
||||
Horror: total rewrite of DNS client error handling because
|
||||
some misguided proposal attempts to give special meaning
|
||||
to some syntactically invalid MX hostname lookup result.
|
||||
Not only that, people expect sensible results with
|
||||
reject_unknown_sender_domain etc. Files: dns/dns_lookup.c,
|
||||
smtp/smtp_addr.c smtpd/smtpd_check.c, lmtp/lmtp_addr.c.
|
||||
|
||||
Cleanup: HOLD action executes only once, to reduce noise
|
||||
in the logfile. Files: cleanup/cleanup_message.c, smtpd/smtpd.c.
|
||||
|
||||
Open problems:
|
||||
|
||||
Med: when the cleanup server bounces local mail that should
|
||||
|
@ -17,7 +17,32 @@ 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 20050715
|
||||
Incompatibility with snapshot 20050726
|
||||
======================================
|
||||
|
||||
Name server replies that contain a malformed hostname are now flagged
|
||||
as permanent errors instead of transient errors. This change works
|
||||
around a questionable proposal to use syntactically invalid hostnames
|
||||
in MX records.
|
||||
|
||||
Major changes with snapshot 20050724
|
||||
====================================
|
||||
|
||||
SMTPD Access control based on the existence of an address->name
|
||||
mapping, with reject_unknown_reverse_client_hostname. There is
|
||||
no corresponding access table lookup feature, because the name
|
||||
is not validated in any way (except that it has proper syntax).
|
||||
|
||||
Several confusing SMTPD access restrictions were renamed:
|
||||
|
||||
reject_unknown_client -> reject_unknown_client_hostname,
|
||||
reject_unknown_hostname -> reject_unknown_helo_hostname,
|
||||
reject_invalid_hostname -> reject_invalid_helo_hostname,
|
||||
reject_non_fqdn_hostname -> reject_non_fqdn_helo_hostname.
|
||||
|
||||
The old names are still recognized and documented.
|
||||
|
||||
Incompatibility with snapshot 20050716
|
||||
======================================
|
||||
|
||||
Internal interfaces have changed; this may break third-party patches
|
||||
@ -40,7 +65,7 @@ report "(unsigned) int" versus "(s)size_t" format string argument
|
||||
mis-matches on 32-bit systems; they can be found only on 64-bit
|
||||
systems.
|
||||
|
||||
Major changes with snapshot 20050715
|
||||
Major changes with snapshot 20050716
|
||||
====================================
|
||||
|
||||
Improved portability to LP64 systems, by converting the type of
|
||||
|
@ -8132,11 +8132,13 @@ code for rejected requests (default: 554). </dd>
|
||||
|
||||
<dt><b><a name="reject_unknown_recipient_domain">reject_unknown_recipient_domain</a></b></dt>
|
||||
|
||||
<dd>Reject the request when the RCPT TO address has no DNS A or MX
|
||||
record and Postfix is not final destination for the recipient
|
||||
address. <br> The <a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies
|
||||
the response code for rejected requests (default: 450). The response
|
||||
is always 450 in case of a temporary DNS error.</dd>
|
||||
<dd>Reject the request when Postfix is not final destination for
|
||||
the recipient address, and the RCPT TO address has no DNS A or MX
|
||||
record, or when it has a malformed MX record such as a record with
|
||||
a zero-length MX hostname (Postfix 2.3 and later). <br> The
|
||||
<a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies the response code
|
||||
for rejected requests (default: 450). The response is always 450
|
||||
in case of a temporary DNS error.</dd>
|
||||
|
||||
<dt><b><a name="reject_unlisted_recipient">reject_unlisted_recipient</a></b> (with Postfix 2.0: check_recipient_maps)</dt>
|
||||
|
||||
@ -8602,11 +8604,13 @@ Postfix version 2.1 and later. </dd>
|
||||
|
||||
<dt><b><a name="reject_unknown_sender_domain">reject_unknown_sender_domain</a></b></dt>
|
||||
|
||||
<dd>Reject the request when the MAIL FROM address has no DNS A or
|
||||
MX record and Postfix is not final destination for the sender
|
||||
address. <br> The <a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies
|
||||
the response code for rejected requests (default: 450). The response
|
||||
is always 450 in case of a temporary DNS error. </dd>
|
||||
<dd>Reject the request when Postfix is not final destination for
|
||||
the sender address, and the MAIL FROM address has no DNS A or MX
|
||||
record, or when it has a malformed MX record such as a record with
|
||||
a zero-length MX hostname (Postfix 2.3 and later). <br> The
|
||||
<a href="postconf.5.html#unknown_address_reject_code">unknown_address_reject_code</a> parameter specifies the response code
|
||||
for rejected requests (default: 450). The response is always 450
|
||||
in case of a temporary DNS error. </dd>
|
||||
|
||||
<dt><b><a name="reject_unlisted_sender">reject_unlisted_sender</a></b></dt>
|
||||
|
||||
|
@ -4648,13 +4648,15 @@ no sender-specified routing (user@elsewhere@domain).
|
||||
The relay_domains_reject_code parameter specifies the response
|
||||
code for rejected requests (default: 554).
|
||||
.IP "\fBreject_unknown_recipient_domain\fR"
|
||||
Reject the request when the RCPT TO address has no DNS A or MX
|
||||
record and Postfix is not final destination for the recipient
|
||||
address.
|
||||
Reject the request when Postfix is not final destination for
|
||||
the recipient address, and the RCPT TO address has no DNS A or MX
|
||||
record, or when it has a malformed MX record such as a record with
|
||||
a zero-length MX hostname (Postfix 2.3 and later).
|
||||
.br
|
||||
The unknown_address_reject_code parameter specifies
|
||||
the response code for rejected requests (default: 450). The response
|
||||
is always 450 in case of a temporary DNS error.
|
||||
The
|
||||
unknown_address_reject_code parameter specifies the response code
|
||||
for rejected requests (default: 450). The response is always 450
|
||||
in case of a temporary DNS error.
|
||||
.IP "\fBreject_unlisted_recipient\fR (with Postfix 2.0: check_recipient_maps)"
|
||||
Reject the request when the RCPT TO address is not listed in
|
||||
the list of valid recipients for its domain class. See the
|
||||
@ -4953,13 +4955,15 @@ Enforces the reject_sender_login_mismatch restriction for
|
||||
unauthenticated clients only. This feature is available in
|
||||
Postfix version 2.1 and later.
|
||||
.IP "\fBreject_unknown_sender_domain\fR"
|
||||
Reject the request when the MAIL FROM address has no DNS A or
|
||||
MX record and Postfix is not final destination for the sender
|
||||
address.
|
||||
Reject the request when Postfix is not final destination for
|
||||
the sender address, and the MAIL FROM address has no DNS A or MX
|
||||
record, or when it has a malformed MX record such as a record with
|
||||
a zero-length MX hostname (Postfix 2.3 and later).
|
||||
.br
|
||||
The unknown_address_reject_code parameter specifies
|
||||
the response code for rejected requests (default: 450). The response
|
||||
is always 450 in case of a temporary DNS error.
|
||||
The
|
||||
unknown_address_reject_code parameter specifies the response code
|
||||
for rejected requests (default: 450). The response is always 450
|
||||
in case of a temporary DNS error.
|
||||
.IP "\fBreject_unlisted_sender\fR"
|
||||
Reject the request when the MAIL FROM address is not listed in
|
||||
the list of valid recipients for its domain class. See the
|
||||
|
@ -5150,11 +5150,13 @@ code for rejected requests (default: 554). </dd>
|
||||
|
||||
<dt><b><a name="reject_unknown_recipient_domain">reject_unknown_recipient_domain</a></b></dt>
|
||||
|
||||
<dd>Reject the request when the RCPT TO address has no DNS A or MX
|
||||
record and Postfix is not final destination for the recipient
|
||||
address. <br> The unknown_address_reject_code parameter specifies
|
||||
the response code for rejected requests (default: 450). The response
|
||||
is always 450 in case of a temporary DNS error.</dd>
|
||||
<dd>Reject the request when Postfix is not final destination for
|
||||
the recipient address, and the RCPT TO address has no DNS A or MX
|
||||
record, or when it has a malformed MX record such as a record with
|
||||
a zero-length MX hostname (Postfix 2.3 and later). <br> The
|
||||
unknown_address_reject_code parameter specifies the response code
|
||||
for rejected requests (default: 450). The response is always 450
|
||||
in case of a temporary DNS error.</dd>
|
||||
|
||||
<dt><b><a name="reject_unlisted_recipient">reject_unlisted_recipient</a></b> (with Postfix 2.0: check_recipient_maps)</dt>
|
||||
|
||||
@ -5488,11 +5490,13 @@ Postfix version 2.1 and later. </dd>
|
||||
|
||||
<dt><b><a name="reject_unknown_sender_domain">reject_unknown_sender_domain</a></b></dt>
|
||||
|
||||
<dd>Reject the request when the MAIL FROM address has no DNS A or
|
||||
MX record and Postfix is not final destination for the sender
|
||||
address. <br> The unknown_address_reject_code parameter specifies
|
||||
the response code for rejected requests (default: 450). The response
|
||||
is always 450 in case of a temporary DNS error. </dd>
|
||||
<dd>Reject the request when Postfix is not final destination for
|
||||
the sender address, and the MAIL FROM address has no DNS A or MX
|
||||
record, or when it has a malformed MX record such as a record with
|
||||
a zero-length MX hostname (Postfix 2.3 and later). <br> The
|
||||
unknown_address_reject_code parameter specifies the response code
|
||||
for rejected requests (default: 450). The response is always 450
|
||||
in case of a temporary DNS error. </dd>
|
||||
|
||||
<dt><b><a name="reject_unlisted_sender">reject_unlisted_sender</a></b></dt>
|
||||
|
||||
|
@ -317,7 +317,7 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context,
|
||||
state->reason = dsn_prepend("5.7.1", optional_text);
|
||||
if (*state->reason != '4' && *state->reason != '5') {
|
||||
msg_warn("bad DSN action in %s -- need 4.x.x or 5.x.x",
|
||||
optional_text);
|
||||
optional_text);
|
||||
*state->reason = '4';
|
||||
}
|
||||
} else {
|
||||
@ -356,8 +356,10 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context,
|
||||
return (buf);
|
||||
}
|
||||
if (STREQUAL(value, "HOLD", command_len)) {
|
||||
cleanup_act_log(state, "hold", context, buf, optional_text);
|
||||
state->flags |= CLEANUP_FLAG_HOLD;
|
||||
if ((state->flags & CLEANUP_FLAG_HOLD) == 0) {
|
||||
cleanup_act_log(state, "hold", context, buf, optional_text);
|
||||
state->flags |= CLEANUP_FLAG_HOLD;
|
||||
}
|
||||
return (buf);
|
||||
}
|
||||
if (STREQUAL(value, "PREPEND", command_len)) {
|
||||
|
@ -157,13 +157,15 @@ extern int dns_lookup_v(const char *, unsigned, DNS_RR **, VSTRING *,
|
||||
/*
|
||||
* Request flags.
|
||||
*/
|
||||
#define DNS_REQ_FLAG_ANY (1<<0)
|
||||
#define DNS_REQ_FLAG_ALL (1<<1)
|
||||
#define DNS_REQ_FLAG_STOP_OK (1<<0)
|
||||
#define DNS_REQ_FLAG_STOP_INVAL (1<<1)
|
||||
#define DNS_REQ_FLAG_NONE (0)
|
||||
|
||||
/*
|
||||
* Status codes. Failures must have negative codes so they will not collide
|
||||
* with valid counts of answer records etc.
|
||||
*/
|
||||
#define DNS_INVAL (-5) /* query ok, malformed reply */
|
||||
#define DNS_FAIL (-4) /* query failed, don't retry */
|
||||
#define DNS_NOTFOUND (-3) /* query ok, data not found */
|
||||
#define DNS_RETRY (-2) /* query failed, try again */
|
||||
|
@ -37,7 +37,8 @@
|
||||
/* number of CNAME indirections. All result names (including
|
||||
/* null terminator) will fit a buffer of size DNS_NAME_LEN.
|
||||
/* All name results are validated by \fIvalid_hostname\fR();
|
||||
/* an invalid name is reported as a transient error.
|
||||
/* an invalid name is reported as a DNS_INVAL result, while
|
||||
/* malformed replies are reported as transient errors.
|
||||
/*
|
||||
/* dns_lookup_l() and dns_lookup_v() allow the user to specify
|
||||
/* a list of resource types.
|
||||
@ -46,6 +47,8 @@
|
||||
/* .fi
|
||||
/* .IP name
|
||||
/* The name to be looked up in the domain name system.
|
||||
/* This name must pass the valid_hostname() test; it
|
||||
/* must not be an IP address.
|
||||
/* .IP type
|
||||
/* The resource record type to be looked up (T_A, T_MX etc.).
|
||||
/* .IP rflags
|
||||
@ -59,16 +62,18 @@
|
||||
/* Append local domain to unqualified names.
|
||||
/* .RE
|
||||
/* .IP lflags
|
||||
/* Multi-type request control for dns_lookup_l() and
|
||||
/* dns_lookup_v(). This is one of the following:
|
||||
/* Multi-type request control for dns_lookup_l() and dns_lookup_v().
|
||||
/* For convenience, DNS_REQ_FLAG_NONE requests no special
|
||||
/* processing. Invoke dns_lookup() for all specified resource
|
||||
/* record types in the specified order, and merge their results.
|
||||
/* Otherwise, specify one or more of the following:
|
||||
/* .RS
|
||||
/* .IP DNS_REQ_FLAG_ANY
|
||||
/* Call dns_lookup() for each specified resource record type
|
||||
/* in the specified order, until the list is exhausted or
|
||||
/* until some result is DNS_OK.
|
||||
/* .IP DNS_REQ_FLAG_ALL
|
||||
/* Call dns_lookup() for all specified resource record types
|
||||
/* in the specified order, and merge their results.
|
||||
/* .IP DNS_REQ_FLAG_STOP_INVAL
|
||||
/* Invoke dns_lookup() for the resource types in the order as
|
||||
/* specified, and return when dns_lookup() returns DNS_INVAL.
|
||||
/* .IP DNS_REQ_FLAG_STOP_OK
|
||||
/* Invoke dns_lookup() for the resource types in the order as
|
||||
/* specified, and return when dns_lookup() returns DNS_OK.
|
||||
/* .RE
|
||||
/* .IP ltype
|
||||
/* The resource record types to be looked up. In the case of
|
||||
@ -93,8 +98,11 @@
|
||||
/* The DNS query succeeded.
|
||||
/* .IP DNS_NOTFOUND
|
||||
/* The DNS query succeeded; the requested information was not found.
|
||||
/* .IP DNS_INVAL
|
||||
/* The DNS query succeeded; the result failed the valid_hostname() test.
|
||||
/* .IP DNS_RETRY
|
||||
/* The query failed; the problem is transient.
|
||||
/* The query failed, or the reply was malformed.
|
||||
/* The problem is considered transient.
|
||||
/* .IP DNS_FAIL
|
||||
/* The query failed.
|
||||
/* BUGS
|
||||
@ -142,8 +150,8 @@
|
||||
/*
|
||||
* Structure to keep track of things while decoding a name server reply.
|
||||
*/
|
||||
#define DEF_DNS_REPLY_SIZE 4096 /* in case we're using TCP */
|
||||
#define MAX_DNS_REPLY_SIZE 32768 /* in case we're using TCP */
|
||||
#define DEF_DNS_REPLY_SIZE 4096 /* in case we're using TCP */
|
||||
#define MAX_DNS_REPLY_SIZE 32768 /* in case we're using TCP */
|
||||
|
||||
typedef struct DNS_REPLY {
|
||||
unsigned char *buf; /* raw reply data */
|
||||
@ -341,8 +349,8 @@ static int valid_rr_name(const char *name, const char *location,
|
||||
|
||||
/* dns_get_rr - extract resource record from name server reply */
|
||||
|
||||
static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
|
||||
char *rr_name, DNS_FIXED *fixed)
|
||||
static int dns_get_rr(DNS_RR **list, DNS_REPLY *reply, unsigned char *pos,
|
||||
char *rr_name, DNS_FIXED *fixed)
|
||||
{
|
||||
char temp[DNS_NAME_LEN];
|
||||
ssize_t data_len;
|
||||
@ -353,8 +361,9 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
|
||||
|
||||
#define MIN2(a, b) ((unsigned)(a) < (unsigned)(b) ? (a) : (b))
|
||||
|
||||
*list = 0;
|
||||
if (pos + fixed->length > reply->end)
|
||||
return (0);
|
||||
return (DNS_RETRY);
|
||||
|
||||
switch (fixed->type) {
|
||||
default:
|
||||
@ -367,23 +376,23 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
|
||||
case T_NS:
|
||||
case T_PTR:
|
||||
if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
|
||||
return (0);
|
||||
return (DNS_RETRY);
|
||||
if (!valid_rr_name(temp, "resource data", fixed->type, reply))
|
||||
return (0);
|
||||
return (DNS_INVAL);
|
||||
data_len = strlen(temp) + 1;
|
||||
break;
|
||||
case T_MX:
|
||||
GETSHORT(pref, pos);
|
||||
if (dn_expand(reply->buf, reply->end, pos, temp, sizeof(temp)) < 0)
|
||||
return (0);
|
||||
return (DNS_RETRY);
|
||||
if (!valid_rr_name(temp, "resource data", fixed->type, reply))
|
||||
return (0);
|
||||
return (DNS_INVAL);
|
||||
data_len = strlen(temp) + 1;
|
||||
break;
|
||||
case T_A:
|
||||
if (fixed->length != INET_ADDR_LEN) {
|
||||
msg_warn("extract_answer: bad address length: %d", fixed->length);
|
||||
return (0);
|
||||
return (DNS_RETRY);
|
||||
}
|
||||
if (fixed->length > sizeof(temp))
|
||||
msg_panic("dns_get_rr: length %d > DNS_NAME_LEN",
|
||||
@ -395,7 +404,7 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
|
||||
case T_AAAA:
|
||||
if (fixed->length != INET6_ADDR_LEN) {
|
||||
msg_warn("extract_answer: bad address length: %d", fixed->length);
|
||||
return (0);
|
||||
return (DNS_RETRY);
|
||||
}
|
||||
if (fixed->length > sizeof(temp))
|
||||
msg_panic("dns_get_rr: length %d > DNS_NAME_LEN",
|
||||
@ -414,8 +423,9 @@ static DNS_RR *dns_get_rr(DNS_REPLY *reply, unsigned char *pos,
|
||||
*dst = 0;
|
||||
break;
|
||||
}
|
||||
return (dns_rr_create(rr_name, fixed->type, fixed->class, fixed->ttl,
|
||||
pref, temp, data_len));
|
||||
*list = dns_rr_create(rr_name, fixed->type, fixed->class, fixed->ttl,
|
||||
pref, temp, data_len);
|
||||
return (DNS_OK);
|
||||
}
|
||||
|
||||
/* dns_get_alias - extract CNAME from name server reply */
|
||||
@ -428,7 +438,7 @@ static int dns_get_alias(DNS_REPLY *reply, unsigned char *pos,
|
||||
if (dn_expand(reply->buf, reply->end, pos, cname, c_len) < 0)
|
||||
return (DNS_RETRY);
|
||||
if (!valid_rr_name(cname, "resource data", fixed->type, reply))
|
||||
return (DNS_RETRY);
|
||||
return (DNS_INVAL);
|
||||
return (DNS_OK);
|
||||
}
|
||||
|
||||
@ -445,14 +455,15 @@ static int dns_get_answer(DNS_REPLY *reply, int type,
|
||||
DNS_RR *rr;
|
||||
int resource_found = 0;
|
||||
int cname_found = 0;
|
||||
int not_found_status = DNS_NOTFOUND;
|
||||
int not_found_status = DNS_RETRY; /* can't happen */
|
||||
int status;
|
||||
|
||||
/*
|
||||
* Initialize. Skip over the name server query if we haven't yet.
|
||||
*/
|
||||
if (reply->answer_start == 0)
|
||||
if (dns_skip_query(reply) < 0)
|
||||
return (DNS_RETRY);
|
||||
if ((status = dns_skip_query(reply)) < 0)
|
||||
return (status);
|
||||
pos = reply->answer_start;
|
||||
if (rrlist)
|
||||
*rrlist = 0;
|
||||
@ -461,12 +472,12 @@ static int dns_get_answer(DNS_REPLY *reply, int type,
|
||||
* Either this, or use a GOTO for emergency exits. The purpose is to
|
||||
* prevent incomplete answers from being passed back to the caller.
|
||||
*/
|
||||
#define CORRUPT { \
|
||||
#define CORRUPT(status) { \
|
||||
if (rrlist && *rrlist) { \
|
||||
dns_rr_free(*rrlist); \
|
||||
*rrlist = 0; \
|
||||
} \
|
||||
return (DNS_RETRY); \
|
||||
return (status); \
|
||||
}
|
||||
|
||||
/*
|
||||
@ -478,21 +489,21 @@ static int dns_get_answer(DNS_REPLY *reply, int type,
|
||||
* Optionally extract the fully-qualified domain name.
|
||||
*/
|
||||
if (pos >= reply->end)
|
||||
CORRUPT;
|
||||
CORRUPT(DNS_RETRY);
|
||||
len = dn_expand(reply->buf, reply->end, pos, rr_name, DNS_NAME_LEN);
|
||||
if (len < 0)
|
||||
CORRUPT;
|
||||
CORRUPT(DNS_RETRY);
|
||||
pos += len;
|
||||
|
||||
/*
|
||||
* Extract the fixed reply data: type, class, ttl, length.
|
||||
*/
|
||||
if (pos + RRFIXEDSZ > reply->end)
|
||||
CORRUPT;
|
||||
if (dns_get_fixed(pos, &fixed) != DNS_OK)
|
||||
CORRUPT;
|
||||
CORRUPT(DNS_RETRY);
|
||||
if ((status = dns_get_fixed(pos, &fixed)) != DNS_OK)
|
||||
CORRUPT(status);
|
||||
if (!valid_rr_name(rr_name, "resource name", fixed.type, reply))
|
||||
CORRUPT;
|
||||
CORRUPT(DNS_INVAL);
|
||||
if (fqdn)
|
||||
vstring_strcpy(fqdn, rr_name);
|
||||
if (msg_verbose)
|
||||
@ -504,21 +515,21 @@ static int dns_get_answer(DNS_REPLY *reply, int type,
|
||||
* Optionally extract the requested resource or CNAME data.
|
||||
*/
|
||||
if (pos + fixed.length > reply->end)
|
||||
CORRUPT;
|
||||
CORRUPT(DNS_RETRY);
|
||||
if (type == fixed.type || type == T_ANY) { /* requested type */
|
||||
if (rrlist) {
|
||||
if ((rr = dns_get_rr(reply, pos, rr_name, &fixed)) != 0) {
|
||||
if ((status = dns_get_rr(&rr, reply, pos, rr_name, &fixed)) == DNS_OK) {
|
||||
resource_found++;
|
||||
*rrlist = dns_rr_append(*rrlist, rr);
|
||||
} else
|
||||
not_found_status = DNS_RETRY;
|
||||
} else if (not_found_status != DNS_RETRY)
|
||||
not_found_status = status;
|
||||
} else
|
||||
resource_found++;
|
||||
} else if (fixed.type == T_CNAME) { /* cname resource */
|
||||
cname_found++;
|
||||
if (cname && c_len > 0)
|
||||
if (dns_get_alias(reply, pos, &fixed, cname, c_len) != DNS_OK)
|
||||
CORRUPT;
|
||||
if ((status = dns_get_alias(reply, pos, &fixed, cname, c_len)) != DNS_OK)
|
||||
CORRUPT(status);
|
||||
}
|
||||
pos += fixed.length;
|
||||
}
|
||||
@ -591,10 +602,9 @@ int dns_lookup(const char *name, unsigned type, unsigned flags,
|
||||
default:
|
||||
if (why)
|
||||
vstring_sprintf(why, "Name service error for name=%s type=%s: "
|
||||
"Malformed name server reply",
|
||||
"Malformed or unexpected name server reply",
|
||||
name, dns_strtype(type));
|
||||
case DNS_OK:
|
||||
case DNS_NOTFOUND:
|
||||
return (status);
|
||||
case DNS_RECURSE:
|
||||
if (msg_verbose)
|
||||
@ -633,7 +643,10 @@ int dns_lookup_l(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
non_err = 1;
|
||||
if (rrlist)
|
||||
*rrlist = dns_rr_append(*rrlist, rr);
|
||||
if (lflags == DNS_REQ_FLAG_ANY)
|
||||
if (lflags & DNS_REQ_FLAG_STOP_OK)
|
||||
break;
|
||||
} else if (status == DNS_INVAL) {
|
||||
if (lflags & DNS_REQ_FLAG_STOP_INVAL)
|
||||
break;
|
||||
} else if (status == DNS_RETRY) {
|
||||
soft_err = 1;
|
||||
@ -667,7 +680,10 @@ int dns_lookup_v(const char *name, unsigned flags, DNS_RR **rrlist,
|
||||
non_err = 1;
|
||||
if (rrlist)
|
||||
*rrlist = dns_rr_append(*rrlist, rr);
|
||||
if (lflags == DNS_REQ_FLAG_ANY)
|
||||
if (lflags & DNS_REQ_FLAG_STOP_OK)
|
||||
break;
|
||||
} else if (status == DNS_INVAL) {
|
||||
if (lflags & DNS_REQ_FLAG_STOP_INVAL)
|
||||
break;
|
||||
} else if (status == DNS_RETRY) {
|
||||
soft_err = 1;
|
||||
|
@ -100,7 +100,7 @@ int main(int argc, char **argv)
|
||||
name = argv[2];
|
||||
msg_verbose = 1;
|
||||
switch (dns_lookup_v(name, RES_DEFNAMES | RES_DEBUG, &rr, fqdn, why,
|
||||
DNS_REQ_FLAG_ALL, types)) {
|
||||
DNS_REQ_FLAG_NONE, types)) {
|
||||
default:
|
||||
msg_fatal("%s", vstring_str(why));
|
||||
case DNS_OK:
|
||||
|
@ -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 "20050724"
|
||||
#define MAIL_RELEASE_DATE "20050726"
|
||||
#define MAIL_VERSION_NUMBER "2.3"
|
||||
|
||||
#ifdef SNAPSHOT
|
||||
|
@ -191,7 +191,7 @@ static DNS_RR *lmtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref,
|
||||
* Append the addresses for this host to the address list.
|
||||
*/
|
||||
switch (dns_lookup_v(host, RES_DEFNAMES, &addr, (VSTRING *) 0, why->reason,
|
||||
DNS_REQ_FLAG_ALL, proto_info->dns_atype_list)) {
|
||||
DNS_REQ_FLAG_NONE, proto_info->dns_atype_list)) {
|
||||
case DNS_OK:
|
||||
for (rr = addr; rr; rr = rr->next)
|
||||
rr->pref = pref;
|
||||
@ -207,6 +207,7 @@ static DNS_RR *lmtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref,
|
||||
"5.4.3", 550, "550 Name server failure");
|
||||
lmtp_errno = LMTP_FAIL;
|
||||
break;
|
||||
case DNS_INVAL:
|
||||
case DNS_NOTFOUND:
|
||||
lmtp_dsn_formal(why, DSN_BY_LOCAL_MTA,
|
||||
"5.4.4", 550, "550 Host not found");
|
||||
|
@ -162,7 +162,7 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref,
|
||||
*/
|
||||
if (smtp_host_lookup_mask & SMTP_HOST_FLAG_DNS) {
|
||||
switch (dns_lookup_v(host, RES_DEFNAMES, &addr, (VSTRING *) 0,
|
||||
why->reason, DNS_REQ_FLAG_ALL,
|
||||
why->reason, DNS_REQ_FLAG_NONE,
|
||||
proto_info->dns_atype_list)) {
|
||||
case DNS_OK:
|
||||
for (rr = addr; rr; rr = rr->next)
|
||||
@ -180,6 +180,7 @@ static DNS_RR *smtp_addr_one(DNS_RR *addr_list, char *host, unsigned pref,
|
||||
if (smtp_errno != SMTP_ERR_RETRY)
|
||||
smtp_errno = SMTP_ERR_FAIL;
|
||||
return (addr_list);
|
||||
case DNS_INVAL:
|
||||
case DNS_NOTFOUND:
|
||||
smtp_dsn_formal(why, DSN_BY_LOCAL_MTA,
|
||||
"5.4.4", 550, "550 Host not found");
|
||||
@ -474,6 +475,11 @@ DNS_RR *smtp_domain_addr(char *name, int misc_flags, DSN_BUF *why,
|
||||
addr_list = dns_rr_sort(addr_list, smtp_compare_pref);
|
||||
}
|
||||
break;
|
||||
case DNS_INVAL:
|
||||
smtp_dsn_formal(why, DSN_BY_LOCAL_MTA,
|
||||
"5.4.4", 550, "550 Host not found");
|
||||
smtp_errno = SMTP_ERR_FAIL;
|
||||
break;
|
||||
case DNS_NOTFOUND:
|
||||
addr_list = smtp_host_addr(name, misc_flags, why);
|
||||
break;
|
||||
|
@ -86,7 +86,7 @@ const char *smtp_unalias_name(const char *name)
|
||||
if ((result = htable_find(cache, name)) == 0) {
|
||||
fqdn = vstring_alloc(10);
|
||||
if (dns_lookup_l(name, smtp_unalias_flags, (DNS_RR **) 0, fqdn,
|
||||
(VSTRING *) 0, DNS_REQ_FLAG_ANY, T_MX, T_A,
|
||||
(VSTRING *) 0, DNS_REQ_FLAG_NONE, T_MX, T_A,
|
||||
#ifdef HAS_IPV6
|
||||
T_AAAA,
|
||||
#endif
|
||||
|
@ -966,7 +966,7 @@ static int reject_unknown_client(SMTPD_STATE *state)
|
||||
|
||||
if (state->name_status != SMTPD_PEER_CODE_OK)
|
||||
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
state->name_status == SMTPD_PEER_CODE_PERM ?
|
||||
state->name_status == SMTPD_PEER_CODE_PERM ?
|
||||
var_unk_client_code : 450, "4.7.1",
|
||||
"Client host rejected: cannot find your hostname, [%s]",
|
||||
state->addr));
|
||||
@ -1155,18 +1155,20 @@ static int reject_unknown_hostname(SMTPD_STATE *state, char *name,
|
||||
#endif
|
||||
|
||||
dns_status = dns_lookup_l(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
|
||||
(VSTRING *) 0, DNS_REQ_FLAG_ANY,
|
||||
(VSTRING *) 0, DNS_REQ_FLAG_STOP_OK,
|
||||
RR_ADDR_TYPES, T_MX, 0);
|
||||
if (dns_status == DNS_NOTFOUND)
|
||||
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
var_unk_name_code, "4.7.1",
|
||||
"<%s>: %s rejected: Host not found",
|
||||
reply_name, reply_class));
|
||||
else if (dns_status != DNS_OK)
|
||||
DEFER_IF_PERMIT2(state, MAIL_ERROR_POLICY,
|
||||
450, "4.7.1",
|
||||
"<%s>: %s rejected: Host not found",
|
||||
reply_name, reply_class);
|
||||
if (dns_status != DNS_OK) { /* incl. DNS_INVAL */
|
||||
if (dns_status != DNS_RETRY)
|
||||
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
var_unk_name_code, "4.7.1",
|
||||
"<%s>: %s rejected: Host not found",
|
||||
reply_name, reply_class));
|
||||
else
|
||||
DEFER_IF_PERMIT2(state, MAIL_ERROR_POLICY,
|
||||
450, "4.7.1",
|
||||
"<%s>: %s rejected: Host not found",
|
||||
reply_name, reply_class);
|
||||
}
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
@ -1181,22 +1183,26 @@ static int reject_unknown_mailhost(SMTPD_STATE *state, const char *name,
|
||||
if (msg_verbose)
|
||||
msg_info("%s: %s", myname, name);
|
||||
|
||||
#define MAILHOST_LOOKUP_FLAGS (DNS_REQ_FLAG_STOP_OK | DNS_REQ_FLAG_STOP_INVAL)
|
||||
|
||||
dns_status = dns_lookup_l(name, 0, (DNS_RR **) 0, (VSTRING *) 0,
|
||||
(VSTRING *) 0, DNS_REQ_FLAG_ANY,
|
||||
RR_ADDR_TYPES, T_MX, 0);
|
||||
if (dns_status == DNS_NOTFOUND)
|
||||
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
var_unk_addr_code,
|
||||
(VSTRING *) 0, MAILHOST_LOOKUP_FLAGS,
|
||||
T_MX, RR_ADDR_TYPES, 0);
|
||||
if (dns_status != DNS_OK) { /* incl. DNS_INVAL */
|
||||
if (dns_status != DNS_RETRY)
|
||||
return (smtpd_check_reject(state, MAIL_ERROR_POLICY,
|
||||
var_unk_addr_code,
|
||||
strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
|
||||
"4.1.8" : "4.1.2",
|
||||
"<%s>: %s rejected: Domain not found",
|
||||
reply_name, reply_class));
|
||||
else if (dns_status != DNS_OK)
|
||||
DEFER_IF_PERMIT2(state, MAIL_ERROR_POLICY,
|
||||
450, strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
|
||||
"4.1.8" : "4.1.2",
|
||||
"<%s>: %s rejected: Domain not found",
|
||||
reply_name, reply_class);
|
||||
"4.1.8" : "4.1.2",
|
||||
"<%s>: %s rejected: Domain not found",
|
||||
reply_name, reply_class));
|
||||
else
|
||||
DEFER_IF_PERMIT2(state, MAIL_ERROR_POLICY,
|
||||
450, strcmp(reply_class, SMTPD_NAME_SENDER) == 0 ?
|
||||
"4.1.8" : "4.1.2",
|
||||
"<%s>: %s rejected: Domain not found",
|
||||
reply_name, reply_class);
|
||||
}
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
@ -1395,8 +1401,8 @@ static int all_auth_mx_addr(SMTPD_STATE *state, char *host,
|
||||
* Verify that all host addresses are within permit_mx_backup_networks.
|
||||
*/
|
||||
dns_status = dns_lookup_v(host, 0, &addr_list, (VSTRING *) 0, (VSTRING *) 0,
|
||||
DNS_REQ_FLAG_ALL, inet_proto_info()->dns_atype_list);
|
||||
if (dns_status != DNS_OK) {
|
||||
DNS_REQ_FLAG_NONE, inet_proto_info()->dns_atype_list);
|
||||
if (dns_status != DNS_OK) { /* incl. DNS_INVAL */
|
||||
DEFER_IF_REJECT3(state, MAIL_ERROR_POLICY,
|
||||
450, "4.4.4",
|
||||
"<%s>: %s rejected: Unable to look up host %s as mail exchanger",
|
||||
@ -1622,11 +1628,12 @@ static int permit_mx_backup(SMTPD_STATE *state, const char *recipient,
|
||||
if (dns_status == DNS_NOTFOUND)
|
||||
return (has_my_addr(state, domain, reply_name, reply_class) ?
|
||||
SMTPD_CHECK_OK : SMTPD_CHECK_DUNNO);
|
||||
if (dns_status != DNS_OK) {
|
||||
DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
|
||||
450, "4.4.4",
|
||||
"<%s>: %s rejected: Unable to look up mail exchanger information",
|
||||
reply_name, reply_class);
|
||||
if (dns_status != DNS_OK) { /* incl. DNS_INVAL */
|
||||
if (dns_status == DNS_RETRY)
|
||||
DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
|
||||
450, "4.4.4",
|
||||
"<%s>: %s rejected: Unable to look up mail exchanger information",
|
||||
reply_name, reply_class);
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
}
|
||||
|
||||
@ -1961,7 +1968,8 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
|
||||
*/
|
||||
if (STREQUAL(value, "HOLD", cmd_len)) {
|
||||
#ifndef TEST
|
||||
if (can_delegate_action(state, table, "HOLD", reply_class) == 0)
|
||||
if (can_delegate_action(state, table, "HOLD", reply_class) == 0
|
||||
|| (state->saved_flags & CLEANUP_FLAG_HOLD))
|
||||
return (SMTPD_CHECK_DUNNO);
|
||||
#endif
|
||||
vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class,
|
||||
@ -3502,7 +3510,7 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
|
||||
forbid_whitelist(state, name, status, state->helo_name);
|
||||
}
|
||||
} else if (strcasecmp(name, REJECT_NON_FQDN_HELO_HOSTNAME) == 0
|
||||
||strcasecmp(name, REJECT_NON_FQDN_HOSTNAME) == 0) {
|
||||
|| strcasecmp(name, REJECT_NON_FQDN_HOSTNAME) == 0) {
|
||||
if (state->helo_name) {
|
||||
if (*state->helo_name != '[')
|
||||
status = reject_non_fqdn_hostname(state, state->helo_name,
|
||||
|
Loading…
x
Reference in New Issue
Block a user