mirror of
https://github.com/vdukhovni/postfix
synced 2025-08-30 13:48:06 +00:00
postfix-2.0.9-20030519
This commit is contained in:
committed by
Viktor Dukhovni
parent
cf574a300d
commit
eb8dcde50b
@@ -8047,6 +8047,43 @@ Apologies for any names omitted.
|
||||
Patrik Rak's clever queue manager scheduler (nqmgr). Files:
|
||||
conf/sample-scheduler.cf, README_FILES/SCHEDULER_README.
|
||||
|
||||
20030429
|
||||
|
||||
Bugfix: while verifying an address, the LMTP client entered
|
||||
a forbidden "next" sender state after the last recipient.
|
||||
Fix by Vladimir Davydoff. File: lmtp/lmtp_proto.c.
|
||||
|
||||
Bugfix: proxymap server did not parse "," as space.
|
||||
Leandro Santi. File: proxymap/proxymap.c.
|
||||
|
||||
20030502
|
||||
|
||||
Bugfix: defer delivery after .forward etc. file read error.
|
||||
File: local/token.c.
|
||||
|
||||
20030503
|
||||
|
||||
Bugfix: the Postfix LMTP client used the wrong service
|
||||
name, causing trouble with SASL 2.1.13. Daniel Schales,
|
||||
Louisiana Tech. File: lmtp/lmtp_sasl_glue.c.
|
||||
|
||||
20030518
|
||||
|
||||
Workaround: IRIX select() reports that a non-blocking file
|
||||
descriptor is writable while write() transfers zero bytes.
|
||||
File: util/vstream.c.
|
||||
|
||||
20030519
|
||||
|
||||
Feature: new require_{date,from,message_id,received}_header
|
||||
restriction to reject SMTP mail when some message header
|
||||
is missing. Only the From: and Date: headers are actually
|
||||
required by Internet mail standards; the Received: and
|
||||
Message-ID: headers are optional, but these are often
|
||||
missing from SPAM email. Files: global/cleanup_user.h,
|
||||
global/cleanup_strerror.c, smtpd/smtpd_check.c,
|
||||
cleanup/cleanup_message.c.
|
||||
|
||||
Open problems:
|
||||
|
||||
Low: smtp-source may block when sending large test messages.
|
||||
|
@@ -92,8 +92,7 @@ Incompatibilities with Postfix 1.1
|
||||
|
||||
- The local_recipient_maps feature is now turned on by default, so
|
||||
that the Postfix SMTP server rejects mail for unknown local
|
||||
recipients. This is enabled by default. See the LOCAL_RECIPIENT_README
|
||||
file hints and tips.
|
||||
recipients. See the LOCAL_RECIPIENT_README file hints and tips.
|
||||
|
||||
- Introduction of relay delivery transport in master.cf. This helps
|
||||
to avoid mail delivery scheduling problems on inbound mail relays,
|
||||
|
@@ -236,8 +236,9 @@ program.
|
||||
|
||||
Note: the localhost port 10025 SMTP server filter should announce
|
||||
itself as "220 localhost...". Postfix aborts delivery when it
|
||||
connects to an SMTP server that uses the same hostname, because
|
||||
that normally means you have a mail delivery loop problem.
|
||||
connects to an SMTP server that uses the same hostname as Postfix
|
||||
("host <servername> greeted me with my own hostname"), because that
|
||||
normally means you have a mail delivery loop problem.
|
||||
|
||||
The example here assumes that the /some/where/filter command is a
|
||||
PERL script. PERL has modules that make talking SMTP easy. The
|
||||
@@ -280,9 +281,9 @@ mail.
|
||||
The "-o local_recipient_maps=" and "-o relay_recipient_maps=" avoid
|
||||
unnecessary table lookups.
|
||||
|
||||
The "-o myhostname=localhost.domain.tld" avoids a possible problem
|
||||
if your content filter is based on a proxy that simply relays SMTP
|
||||
commands.
|
||||
The "-o myhostname=localhost.domain.tld" avoids false alarms ("host
|
||||
<servername> greeted me with my own hostname") if your content
|
||||
filter is based on a proxy that simply relays SMTP commands.
|
||||
|
||||
The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
|
||||
turn off UCE controls that would only waste time here.
|
||||
|
@@ -13,10 +13,11 @@ The old Postfix scheduler had several limitations due to unfortunate
|
||||
choices in its design.
|
||||
|
||||
1 - Round-robin selection by destination for mail that is delivered
|
||||
via the same message delivery transport. That strategy broke
|
||||
down when one single destination (say, inbound mail) had to
|
||||
compete with multiple other destinations (say, outbound mail).
|
||||
The poor suffering destination would be selected only
|
||||
via the same message delivery transport. The round-robin strategy
|
||||
was chosen with the intention to prevent a single (destination)
|
||||
site from using up too many mail delivery resources. However,
|
||||
that strategy penalized inbound mail on bi-directional gateways.
|
||||
The poor suffering inbound destination would be selected only
|
||||
1/number-of-destinations of the time, even when it had more
|
||||
mail than other destinations, and thus mail could be delayed.
|
||||
|
||||
@@ -62,7 +63,7 @@ However, even from programmer's point of view, there is nothing
|
||||
more to add to the message scheduling idea itself. There are few
|
||||
things which make it look more complicated than it is, but the
|
||||
algorithm is the same as the user percieves it. The summary of the
|
||||
changes from the user's view:
|
||||
differences of the programmer's view from the user's view are:
|
||||
|
||||
1) Simplification of terms for users: The user knows about messages
|
||||
and recipients. The program itself works with jobs (one message is
|
||||
|
@@ -68,7 +68,7 @@ virtual_mailbox_domains
|
||||
|
||||
Specifies the list of domains that should be delivered to the
|
||||
$virtual_transport delivery agent (default: virtual). As of
|
||||
version 1.2, Postfix is smart enough that you don't have to
|
||||
version 2.0, Postfix is smart enough that you don't have to
|
||||
list every virtual domain in a Postfix transport map.
|
||||
|
||||
virtual_mailbox_maps
|
||||
|
@@ -1,8 +1,14 @@
|
||||
#
|
||||
# Postfix master process configuration file. Each line describes how
|
||||
# a mailer component program should be run. The fields that make up
|
||||
# each line are described below. A "-" field value requests that a
|
||||
# default value be used for that field.
|
||||
# Postfix master process configuration file. Each logical line
|
||||
# describes how a Postfix daemon program should be run.
|
||||
#
|
||||
# A logical line starts with non-whitespace, non-comment text.
|
||||
# Empty lines and whitespace-only lines are ignored, as are comment
|
||||
# lines whose first non-whitespace character is a `#'.
|
||||
# A line that starts with whitespace continues a logical line.
|
||||
#
|
||||
# The fields that make up each line are described below. A "-" field
|
||||
# value requests that a default value be used for that field.
|
||||
#
|
||||
# Service: any name that is valid for the specified transport type
|
||||
# (the next field). With INET transports, a service is specified as
|
||||
@@ -59,12 +65,6 @@
|
||||
# SPECIFY ONLY PROGRAMS THAT ARE WRITTEN TO RUN AS POSTFIX DAEMONS.
|
||||
# ALL DAEMONS SPECIFIED HERE MUST SPEAK A POSTFIX-INTERNAL PROTOCOL.
|
||||
#
|
||||
# DO NOT CHANGE THE ZERO PROCESS LIMIT FOR CLEANUP/BOUNCE/DEFER OR
|
||||
# POSTFIX WILL BECOME STUCK UP UNDER HEAVY LOAD
|
||||
#
|
||||
# DO NOT CHANGE THE ONE PROCESS LIMIT FOR PICKUP/QMGR OR POSTFIX WILL
|
||||
# DELIVER MAIL MULTIPLE TIMES.
|
||||
#
|
||||
# DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES.
|
||||
#
|
||||
# ==========================================================================
|
||||
|
@@ -135,7 +135,7 @@
|
||||
#
|
||||
# EXAMPLE SMTPD ACCESS MAP
|
||||
# # Protect your outgoing majordomo exploders
|
||||
# /^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
|
||||
# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
|
||||
#
|
||||
# # Bounce friend@whatever, except when whatever is our domain (you would
|
||||
# # be better just bouncing all friend@ mail - this is just an example).
|
||||
|
@@ -66,4 +66,4 @@ strict_8bitmime = no
|
||||
#
|
||||
# This blocks mail from poorly written mail software.
|
||||
#
|
||||
strict_mime_domain_encoding = no
|
||||
strict_mime_encoding_domain = no
|
||||
|
@@ -45,7 +45,7 @@
|
||||
|
||||
# Protect your outgoing majordomo exploders
|
||||
#
|
||||
/^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
|
||||
/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
|
||||
|
||||
|
||||
# Bounce friend@whatever, except when whatever is our domain (you would
|
||||
|
@@ -30,4 +30,6 @@
|
||||
/^postmaster@/ OK
|
||||
|
||||
# Protect your outgoing majordomo exploders
|
||||
/^(.*)-outgoing@(.*)$/!/^owner-.*/ 550 Use ${1}@${2} instead
|
||||
if !/^owner-.*/
|
||||
/^(.*)-outgoing@(.*)$/ 550 Use ${1}@${2} instead
|
||||
endif
|
||||
|
@@ -136,7 +136,7 @@ PCRE_TABLE(5) PCRE_TABLE(5)
|
||||
|
||||
<b>EXAMPLE</b> <b>SMTPD</b> <b>ACCESS</b> <b>MAP</b>
|
||||
# Protect your outgoing majordomo exploders
|
||||
/^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
|
||||
/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
|
||||
|
||||
# Bounce friend@whatever, except when whatever is our domain (you would
|
||||
# be better just bouncing all friend@ mail - this is just an example).
|
||||
|
@@ -119,7 +119,7 @@ or $(n) if they aren't followed by whitespace.
|
||||
.na
|
||||
.nf
|
||||
# Protect your outgoing majordomo exploders
|
||||
/^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
|
||||
/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
|
||||
|
||||
# Bounce friend@whatever, except when whatever is our domain (you would
|
||||
# be better just bouncing all friend@ mail - this is just an example).
|
||||
|
@@ -121,7 +121,7 @@ this also breaks majordomo approval requests when the included
|
||||
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.
|
||||
|
@@ -111,7 +111,7 @@
|
||||
# or $(n) if they aren't followed by whitespace.
|
||||
# EXAMPLE SMTPD ACCESS MAP
|
||||
# # Protect your outgoing majordomo exploders
|
||||
# /^(?!owner-)(.*)-outgoing@/ 550 Use ${1}@${2} instead
|
||||
# /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
|
||||
#
|
||||
# # Bounce friend@whatever, except when whatever is our domain (you would
|
||||
# # be better just bouncing all friend@ mail - this is just an example).
|
||||
|
@@ -277,9 +277,6 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
|
||||
* our status report.
|
||||
*/
|
||||
if (CLEANUP_OUT_OK(state) == 0 && type > 0) {
|
||||
if ((state->errs & CLEANUP_STAT_CONT) == 0
|
||||
&& (state->flags & CLEANUP_FLAG_DISCARD) == 0)
|
||||
msg_warn("%s: skipping further client input", state->queue_id);
|
||||
while (type != REC_TYPE_END
|
||||
&& (type = rec_get(src, buf, 0)) > 0)
|
||||
/* void */ ;
|
||||
|
@@ -132,6 +132,8 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
|
||||
return;
|
||||
}
|
||||
if (type == REC_TYPE_FLGS) {
|
||||
if (msg_verbose)
|
||||
msg_info("envelope %c %.*s", type, len, buf);
|
||||
extra_flags = atol(buf);
|
||||
if (extra_flags & ~CLEANUP_FLAG_MASK_EXTRA)
|
||||
msg_warn("%s: bad extra flags: 0x%x", state->queue_id, extra_flags);
|
||||
|
@@ -493,6 +493,29 @@ static void cleanup_header_callback(void *context, int header_class,
|
||||
}
|
||||
}
|
||||
|
||||
/* cleanup_missing - handle missing message header */
|
||||
|
||||
static void cleanup_missing(CLEANUP_STATE *state, const char *resent,
|
||||
const char *header)
|
||||
{
|
||||
const char *attr;
|
||||
|
||||
if ((attr = nvtable_find(state->attr, MAIL_ATTR_ORIGIN)) == 0)
|
||||
attr = "unknown";
|
||||
vstring_sprintf(state->temp1, "%s: reject: missing %s%s header from %s;",
|
||||
state->queue_id, resent, header, attr);
|
||||
if (state->sender)
|
||||
vstring_sprintf_append(state->temp1, " from=<%s>", state->sender);
|
||||
if (state->recip)
|
||||
vstring_sprintf_append(state->temp1, " to=<%s>", state->recip);
|
||||
if ((attr = nvtable_find(state->attr, MAIL_ATTR_PROTO_NAME)) != 0)
|
||||
vstring_sprintf_append(state->temp1, " proto=%s", attr);
|
||||
if ((attr = nvtable_find(state->attr, MAIL_ATTR_HELO_NAME)) != 0)
|
||||
vstring_sprintf_append(state->temp1, " helo=<%s>", attr);
|
||||
msg_info("%s", vstring_str(state->temp1));
|
||||
state->errs |= CLEANUP_STAT_MISS_HDR;
|
||||
}
|
||||
|
||||
/* cleanup_header_done_callback - insert missing message headers */
|
||||
|
||||
static void cleanup_header_done_callback(void *context)
|
||||
@@ -502,6 +525,15 @@ static void cleanup_header_done_callback(void *context)
|
||||
struct tm *tp;
|
||||
TOK822 *token;
|
||||
|
||||
/*
|
||||
* Postfix prepends a Received: message header, so we should see two when
|
||||
* one is required.
|
||||
*/
|
||||
if ((state->flags & CLEANUP_FLAG_NEED_RCVD) && state->hop_count < 2) {
|
||||
cleanup_missing(state, "", "Received");
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Add a missing (Resent-)Message-Id: header. The message ID gives the
|
||||
* time in GMT units, plus the local queue ID.
|
||||
@@ -513,6 +545,10 @@ static void cleanup_header_done_callback(void *context)
|
||||
*/
|
||||
if ((state->headers_seen & (1 << (state->resent[0] ?
|
||||
HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID))) == 0) {
|
||||
if (state->flags & CLEANUP_FLAG_NEED_MSGID) {
|
||||
cleanup_missing(state, state->resent, "Message-Id");
|
||||
return;
|
||||
}
|
||||
tp = gmtime(&state->time);
|
||||
strftime(time_stamp, sizeof(time_stamp), "%Y%m%d%H%M%S", tp);
|
||||
cleanup_out_format(state, REC_TYPE_NORM, "%sMessage-Id: <%s.%s@%s>",
|
||||
@@ -528,6 +564,10 @@ static void cleanup_header_done_callback(void *context)
|
||||
*/
|
||||
if ((state->headers_seen & (1 << (state->resent[0] ?
|
||||
HDR_RESENT_DATE : HDR_DATE))) == 0) {
|
||||
if (state->flags & CLEANUP_FLAG_NEED_DATE) {
|
||||
cleanup_missing(state, state->resent, "Date");
|
||||
return;
|
||||
}
|
||||
cleanup_out_format(state, REC_TYPE_NORM, "%sDate: %s",
|
||||
state->resent, mail_date(state->time));
|
||||
}
|
||||
@@ -537,6 +577,10 @@ static void cleanup_header_done_callback(void *context)
|
||||
*/
|
||||
if ((state->headers_seen & (1 << (state->resent[0] ?
|
||||
HDR_RESENT_FROM : HDR_FROM))) == 0) {
|
||||
if (state->flags & CLEANUP_FLAG_NEED_FROM) {
|
||||
cleanup_missing(state, state->resent, "From");
|
||||
return;
|
||||
}
|
||||
quote_822_local(state->temp1, *state->sender ?
|
||||
state->sender : MAIL_ADDR_MAIL_DAEMON);
|
||||
vstring_sprintf(state->temp2, "%sFrom: %s",
|
||||
|
@@ -51,6 +51,7 @@ static struct cleanup_stat_map cleanup_stat_map[] = {
|
||||
CLEANUP_STAT_BAD, "Internal protocol error",
|
||||
CLEANUP_STAT_RCPT, "No recipients specified",
|
||||
CLEANUP_STAT_HOPS, "Too many hops",
|
||||
CLEANUP_STAT_MISS_HDR, "Missing message header",
|
||||
CLEANUP_STAT_SIZE, "Message file too big",
|
||||
CLEANUP_STAT_CONT, "Message content rejected",
|
||||
CLEANUP_STAT_WRITE, "Error writing message file",
|
||||
|
@@ -20,13 +20,19 @@
|
||||
#define CLEANUP_FLAG_HOLD (1<<2) /* Place message on hold */
|
||||
#define CLEANUP_FLAG_DISCARD (1<<3) /* Discard message silently */
|
||||
#define CLEANUP_FLAG_BCC_OK (1<<4) /* Ok to add auto-BCC addresses */
|
||||
#define CLEANUP_FLAG_NEED_DATE (1<<5) /* Require (Resent:-)Date: */
|
||||
#define CLEANUP_FLAG_NEED_FROM (1<<6) /* Require (Resent:-)From: */
|
||||
#define CLEANUP_FLAG_NEED_MSGID (1<<7) /* Require (Resent:-)Message-Id: */
|
||||
#define CLEANUP_FLAG_NEED_RCVD (1<<8) /* Require two Received: headers */
|
||||
|
||||
/*
|
||||
* These are set on the fly while processing SMTP envelopes or message
|
||||
* content.
|
||||
*/
|
||||
#define CLEANUP_FLAG_MASK_EXTRA \
|
||||
(CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD)
|
||||
(CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD | CLEANUP_FLAG_NEED_DATE | \
|
||||
CLEANUP_FLAG_NEED_FROM | CLEANUP_FLAG_NEED_MSGID | \
|
||||
CLEANUP_FLAG_NEED_RCVD)
|
||||
|
||||
/*
|
||||
* Diagnostics.
|
||||
@@ -39,6 +45,7 @@
|
||||
#define CLEANUP_STAT_SIZE (1<<2) /* Message file too big */
|
||||
#define CLEANUP_STAT_CONT (1<<3) /* Message content rejected */
|
||||
#define CLEANUP_STAT_HOPS (1<<4) /* Too many hops */
|
||||
#define CLEANUP_STAT_MISS_HDR (1<<5) /* Some missing header */
|
||||
#define CLEANUP_STAT_RCPT (1<<6) /* No recipients found */
|
||||
|
||||
/*
|
||||
|
@@ -1337,6 +1337,11 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\
|
||||
abcdefghijklmnopqrstuvwxyz{|}~"
|
||||
extern char *var_smtpd_exp_filter;
|
||||
|
||||
#define REQUIRE_DATE_HDR "require_date_header"
|
||||
#define REQUIRE_FROM_HDR "require_from_header"
|
||||
#define REQUIRE_MSGID_HDR "require_message_id_header"
|
||||
#define REQUIRE_RCVD_HDR "require_received_header"
|
||||
|
||||
/*
|
||||
* Heuristic to reject unknown local recipients at the SMTP port.
|
||||
*/
|
||||
|
@@ -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 "20030424"
|
||||
#define MAIL_RELEASE_DATE "20030519"
|
||||
|
||||
#define VAR_MAIL_VERSION "mail_version"
|
||||
#define DEF_MAIL_VERSION "2.0.9-" MAIL_RELEASE_DATE
|
||||
|
@@ -396,7 +396,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
|
||||
vstring_str(state->scratch));
|
||||
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
|
||||
next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
|
||||
LMTP_STATE_ABORT : LMTP_STATE_DATA;
|
||||
LMTP_STATE_RSET : LMTP_STATE_DATA;
|
||||
break;
|
||||
|
||||
/*
|
||||
|
@@ -369,7 +369,7 @@ void lmtp_sasl_start(LMTP_STATE *state)
|
||||
#define NULL_SERVER_ADDR ((char *) 0)
|
||||
#define NULL_CLIENT_ADDR ((char *) 0)
|
||||
|
||||
if (SASL_CLIENT_NEW("smtp", state->session->host,
|
||||
if (SASL_CLIENT_NEW("lmtp", state->session->host,
|
||||
NULL_CLIENT_ADDR, NULL_SERVER_ADDR,
|
||||
state->sasl_callbacks, NULL_SECFLAGS,
|
||||
(sasl_conn_t **) &state->sasl_conn) != SASL_OK)
|
||||
|
@@ -98,6 +98,7 @@
|
||||
#include <tok822.h>
|
||||
#include <mail_params.h>
|
||||
#include <bounce.h>
|
||||
#include <defer.h>
|
||||
|
||||
/* Application-specific. */
|
||||
|
||||
@@ -207,6 +208,10 @@ int deliver_token_stream(LOCAL_STATE state, USER_ATTR usr_attr,
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (vstream_ferror(fp))
|
||||
status = defer_append(BOUNCE_FLAGS(state.request),
|
||||
BOUNCE_ATTR(state.msg_attr),
|
||||
"error reading .forward file: %m");
|
||||
vstring_free(buf);
|
||||
return (status);
|
||||
}
|
||||
|
@@ -350,7 +350,7 @@ DICT *dict_proxy_open(const char *map, int open_flags, int dict_flags)
|
||||
|
||||
static void post_jail_init(char *unused_name, char **unused_argv)
|
||||
{
|
||||
const char *sep = " \t\r\n";
|
||||
const char *sep = ", \t\r\n";
|
||||
char *saved_filter;
|
||||
char *bp;
|
||||
char *type_name;
|
||||
|
@@ -482,6 +482,9 @@ static void qmqpd_send_status(QMQPD_STATE *state)
|
||||
} else if ((state->err & CLEANUP_STAT_RCPT) != 0) {
|
||||
qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD,
|
||||
"Error: no recipients specified");
|
||||
} else if ((state->err & CLEANUP_STAT_MISS_HDR) != 0) {
|
||||
qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD,
|
||||
"Error: missing message header");
|
||||
} else {
|
||||
qmqpd_reply(state, DO_LOG, QMQPD_STAT_RETRY,
|
||||
"Error: internal error %d", state->err);
|
||||
|
@@ -1141,6 +1141,9 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
|
||||
} else if ((state->err & CLEANUP_STAT_WRITE) != 0) {
|
||||
state->error_mask |= MAIL_ERROR_RESOURCE;
|
||||
smtpd_chat_reply(state, "451 Error: queue file write error");
|
||||
} else if ((state->err & CLEANUP_STAT_MISS_HDR) != 0) {
|
||||
state->error_mask |= MAIL_ERROR_POLICY;
|
||||
smtpd_chat_reply(state, "550 Error: missing message header");
|
||||
} else {
|
||||
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
||||
smtpd_chat_reply(state, "451 Error: internal error %d", state->err);
|
||||
|
@@ -57,6 +57,13 @@
|
||||
/* Reject, defer or permit the request unconditionally. This is to be used
|
||||
/* at the end of a restriction list in order to make the default
|
||||
/* action explicit.
|
||||
/* .IP require_date_header
|
||||
/* .IP require_from_header
|
||||
/* .IP require_message_id_header
|
||||
/* .IP require_received_header
|
||||
/* Reject the message when it does not contain a Date: etc.
|
||||
/* message header. Only the Date: header is required by mail
|
||||
/* standards. The other headers are usually added by MTAs.
|
||||
/* .IP reject_unknown_client
|
||||
/* Reject the request when the client hostname could not be found.
|
||||
/* The \fIunknown_client_reject_code\fR configuration parameter
|
||||
@@ -2750,6 +2757,26 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
|
||||
DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
|
||||
"450 <%s>: %s rejected: defer_if_reject requested",
|
||||
reply_name, reply_class);
|
||||
} else if (strcasecmp(name, REQUIRE_DATE_HDR) == 0) {
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
|
||||
CLEANUP_FLAG_NEED_DATE);
|
||||
#endif
|
||||
} else if (strcasecmp(name, REQUIRE_FROM_HDR) == 0) {
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
|
||||
CLEANUP_FLAG_NEED_FROM);
|
||||
#endif
|
||||
} else if (strcasecmp(name, REQUIRE_MSGID_HDR) == 0) {
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
|
||||
CLEANUP_FLAG_NEED_MSGID);
|
||||
#endif
|
||||
} else if (strcasecmp(name, REQUIRE_RCVD_HDR) == 0) {
|
||||
#ifndef TEST
|
||||
rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
|
||||
CLEANUP_FLAG_NEED_RCVD);
|
||||
#endif
|
||||
}
|
||||
|
||||
/*
|
||||
|
@@ -470,6 +470,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_NON_BLOCKING_WRITE_SELECT
|
||||
#endif
|
||||
|
||||
#if defined(IRIX5)
|
||||
|
@@ -535,11 +535,23 @@ static int vstream_fflush_some(VSTREAM *stream, int to_flush)
|
||||
* When flushing a buffer, allow for partial writes. These can happen
|
||||
* while talking to a network. Update the cached file seek position, if
|
||||
* any.
|
||||
*
|
||||
* XXX Workaround for IRIX brain damage: select() indicates that a pipe is
|
||||
* writable, but write() transfers zero bytes on non-blocking pipes. This
|
||||
* means that there is no reasonable way to enforce write timeouts.
|
||||
*/
|
||||
for (data = (char *) bp->data, len = to_flush; len > 0; len -= n, data += n) {
|
||||
if (stream->timeout)
|
||||
stream->iotime = time((time_t *) 0);
|
||||
if ((n = stream->write_fn(stream->fd, data, len, stream->timeout, stream->context)) <= 0) {
|
||||
#ifdef BROKEN_NON_BLOCKING_WRITE_SELECT
|
||||
if (n == 0) {
|
||||
msg_warn("%s: write() transfers 0 bytes on a writable descriptor!",
|
||||
myname);
|
||||
sleep(1);
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
bp->flags |= VSTREAM_FLAG_ERR;
|
||||
if (errno == ETIMEDOUT)
|
||||
bp->flags |= VSTREAM_FLAG_TIMEOUT;
|
||||
|
Reference in New Issue
Block a user