summaryrefslogtreecommitdiff
path: root/gnu/dist/postfix/src
diff options
context:
space:
mode:
authorheas <heas@NetBSD.org>2004-03-27 16:31:19 +0000
committerheas <heas@NetBSD.org>2004-03-27 16:31:19 +0000
commitf32166d8a91a2c82316a00a40ee4842e27ec245d (patch)
tree23fa8e0342da03f7dc80d4e582d0351d2a2f3724 /gnu/dist/postfix/src
parent5f1ffa71fcd47bffcc5eb3f23221d6570b558e8f (diff)
merge from 2.0.19 import
Diffstat (limited to 'gnu/dist/postfix/src')
-rw-r--r--gnu/dist/postfix/src/cleanup/cleanup.c4
-rw-r--r--gnu/dist/postfix/src/cleanup/cleanup_envelope.c8
-rw-r--r--gnu/dist/postfix/src/dns/dns_lookup.c2
-rw-r--r--gnu/dist/postfix/src/global/Makefile.in1
-rw-r--r--gnu/dist/postfix/src/global/tok822_parse.c4
-rw-r--r--gnu/dist/postfix/src/master/master_ent.c28
-rw-r--r--gnu/dist/postfix/src/qmgr/qmgr_message.c5
-rw-r--r--gnu/dist/postfix/src/smtp/smtp_connect.c5
-rw-r--r--gnu/dist/postfix/src/smtpd/smtpd.c49
-rw-r--r--gnu/dist/postfix/src/smtpd/smtpd_check.c112
-rw-r--r--gnu/dist/postfix/src/util/Makefile.in19
-rw-r--r--gnu/dist/postfix/src/util/inet_connect.c3
-rw-r--r--gnu/dist/postfix/src/util/inet_listen.c5
-rw-r--r--gnu/dist/postfix/src/util/match_ops.c14
-rw-r--r--gnu/dist/postfix/src/util/sys_defs.h5
15 files changed, 185 insertions, 79 deletions
diff --git a/gnu/dist/postfix/src/cleanup/cleanup.c b/gnu/dist/postfix/src/cleanup/cleanup.c
index f6cbd8d9115..2a73ea97bd7 100644
--- a/gnu/dist/postfix/src/cleanup/cleanup.c
+++ b/gnu/dist/postfix/src/cleanup/cleanup.c
@@ -107,7 +107,7 @@
/* request contains valid 8-bit MIME mail, and it breaks bounces from
/* mailers that do not properly encapsulate 8-bit content (for example,
/* bounces from qmail or from old versions of Postfix).
-/* .IP \fBstrict_mime_domain_encoding\fR
+/* .IP \fBstrict_mime_encoding_domain\fR
/* Reject mail with invalid \fBContent-Transfer-Encoding:\fR
/* information for message/* or multipart/*. This blocks mail
/* from poorly written software.
@@ -159,7 +159,7 @@
/* .IP \fBheader_address_token_limit\fR
/* Limits the number of address tokens used to process a message header.
/* .IP \fBheader_size_limit\fR
-/* Limits the amount of memory in bytes used to process a message header.
+/* Limits the amount of memory in bytes used to store a message header.
/* .IP \fBin_flow_delay\fR
/* Amount of time to pause before accepting a message, when the
/* message arrival rate exceeds the message delivery rate.
diff --git a/gnu/dist/postfix/src/cleanup/cleanup_envelope.c b/gnu/dist/postfix/src/cleanup/cleanup_envelope.c
index 3ef96b0e8e7..5be545bb5ac 100644
--- a/gnu/dist/postfix/src/cleanup/cleanup_envelope.c
+++ b/gnu/dist/postfix/src/cleanup/cleanup_envelope.c
@@ -153,10 +153,12 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf,
}
}
if (type == REC_TYPE_TIME) {
- state->time = atol(buf);
+ if (state->time == 0)
+ state->time = atol(buf);
cleanup_out(state, type, buf, len);
} else if (type == REC_TYPE_FULL) {
- state->fullname = mystrdup(buf);
+ if (state->fullname == 0)
+ state->fullname = mystrdup(buf);
} else if (type == REC_TYPE_FROM) {
VSTRING *clean_addr = vstring_alloc(100);
@@ -211,6 +213,8 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type, char *buf,
vstring_free(clean_addr);
myfree(state->orig_rcpt);
state->orig_rcpt = 0;
+ } else if (type == REC_TYPE_DONE) {
+ /* void */ ;
} else if (type == REC_TYPE_WARN) {
if ((state->warn_time = atol(buf)) < 0) {
state->errs |= CLEANUP_STAT_BAD;
diff --git a/gnu/dist/postfix/src/dns/dns_lookup.c b/gnu/dist/postfix/src/dns/dns_lookup.c
index 4ff4fe2bd50..81a1dda734b 100644
--- a/gnu/dist/postfix/src/dns/dns_lookup.c
+++ b/gnu/dist/postfix/src/dns/dns_lookup.c
@@ -141,6 +141,7 @@ static int dns_query(const char *name, int type, int flags,
{
HEADER *reply_header;
int len;
+ unsigned long saved_options = _res.options;
/*
* Initialize the name service.
@@ -167,6 +168,7 @@ static int dns_query(const char *name, int type, int flags,
* only if the name server told us so.
*/
len = res_search((char *) name, C_IN, type, reply->buf, sizeof(reply->buf));
+ _res.options = saved_options;
if (len < 0) {
if (why)
vstring_sprintf(why, "Name service error for name=%s type=%s: %s",
diff --git a/gnu/dist/postfix/src/global/Makefile.in b/gnu/dist/postfix/src/global/Makefile.in
index a981d06f978..8f48d059fd8 100644
--- a/gnu/dist/postfix/src/global/Makefile.in
+++ b/gnu/dist/postfix/src/global/Makefile.in
@@ -1210,6 +1210,7 @@ tok822_parse.o: ../../include/sys_defs.h
tok822_parse.o: ../../include/vstring.h
tok822_parse.o: ../../include/vbuf.h
tok822_parse.o: ../../include/msg.h
+tok822_parse.o: ../../include/stringops.h
tok822_parse.o: lex_822.h
tok822_parse.o: quote_822_local.h
tok822_parse.o: quote_flags.h
diff --git a/gnu/dist/postfix/src/global/tok822_parse.c b/gnu/dist/postfix/src/global/tok822_parse.c
index fe554bf7ae2..4866ac5ad3d 100644
--- a/gnu/dist/postfix/src/global/tok822_parse.c
+++ b/gnu/dist/postfix/src/global/tok822_parse.c
@@ -126,6 +126,7 @@
#include <vstring.h>
#include <msg.h>
+#include <stringops.h>
/* Global library. */
@@ -250,7 +251,7 @@ static void strip_address(VSTRING *vp, int start, TOK822 *addr)
* Emit plain <address>. Discard any comments or phrases.
*/
msg_warn("stripping too many comments from address: %.100s...",
- vstring_str(vp) + start);
+ printable(vstring_str(vp) + start, '?'));
vstring_truncate(vp, start);
VSTRING_ADDCH(vp, '<');
if (addr) {
@@ -263,7 +264,6 @@ static void strip_address(VSTRING *vp, int start, TOK822 *addr)
VSTRING_ADDCH(vp, '>');
}
-
/* tok822_externalize - token tree to string, external form */
VSTRING *tok822_externalize(VSTRING *vp, TOK822 *tree, int flags)
diff --git a/gnu/dist/postfix/src/master/master_ent.c b/gnu/dist/postfix/src/master/master_ent.c
index cccaa8ea156..8c22bb91c95 100644
--- a/gnu/dist/postfix/src/master/master_ent.c
+++ b/gnu/dist/postfix/src/master/master_ent.c
@@ -234,11 +234,27 @@ MASTER_SERV *get_master_ent()
int n;
char *bufp;
char *atmp;
+ static char *saved_interfaces = 0;
if (master_fp == 0)
msg_panic("get_master_ent: config file not open");
/*
+ * XXX We cannot change the inet_interfaces setting for a running master
+ * process. Listening sockets are inherited by child processes so that
+ * closing and reopening those sockets in the master does not work.
+ *
+ * Another problem is that library routines still cache results that are
+ * based on the old inet_interfaces setting. It is too much trouble to
+ * recompute everything.
+ *
+ * In order to keep our data structures consistent we ignore changes in
+ * inet_interfaces settings, and issue a warning instead.
+ */
+ if (saved_interfaces == 0)
+ saved_interfaces = mystrdup(var_inet_interfaces);
+
+ /*
* Skip blank lines and comment lines.
*/
do {
@@ -274,6 +290,12 @@ MASTER_SERV *get_master_ent()
transport = get_str_ent(&bufp, "transport type", (char *) 0);
if (STR_SAME(transport, MASTER_XPORT_NAME_INET)) {
+ if (!STR_SAME(saved_interfaces, var_inet_interfaces)) {
+ msg_warn("service %s: ignoring %s change",
+ name, VAR_INET_INTERFACES);
+ msg_warn("to change %s, stop and start Postfix",
+ VAR_INET_INTERFACES);
+ }
serv->type = MASTER_SERV_TYPE_INET;
atmp = inet_parse(name, &host, &port);
if (*host) {
@@ -281,10 +303,12 @@ MASTER_SERV *get_master_ent()
MASTER_INET_ADDRLIST(serv) = (INET_ADDR_LIST *)
mymalloc(sizeof(*MASTER_INET_ADDRLIST(serv)));
inet_addr_list_init(MASTER_INET_ADDRLIST(serv));
- inet_addr_host(MASTER_INET_ADDRLIST(serv), host);
+ if (inet_addr_host(MASTER_INET_ADDRLIST(serv), host) == 0)
+ msg_fatal("%s: line %d: bad hostname or network address: %s",
+ VSTREAM_PATH(master_fp), master_line, host);
inet_addr_list_uniq(MASTER_INET_ADDRLIST(serv));
serv->listen_fd_count = MASTER_INET_ADDRLIST(serv)->used;
- } else if (strcasecmp(var_inet_interfaces, DEF_INET_INTERFACES) == 0) {
+ } else if (strcasecmp(saved_interfaces, DEF_INET_INTERFACES) == 0) {
MASTER_INET_ADDRLIST(serv) = 0; /* wild-card */
serv->listen_fd_count = 1;
} else {
diff --git a/gnu/dist/postfix/src/qmgr/qmgr_message.c b/gnu/dist/postfix/src/qmgr/qmgr_message.c
index 233477cd850..9afac7ff9c2 100644
--- a/gnu/dist/postfix/src/qmgr/qmgr_message.c
+++ b/gnu/dist/postfix/src/qmgr/qmgr_message.c
@@ -273,6 +273,7 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
"queue %s", message->queue_name);
}
} else if (rec_type == REC_TYPE_RCPT) {
+ /* See also below for code setting orig_rcpt. */
#define FUDGE(x) ((x) * (var_qmgr_fudge / 100.0))
if (message->rcpt_list.len < FUDGE(var_qmgr_rcpt_limit)) {
qmgr_rcpt_list_add(&message->rcpt_list, curr_offset,
@@ -347,7 +348,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
orig_rcpt = 0;
}
if (rec_type == REC_TYPE_ORCP)
- orig_rcpt = mystrdup(start);
+ /* See also above for code clearing orig_rcpt. */
+ if (message->rcpt_offset == 0)
+ orig_rcpt = mystrdup(start);
} while (rec_type > 0 && rec_type != REC_TYPE_END);
/*
diff --git a/gnu/dist/postfix/src/smtp/smtp_connect.c b/gnu/dist/postfix/src/smtp/smtp_connect.c
index 173ec7461de..2fe78eec1a1 100644
--- a/gnu/dist/postfix/src/smtp/smtp_connect.c
+++ b/gnu/dist/postfix/src/smtp/smtp_connect.c
@@ -112,6 +112,7 @@
#include <timed_connect.h>
#include <stringops.h>
#include <host_port.h>
+#include <sane_connect.h>
/* Global library. */
@@ -208,7 +209,7 @@ static SMTP_SESSION *smtp_connect_addr(DNS_RR *addr, unsigned port,
non_blocking(sock, BLOCKING);
errno = saved_errno;
} else {
- conn_stat = connect(sock, (struct sockaddr *) & sin, sizeof(sin));
+ conn_stat = sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin));
}
if (conn_stat < 0) {
vstring_sprintf(why, "connect to %s[%s]: %m",
@@ -345,7 +346,7 @@ static char *smtp_parse_destination(char *destination, char *def_service,
/*
* Convert service to port number, network byte order.
*/
- if ((port = atoi(service)) != 0) {
+ if (alldig(service) && (port = atoi(service)) != 0) {
*portp = htons(port);
} else {
if ((sp = getservbyname(service, protocol)) == 0)
diff --git a/gnu/dist/postfix/src/smtpd/smtpd.c b/gnu/dist/postfix/src/smtpd/smtpd.c
index 185ddd22777..4fd11947101 100644
--- a/gnu/dist/postfix/src/smtpd/smtpd.c
+++ b/gnu/dist/postfix/src/smtpd/smtpd.c
@@ -59,7 +59,7 @@
/* Disallow non-RFC 821 style addresses in SMTP commands. For example,
/* the RFC822-style address forms with comments that Sendmail allows.
/* .IP \fBbroken_sasl_auth_clients\fR
-/* Support older Microsoft clients that mis-implement the AUTH
+/* Support Microsoft clients that implement an older version of the AUTH
/* protocol, and that expect an EHLO response of "250 AUTH=list"
/* instead of "250 AUTH list".
/* .IP \fBsmtpd_noop_commands\fR
@@ -73,7 +73,7 @@
/* This parameter uses the same syntax as the right-hand side of
/* a Postfix transport table.
/* .SH "Authentication controls"
-/* .IP \fBenable_sasl_authentication\fR
+/* .IP \fBsmtpd_sasl_auth_enable\fR
/* Enable per-session authentication as per RFC 2554 (SASL).
/* This functionality is available only when explicitly selected
/* at program build time and explicitly enabled at runtime.
@@ -629,7 +629,9 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
int naddr;
int non_addr;
char *err = 0;
- char *junk;
+ char *junk = 0;
+ char *text;
+ char *colon;
/*
* Special case.
@@ -653,11 +655,19 @@ static char *extract_addr(SMTPD_STATE *state, SMTPD_TOKEN *arg,
msg_info("%s: input: %s", myname, STR(arg->vstrval));
if (STR(arg->vstrval)[0] == '<'
&& STR(arg->vstrval)[LEN(arg->vstrval) - 1] == '>') {
- junk = mystrndup(STR(arg->vstrval) + 1, LEN(arg->vstrval) - 2);
- tree = tok822_parse(junk);
- myfree(junk);
+ junk = text = mystrndup(STR(arg->vstrval) + 1, LEN(arg->vstrval) - 2);
} else
- tree = tok822_parse(STR(arg->vstrval));
+ text = STR(arg->vstrval);
+
+ /*
+ * Truncate deprecated route address form.
+ */
+ if (*text == '@' && (colon = strchr(text, ':')) != 0)
+ text = colon + 1;
+ tree = tok822_parse(text);
+
+ if (junk)
+ myfree(junk);
/*
* Find trouble.
@@ -796,7 +806,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
verp_delims = arg + VERP_CMD_LEN + 1;
if (verp_delims_verify(verp_delims) != 0) {
state->error_mask |= MAIL_ERROR_PROTOCOL;
- smtpd_chat_reply(state, "501 %s needs two characters from %s",
+ smtpd_chat_reply(state, "501 Error: %s needs two characters from %s",
VERP_CMD, var_verp_filter);
return (-1);
}
@@ -808,7 +818,8 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
}
}
if (verp_delims && argv[2].strval[0] == 0) {
- smtpd_chat_reply(state, "503 Error: XVERP requires non-null sender");
+ smtpd_chat_reply(state, "503 Error: %s requires non-null sender",
+ VERP_CMD);
return (-1);
}
state->time = time((time_t *) 0);
@@ -837,10 +848,12 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
/*
* Record the time of arrival and the sender envelope address.
*/
- rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld",
- (long) time((time_t *) 0));
- if (*var_filter_xport)
- rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
+ if (SMTPD_STAND_ALONE(state) == 0) {
+ rec_fprintf(state->cleanup, REC_TYPE_TIME, "%ld",
+ (long) time((time_t *) 0));
+ if (*var_filter_xport)
+ rec_fprintf(state->cleanup, REC_TYPE_FILT, "%s", var_filter_xport);
+ }
rec_fputs(state->cleanup, REC_TYPE_FROM, argv[2].strval);
if (encoding != 0)
rec_fprintf(state->cleanup, REC_TYPE_ATTR, "%s=%s",
@@ -893,6 +906,7 @@ static void mail_reset(SMTPD_STATE *state)
if (var_smtpd_sasl_enable)
smtpd_sasl_mail_reset(state);
#endif
+ state->discard = 0;
}
/* rcpt_cmd - process RCPT TO command */
@@ -951,10 +965,6 @@ static int rcpt_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
smtpd_chat_reply(state, "%s", err);
return (-1);
}
- if ((err = smtpd_check_rcptmap(state, argv[2].strval)) != 0) {
- smtpd_chat_reply(state, "%s", err);
- return (-1);
- }
}
/*
@@ -1259,7 +1269,7 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
return (-1);
}
if (SMTPD_STAND_ALONE(state) == 0
- && (err = smtpd_check_rcptmap(state, argv[1].strval)) != 0) {
+ && (err = smtpd_check_rcpt(state, argv[1].strval)) != 0) {
smtpd_chat_reply(state, "%s", err);
return (-1);
}
@@ -1463,7 +1473,8 @@ static void smtpd_proto(SMTPD_STATE *state)
break;
case 0:
- if (var_smtpd_delay_reject == 0
+ if (SMTPD_STAND_ALONE(state) == 0
+ && var_smtpd_delay_reject == 0
&& (state->access_denied = smtpd_check_client(state)) != 0) {
smtpd_chat_reply(state, "%s", state->access_denied);
} else {
diff --git a/gnu/dist/postfix/src/smtpd/smtpd_check.c b/gnu/dist/postfix/src/smtpd/smtpd_check.c
index 678a86f0b04..755e551a7ae 100644
--- a/gnu/dist/postfix/src/smtpd/smtpd_check.c
+++ b/gnu/dist/postfix/src/smtpd/smtpd_check.c
@@ -24,10 +24,6 @@
/* SMTPD_STATE *state;
/* char *recipient;
/*
-/* char *smtpd_check_rcptmap(state, recipient)
-/* SMTPD_STATE *state;
-/* char *recipient;
-/*
/* char *smtpd_check_etrn(state, destination)
/* SMTPD_STATE *state;
/* char *destination;
@@ -192,11 +188,7 @@
/* .IP smtpd_recipient_restrictions
/* Restrictions on the recipient address that is sent with the RCPT
/* TO command.
-/* .PP
-/* smtpd_check_rcptmap() validates the recipient address provided
-/* with an RCPT TO request and sets the rcptmap_checked flag.
-/* Relevant configuration parameters:
-/* .IP local_recipients_map
+/* .IP local_recipient_maps
/* Tables of user names (not addresses) that exist in $mydestination.
/* Mail for local users not in these tables is rejected.
/* .PP
@@ -795,6 +787,13 @@ static int smtpd_check_reject(SMTPD_STATE *state, int error_class,
va_end(ap);
/*
+ * Ensure RFC compliance. We could do this inside smtpd_chat_reply() and
+ * switch to multi-line for long replies.
+ */
+ vstring_truncate(error_text, 510);
+ VSTRING_TERMINATE(error_text);
+
+ /*
* Validate the response, that is, the response must begin with a
* three-digit status code, and the first digit must be 4 or 5. If the
* response is bad, log a warning and send a generic response instead.
@@ -1622,6 +1621,31 @@ static int reject_unknown_address(SMTPD_STATE *state, const char *addr,
return (reject_unknown_mailhost(state, domain, reply_name, reply_class));
}
+/* warn_skip_access_action - FILTER etc. action in unsupported context */
+
+static void warn_skip_access_action(const char *table, const char *action,
+ const char *reply_class)
+{
+
+ /*
+ * Warn only about FILTER/HOLD/etc. access table actions that appear in
+ * restrictions where they will always be ignored.
+ */
+ if (strcmp(reply_class, SMTPD_NAME_CLIENT) == 0
+ || strcmp(reply_class, SMTPD_NAME_HELO) == 0
+ || strcmp(reply_class, SMTPD_NAME_SENDER) == 0) {
+ if (var_smtpd_delay_reject == 0)
+ msg_warn("access table %s: with %s=%s, "
+ "action %s is always skipped in %s restrictions",
+ table, VAR_SMTPD_DELAY_REJECT, CONFIG_BOOL_NO,
+ action, reply_class);
+ } else {
+ msg_warn("access table %s: action %s is always "
+ "skipped in %s restrictions",
+ table, action, reply_class);
+ }
+}
+
/* check_table_result - translate table lookup result into pass/reject */
static int check_table_result(SMTPD_STATE *state, const char *table,
@@ -1673,6 +1697,12 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
* mind, and reject/discard the message for other reasons.
*/
if (STREQUAL(value, "FILTER", cmd_len)) {
+#ifndef TEST
+ if (state->dest == 0) {
+ warn_skip_access_action(table, "FILTER", reply_class);
+ return (SMTPD_CHECK_DUNNO);
+ }
+#endif
if (*cmd_text == 0) {
msg_warn("access map %s entry \"%s\" has FILTER entry without value",
table, datum);
@@ -1697,6 +1727,12 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
* reject/discard the message for other reasons.
*/
if (STREQUAL(value, "HOLD", cmd_len)) {
+#ifndef TEST
+ if (state->dest == 0) {
+ warn_skip_access_action(table, "HOLD", reply_class);
+ return (SMTPD_CHECK_DUNNO);
+ }
+#endif
vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class,
*cmd_text ? cmd_text : "triggers HOLD action");
log_whatsup(state, "hold", STR(error_text));
@@ -1709,17 +1745,21 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
/*
* DISCARD means silently discard and claim successful delivery.
- *
- * XXX Set some global flag that disables all further restrictions.
- * Triggering a "reject" or "hold" action after "discard" is silly.
*/
if (STREQUAL(value, "DISCARD", cmd_len)) {
+#ifndef TEST
+ if (state->dest == 0) {
+ warn_skip_access_action(table, "DISCARD", reply_class);
+ return (SMTPD_CHECK_DUNNO);
+ }
+#endif
vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class,
*cmd_text ? cmd_text : "triggers DISCARD action");
log_whatsup(state, "discard", STR(error_text));
#ifndef TEST
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
CLEANUP_FLAG_DISCARD);
+ state->discard = 1;
#endif
return (SMTPD_CHECK_OK);
}
@@ -2548,6 +2588,9 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
for (cpp = restrictions->argv; (name = *cpp) != 0; cpp++) {
+ if (state->discard != 0)
+ break;
+
if (msg_verbose)
msg_info("%s: name=%s", myname, name);
@@ -2998,10 +3041,7 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
/*
* The "check_recipient_maps" restriction is relevant only when
- * responding to RCPT TO. It's effectively disabled with DATA (recipient
- * context is explicitly turned off) and not applicable with undelayed
- * client/helo/sender restrictions (no recipient info) or with ETRN
- * (command not allowed in the middle of an ongoing MAIL transaction).
+ * responding to RCPT TO or VRFY.
*/
state->rcptmap_checked = 0;
@@ -3027,7 +3067,7 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
SMTPD_CHECK_RESET();
status = setjmp(smtpd_check_buf);
if (status == 0 && rcpt_restrctions->argc)
- status = generic_checks(state, rcpt_restrctions,
+ status = generic_checks(state, rcpt_restrctions,
recipient, SMTPD_NAME_RECIPIENT, CHECK_RECIP_ACL);
/*
@@ -3038,6 +3078,14 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient)
status = smtpd_check_reject(state, state->defer_if_permit.class,
"%s", STR(state->defer_if_permit.reason));
+ /*
+ * If the "check_recipient_maps" restriction was not applied, and if mail
+ * is not being rejected or discarded, validate the recipient here.
+ */
+ if (status != SMTPD_CHECK_REJECT && state->rcptmap_checked == 0
+ && state->discard == 0)
+ status = check_rcpt_maps(state, recipient);
+
SMTPD_CHECK_RCPT_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
}
@@ -3102,25 +3150,6 @@ char *smtpd_check_etrn(SMTPD_STATE *state, char *domain)
SMTPD_CHECK_ETRN_RETURN(status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
}
-/* smtpd_check_rcptmap - permit if recipient address matches lookup table */
-
-char *smtpd_check_rcptmap(SMTPD_STATE *state, char *recipient)
-{
- char *myname = "smtpd_check_rcptmap";
- int status;
-
- if (msg_verbose)
- msg_info("%s: %s", myname, recipient);
-
- /*
- * Return here in case of serious trouble.
- */
- if ((status = setjmp(smtpd_check_buf)) == 0)
- status = check_rcpt_maps(state, recipient);
-
- return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0);
-}
-
/* check_rcpt_maps - generic_checks() interface for recipient table check */
static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient)
@@ -3198,13 +3227,13 @@ static int check_rcpt_maps(SMTPD_STATE *state, const char *recipient)
if ((reply->flags & RESOLVE_CLASS_LOCAL)
&& *var_local_rcpt_maps
- /* Generated by bounce, absorbed by qmgr. */
+ /* Generated by bounce, absorbed by qmgr. */
&& !MATCH_LEFT(var_double_bounce_sender, CONST_STR(reply->recipient),
strlen(var_double_bounce_sender))
- /* Absorbed by qmgr. */
+ /* Absorbed by qmgr. */
&& !MATCH_LEFT(MAIL_ADDR_POSTMASTER, CONST_STR(reply->recipient),
strlen(MAIL_ADDR_POSTMASTER))
- /* Generated by bounce. */
+ /* Generated by bounce. */
&& !MATCH_LEFT(MAIL_ADDR_MAIL_DAEMON, CONST_STR(reply->recipient),
strlen(MAIL_ADDR_MAIL_DAEMON))
&& NOMATCH(local_rcpt_maps, CONST_STR(reply->recipient)))
@@ -3486,6 +3515,7 @@ int var_local_rcpt_code;
int var_relay_rcpt_code;
int var_virt_mailbox_code;
int var_virt_alias_code;
+int var_show_unk_rcpt_table;
static INT_TABLE int_table[] = {
"msg_verbose", 0, &msg_verbose,
@@ -3505,6 +3535,7 @@ static INT_TABLE int_table[] = {
VAR_RELAY_RCPT_CODE, DEF_RELAY_RCPT_CODE, &var_relay_rcpt_code,
VAR_VIRT_ALIAS_CODE, DEF_VIRT_ALIAS_CODE, &var_virt_alias_code,
VAR_VIRT_MAILBOX_CODE, DEF_VIRT_MAILBOX_CODE, &var_virt_mailbox_code,
+ VAR_SHOW_UNK_RCPT_TABLE, DEF_SHOW_UNK_RCPT_TABLE, &var_show_unk_rcpt_table,
0,
};
@@ -3883,8 +3914,7 @@ int main(int argc, char **argv)
} else if (strcasecmp(args->argv[0], "rcpt") == 0) {
state.where = "RCPT";
TRIM_ADDR(args->argv[1], addr);
- (resp = smtpd_check_rcpt(&state, addr))
- || (resp = smtpd_check_rcptmap(&state, addr));
+ resp = smtpd_check_rcpt(&state, addr);
}
break;
diff --git a/gnu/dist/postfix/src/util/Makefile.in b/gnu/dist/postfix/src/util/Makefile.in
index 4167dfff018..d1d841bb545 100644
--- a/gnu/dist/postfix/src/util/Makefile.in
+++ b/gnu/dist/postfix/src/util/Makefile.in
@@ -26,7 +26,7 @@ SRCS = alldig.c argv.c argv_split.c attr_print0.c attr_print64.c \
unix_connect.c unix_listen.c unix_trigger.c unsafe.c username.c \
valid_hostname.c vbuf.c vbuf_print.c vstream.c vstream_popen.c \
vstring.c vstring_vstream.c watchdog.c writable.c write_buf.c \
- write_wait.c strcasecmp.c nvtable.c host_port.c
+ write_wait.c strcasecmp.c nvtable.c host_port.c sane_connect.c
OBJS = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
attr_scan0.o attr_scan64.o base64_code.o basename.o binhash.o \
chroot_uid.o clean_env.o close_on_exec.o concatenate.o ctable.o \
@@ -54,7 +54,7 @@ OBJS = alldig.o argv.o argv_split.o attr_print0.o attr_print64.o \
unix_connect.o unix_listen.o unix_trigger.o unsafe.o username.o \
valid_hostname.o vbuf.o vbuf_print.o vstream.o vstream_popen.o \
vstring.o vstring_vstream.o watchdog.o writable.o write_buf.o \
- write_wait.o nvtable.o $(STRCASE) host_port.o
+ write_wait.o nvtable.o host_port.o sane_connect.o $(STRCASE)
HDRS = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
connect.h ctable.h dict.h dict_db.h dict_dbm.h dict_env.h \
dict_ht.h dict_ldap.h dict_mysql.h dict_ni.h dict_nis.h \
@@ -72,7 +72,7 @@ HDRS = argv.h attr.h base64_code.h binhash.h chroot_uid.h clean_env.h \
split_at.h stat_as.h stringops.h sys_defs.h timed_connect.h \
timed_wait.h trigger.h username.h valid_hostname.h vbuf.h \
vbuf_print.h vstream.h vstring.h vstring_vstream.h watchdog.h \
- nvtable.h host_port.h
+ nvtable.h host_port.h sane_connect.h
TESTSRC = fifo_open.c fifo_rdwr_bug.c fifo_rdonly_bug.c select_bug.c \
stream_test.c dup2_pass_on_exec.c
WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \
@@ -739,6 +739,9 @@ file_limit.o: iostuff.h
find_inet.o: find_inet.c
find_inet.o: sys_defs.h
find_inet.o: msg.h
+find_inet.o: stringops.h
+find_inet.o: vstring.h
+find_inet.o: vbuf.h
find_inet.o: find_inet.h
fsspace.o: fsspace.c
fsspace.o: sys_defs.h
@@ -805,6 +808,7 @@ inet_connect.o: msg.h
inet_connect.o: find_inet.h
inet_connect.o: inet_util.h
inet_connect.o: iostuff.h
+inet_connect.o: sane_connect.h
inet_connect.o: connect.h
inet_connect.o: timed_connect.h
inet_listen.o: inet_listen.c
@@ -916,6 +920,7 @@ msg_syslog.o: stringops.h
msg_syslog.o: msg.h
msg_syslog.o: msg_output.h
msg_syslog.o: msg_syslog.h
+msg_syslog.o: safe.h
msg_vstream.o: msg_vstream.c
msg_vstream.o: sys_defs.h
msg_vstream.o: vstream.h
@@ -1036,6 +1041,10 @@ sane_accept.o: sane_accept.c
sane_accept.o: sys_defs.h
sane_accept.o: msg.h
sane_accept.o: sane_accept.h
+sane_connect.o: sane_connect.c
+sane_connect.o: sys_defs.h
+sane_connect.o: msg.h
+sane_connect.o: sane_connect.h
sane_link.o: sane_link.c
sane_link.o: sys_defs.h
sane_link.o: msg.h
@@ -1143,9 +1152,11 @@ timed_connect.o: timed_connect.c
timed_connect.o: sys_defs.h
timed_connect.o: msg.h
timed_connect.o: iostuff.h
+timed_connect.o: sane_connect.h
timed_connect.o: timed_connect.h
timed_read.o: timed_read.c
timed_read.o: sys_defs.h
+timed_read.o: msg.h
timed_read.o: iostuff.h
timed_wait.o: timed_wait.c
timed_wait.o: sys_defs.h
@@ -1154,6 +1165,7 @@ timed_wait.o: posix_signals.h
timed_wait.o: timed_wait.h
timed_write.o: timed_write.c
timed_write.o: sys_defs.h
+timed_write.o: msg.h
timed_write.o: iostuff.h
translit.o: translit.c
translit.o: sys_defs.h
@@ -1174,6 +1186,7 @@ unix_connect.o: unix_connect.c
unix_connect.o: sys_defs.h
unix_connect.o: msg.h
unix_connect.o: iostuff.h
+unix_connect.o: sane_connect.h
unix_connect.o: connect.h
unix_connect.o: timed_connect.h
unix_listen.o: unix_listen.c
diff --git a/gnu/dist/postfix/src/util/inet_connect.c b/gnu/dist/postfix/src/util/inet_connect.c
index 152e498461e..3c76734cdda 100644
--- a/gnu/dist/postfix/src/util/inet_connect.c
+++ b/gnu/dist/postfix/src/util/inet_connect.c
@@ -63,6 +63,7 @@
#include "find_inet.h"
#include "inet_util.h"
#include "iostuff.h"
+#include "sane_connect.h"
#include "connect.h"
#include "timed_connect.h"
@@ -114,7 +115,7 @@ int inet_connect(const char *addr, int block_mode, int timeout)
*/
else {
non_blocking(sock, block_mode);
- if (connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0
+ if (sane_connect(sock, (struct sockaddr *) & sin, sizeof(sin)) < 0
&& errno != EINPROGRESS) {
close(sock);
return (-1);
diff --git a/gnu/dist/postfix/src/util/inet_listen.c b/gnu/dist/postfix/src/util/inet_listen.c
index 91347c95ab4..2a846b39b8d 100644
--- a/gnu/dist/postfix/src/util/inet_listen.c
+++ b/gnu/dist/postfix/src/util/inet_listen.c
@@ -116,5 +116,8 @@ int inet_listen(const char *addr, int backlog, int block_mode)
int inet_accept(int fd)
{
- return (sane_accept(fd, (struct sockaddr *) 0, (SOCKADDR_SIZE *) 0));
+ struct sockaddr_in sin;
+ SOCKADDR_SIZE len = sizeof(sin);
+
+ return (sane_accept(fd, (struct sockaddr *) & sin, &len));
}
diff --git a/gnu/dist/postfix/src/util/match_ops.c b/gnu/dist/postfix/src/util/match_ops.c
index 1bde84abdfa..ea615d7c557 100644
--- a/gnu/dist/postfix/src/util/match_ops.c
+++ b/gnu/dist/postfix/src/util/match_ops.c
@@ -69,7 +69,7 @@
#endif
#ifndef INADDR_NONE
-#define INADDR_NONE 0xffffff
+#define INADDR_NONE 0xffffffff
#endif
/* Utility library. */
@@ -139,7 +139,7 @@ int match_hostname(int flags, const char *name, const char *pattern)
if (strchr(pattern, ':') != 0) {
temp = lowercase(mystrdup(name));
match = 0;
- for (entry = temp; /* void */ ; entry = next) {
+ for (entry = temp; *entry != 0; entry = next) {
if ((match = (dict_lookup(pattern, entry) != 0)) != 0)
break;
if (dict_errno != 0)
@@ -207,6 +207,7 @@ int match_hostaddr(int unused_flags, const char *addr, const char *pattern)
unsigned long mask_bits;
unsigned long net_bits;
unsigned long addr_bits;
+ struct in_addr net_addr;
if (msg_verbose)
msg_info("%s: %s ~? %s", myname, addr, pattern);
@@ -242,7 +243,14 @@ int match_hostaddr(int unused_flags, const char *addr, const char *pattern)
if (addr_bits == INADDR_NONE)
msg_fatal("%s: bad address argument: %s", myname, addr);
mask_bits = htonl((0xffffffff) << (BITS_PER_ADDR - mask_shift));
- return ((addr_bits & mask_bits) == (net_bits & mask_bits));
+ if ((addr_bits & mask_bits) == net_bits)
+ return (1);
+ if (net_bits & ~mask_bits) {
+ net_addr.s_addr = (net_bits & mask_bits);
+ msg_fatal("net/mask pattern %s has a non-null host portion; "
+ "specify %s/%d if this is really what you want",
+ pattern, inet_ntoa(net_addr), mask_shift);
+ }
}
return (0);
}
diff --git a/gnu/dist/postfix/src/util/sys_defs.h b/gnu/dist/postfix/src/util/sys_defs.h
index d1735d9f8fa..1e3b4ee4250 100644
--- a/gnu/dist/postfix/src/util/sys_defs.h
+++ b/gnu/dist/postfix/src/util/sys_defs.h
@@ -98,7 +98,9 @@
#define NORETURN void
#define PRINTFLIKE(x,y)
#define SCANFLIKE(x,y)
+#ifndef NO_NETINFO
#define HAS_NETINFO
+#endif
#define NATIVE_SENDMAIL_PATH "/usr/sbin/sendmail"
#define NATIVE_MAILQ_PATH "/usr/bin/mailq"
#define NATIVE_NEWALIAS_PATH "/usr/bin/newaliases"
@@ -185,6 +187,7 @@ extern int opterr; /* XXX use <getopt.h> */
#define USE_STATFS
#define STATFS_IN_SYS_MOUNT_H
#define HAS_POSIX_REGEXP
+#define BROKEN_WRITE_SELECT_ON_NON_BLOCKING_PIPE
#endif
/*
@@ -260,6 +263,7 @@ extern int opterr;
#define LOCAL_CONNECT stream_connect
#define LOCAL_TRIGGER stream_trigger
#define HAS_VOLATILE_LOCKS
+#define BROKEN_READ_SELECT_ON_TCP_SOCKET
/*
* Allow build environment to override paths.
*/
@@ -463,6 +467,7 @@ extern int initgroups(const char *, int);
#define DBM_NO_TRAILING_NULL /* XXX check */
#define USE_STATVFS
#define STATVFS_IN_SYS_STATVFS_H
+#define BROKEN_WRITE_SELECT_ON_NON_BLOCKING_PIPE
#endif
#if defined(IRIX5)