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:
|
Patrik Rak's clever queue manager scheduler (nqmgr). Files:
|
||||||
conf/sample-scheduler.cf, README_FILES/SCHEDULER_README.
|
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:
|
Open problems:
|
||||||
|
|
||||||
Low: smtp-source may block when sending large test messages.
|
Low: smtp-source may block when sending large test messages.
|
||||||
|
@@ -28,43 +28,43 @@ Initially the list of address classes is hard coded, but this is
|
|||||||
meant to become extensible:
|
meant to become extensible:
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Class Description
|
Class Description
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
local For UNIX accounts and for traditional /etc/aliases
|
local For UNIX accounts and for traditional /etc/aliases
|
||||||
Domain names are listed in $mydestination (or match the IP
|
Domain names are listed in $mydestination (or match the IP
|
||||||
address listed with $inet_interfaces)
|
address listed with $inet_interfaces)
|
||||||
Known recipients are listed in $local_recipient_maps (this
|
Known recipients are listed in $local_recipient_maps (this
|
||||||
information is currently used by the Postfix SMTP server
|
information is currently used by the Postfix SMTP server
|
||||||
only; if $local_recipient_maps is empty, the Postfix
|
only; if $local_recipient_maps is empty, the Postfix
|
||||||
SMTP server accepts all recipients)
|
SMTP server accepts all recipients)
|
||||||
Default delivery agent: local
|
Default delivery agent: local
|
||||||
|
|
||||||
virtual For hosted domains that are aliased to mailboxes in other
|
virtual For hosted domains that are aliased to mailboxes in other
|
||||||
alias domains
|
alias domains
|
||||||
Known recipients are listed in $virtual_alias_maps (default
|
Known recipients are listed in $virtual_alias_maps (default
|
||||||
is $virtual_maps for Postfix 1.1 compatibility)
|
is $virtual_maps for Postfix 1.1 compatibility)
|
||||||
Domain names are listed in $virtual_alias_domains (default
|
Domain names are listed in $virtual_alias_domains (default
|
||||||
is $virtual_alias_maps for Postfix 1.1 compatibility)
|
is $virtual_alias_maps for Postfix 1.1 compatibility)
|
||||||
|
|
||||||
virtual For hosted domains with their own mailboxes
|
virtual For hosted domains with their own mailboxes
|
||||||
mailbox Known recipients are listed in $virtual_mailbox_maps (if
|
mailbox Known recipients are listed in $virtual_mailbox_maps (if
|
||||||
this parameter is empty, the Postfix SMTP server accepts
|
this parameter is empty, the Postfix SMTP server accepts
|
||||||
all recipients for domains listed in $virtual_mailbox_domains)
|
all recipients for domains listed in $virtual_mailbox_domains)
|
||||||
Domain names are listed in $virtual_mailbox_domains (default
|
Domain names are listed in $virtual_mailbox_domains (default
|
||||||
is $virtual_mailbox_maps for Postfix 1.1 compatibility)
|
is $virtual_mailbox_maps for Postfix 1.1 compatibility)
|
||||||
Default delivery agent: virtual
|
Default delivery agent: virtual
|
||||||
|
|
||||||
relay For remote destinations that list your system as MX host
|
relay For remote destinations that list your system as MX host
|
||||||
Domain names are listed in $relay_domains
|
Domain names are listed in $relay_domains
|
||||||
Known recipients are listed in $relay_recipient_maps (if
|
Known recipients are listed in $relay_recipient_maps (if
|
||||||
this parameter is empty, the Postfix SMTP server accepts
|
this parameter is empty, the Postfix SMTP server accepts
|
||||||
all recipients for domains listed in $relay_domains)
|
all recipients for domains listed in $relay_domains)
|
||||||
Default delivery agent: relay (clone of default smtp agent)
|
Default delivery agent: relay (clone of default smtp agent)
|
||||||
|
|
||||||
other Restricted to mail from authorized clients
|
other Restricted to mail from authorized clients
|
||||||
Default delivery agent: smtp
|
Default delivery agent: smtp
|
||||||
No domain table
|
No domain table
|
||||||
No recipient table
|
No recipient table
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
|
|
||||||
Incompatibilities with Postfix 1.1
|
Incompatibilities with Postfix 1.1
|
||||||
@@ -92,8 +92,7 @@ Incompatibilities with Postfix 1.1
|
|||||||
|
|
||||||
- The local_recipient_maps feature is now turned on by default, so
|
- The local_recipient_maps feature is now turned on by default, so
|
||||||
that the Postfix SMTP server rejects mail for unknown local
|
that the Postfix SMTP server rejects mail for unknown local
|
||||||
recipients. This is enabled by default. See the LOCAL_RECIPIENT_README
|
recipients. See the LOCAL_RECIPIENT_README file hints and tips.
|
||||||
file hints and tips.
|
|
||||||
|
|
||||||
- Introduction of relay delivery transport in master.cf. This helps
|
- Introduction of relay delivery transport in master.cf. This helps
|
||||||
to avoid mail delivery scheduling problems on inbound mail relays,
|
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
|
Note: the localhost port 10025 SMTP server filter should announce
|
||||||
itself as "220 localhost...". Postfix aborts delivery when it
|
itself as "220 localhost...". Postfix aborts delivery when it
|
||||||
connects to an SMTP server that uses the same hostname, because
|
connects to an SMTP server that uses the same hostname as Postfix
|
||||||
that normally means you have a mail delivery loop problem.
|
("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
|
The example here assumes that the /some/where/filter command is a
|
||||||
PERL script. PERL has modules that make talking SMTP easy. The
|
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
|
The "-o local_recipient_maps=" and "-o relay_recipient_maps=" avoid
|
||||||
unnecessary table lookups.
|
unnecessary table lookups.
|
||||||
|
|
||||||
The "-o myhostname=localhost.domain.tld" avoids a possible problem
|
The "-o myhostname=localhost.domain.tld" avoids false alarms ("host
|
||||||
if your content filter is based on a proxy that simply relays SMTP
|
<servername> greeted me with my own hostname") if your content
|
||||||
commands.
|
filter is based on a proxy that simply relays SMTP commands.
|
||||||
|
|
||||||
The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
|
The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
|
||||||
turn off UCE controls that would only waste time here.
|
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.
|
choices in its design.
|
||||||
|
|
||||||
1 - Round-robin selection by destination for mail that is delivered
|
1 - Round-robin selection by destination for mail that is delivered
|
||||||
via the same message delivery transport. That strategy broke
|
via the same message delivery transport. The round-robin strategy
|
||||||
down when one single destination (say, inbound mail) had to
|
was chosen with the intention to prevent a single (destination)
|
||||||
compete with multiple other destinations (say, outbound mail).
|
site from using up too many mail delivery resources. However,
|
||||||
The poor suffering destination would be selected only
|
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
|
1/number-of-destinations of the time, even when it had more
|
||||||
mail than other destinations, and thus mail could be delayed.
|
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
|
more to add to the message scheduling idea itself. There are few
|
||||||
things which make it look more complicated than it is, but the
|
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
|
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
|
1) Simplification of terms for users: The user knows about messages
|
||||||
and recipients. The program itself works with jobs (one message is
|
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
|
Specifies the list of domains that should be delivered to the
|
||||||
$virtual_transport delivery agent (default: virtual). As of
|
$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.
|
list every virtual domain in a Postfix transport map.
|
||||||
|
|
||||||
virtual_mailbox_maps
|
virtual_mailbox_maps
|
||||||
|
@@ -1,8 +1,14 @@
|
|||||||
#
|
#
|
||||||
# Postfix master process configuration file. Each line describes how
|
# Postfix master process configuration file. Each logical line
|
||||||
# a mailer component program should be run. The fields that make up
|
# describes how a Postfix daemon program should be run.
|
||||||
# each line are described below. A "-" field value requests that a
|
#
|
||||||
# default value be used for that field.
|
# 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
|
# Service: any name that is valid for the specified transport type
|
||||||
# (the next field). With INET transports, a service is specified as
|
# (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.
|
# SPECIFY ONLY PROGRAMS THAT ARE WRITTEN TO RUN AS POSTFIX DAEMONS.
|
||||||
# ALL DAEMONS SPECIFIED HERE MUST SPEAK A POSTFIX-INTERNAL PROTOCOL.
|
# 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.
|
# DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES.
|
||||||
#
|
#
|
||||||
# ==========================================================================
|
# ==========================================================================
|
||||||
|
@@ -135,7 +135,7 @@
|
|||||||
#
|
#
|
||||||
# EXAMPLE SMTPD ACCESS MAP
|
# EXAMPLE SMTPD ACCESS MAP
|
||||||
# # Protect your outgoing majordomo exploders
|
# # 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
|
# # Bounce friend@whatever, except when whatever is our domain (you would
|
||||||
# # be better just bouncing all friend@ mail - this is just an example).
|
# # 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.
|
# 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
|
# 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
|
# Bounce friend@whatever, except when whatever is our domain (you would
|
||||||
|
@@ -30,4 +30,6 @@
|
|||||||
/^postmaster@/ OK
|
/^postmaster@/ OK
|
||||||
|
|
||||||
# Protect your outgoing majordomo exploders
|
# 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>
|
<b>EXAMPLE</b> <b>SMTPD</b> <b>ACCESS</b> <b>MAP</b>
|
||||||
# Protect your outgoing majordomo exploders
|
# 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
|
# Bounce friend@whatever, except when whatever is our domain (you would
|
||||||
# be better just bouncing all friend@ mail - this is just an example).
|
# 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
|
.na
|
||||||
.nf
|
.nf
|
||||||
# Protect your outgoing majordomo exploders
|
# 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
|
# Bounce friend@whatever, except when whatever is our domain (you would
|
||||||
# be better just bouncing all friend@ mail - this is just an example).
|
# 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
|
request contains valid 8-bit MIME mail, and it breaks bounces from
|
||||||
mailers that do not properly encapsulate 8-bit content (for example,
|
mailers that do not properly encapsulate 8-bit content (for example,
|
||||||
bounces from qmail or from old versions of Postfix).
|
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
|
Reject mail with invalid \fBContent-Transfer-Encoding:\fR
|
||||||
information for message/* or multipart/*. This blocks mail
|
information for message/* or multipart/*. This blocks mail
|
||||||
from poorly written software.
|
from poorly written software.
|
||||||
|
@@ -111,7 +111,7 @@
|
|||||||
# or $(n) if they aren't followed by whitespace.
|
# or $(n) if they aren't followed by whitespace.
|
||||||
# EXAMPLE SMTPD ACCESS MAP
|
# EXAMPLE SMTPD ACCESS MAP
|
||||||
# # Protect your outgoing majordomo exploders
|
# # 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
|
# # Bounce friend@whatever, except when whatever is our domain (you would
|
||||||
# # be better just bouncing all friend@ mail - this is just an example).
|
# # 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.
|
* our status report.
|
||||||
*/
|
*/
|
||||||
if (CLEANUP_OUT_OK(state) == 0 && type > 0) {
|
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
|
while (type != REC_TYPE_END
|
||||||
&& (type = rec_get(src, buf, 0)) > 0)
|
&& (type = rec_get(src, buf, 0)) > 0)
|
||||||
/* void */ ;
|
/* void */ ;
|
||||||
|
@@ -132,6 +132,8 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (type == REC_TYPE_FLGS) {
|
if (type == REC_TYPE_FLGS) {
|
||||||
|
if (msg_verbose)
|
||||||
|
msg_info("envelope %c %.*s", type, len, buf);
|
||||||
extra_flags = atol(buf);
|
extra_flags = atol(buf);
|
||||||
if (extra_flags & ~CLEANUP_FLAG_MASK_EXTRA)
|
if (extra_flags & ~CLEANUP_FLAG_MASK_EXTRA)
|
||||||
msg_warn("%s: bad extra flags: 0x%x", state->queue_id, extra_flags);
|
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 */
|
/* cleanup_header_done_callback - insert missing message headers */
|
||||||
|
|
||||||
static void cleanup_header_done_callback(void *context)
|
static void cleanup_header_done_callback(void *context)
|
||||||
@@ -502,6 +525,15 @@ static void cleanup_header_done_callback(void *context)
|
|||||||
struct tm *tp;
|
struct tm *tp;
|
||||||
TOK822 *token;
|
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
|
* Add a missing (Resent-)Message-Id: header. The message ID gives the
|
||||||
* time in GMT units, plus the local queue ID.
|
* 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] ?
|
if ((state->headers_seen & (1 << (state->resent[0] ?
|
||||||
HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID))) == 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);
|
tp = gmtime(&state->time);
|
||||||
strftime(time_stamp, sizeof(time_stamp), "%Y%m%d%H%M%S", tp);
|
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>",
|
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] ?
|
if ((state->headers_seen & (1 << (state->resent[0] ?
|
||||||
HDR_RESENT_DATE : HDR_DATE))) == 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",
|
cleanup_out_format(state, REC_TYPE_NORM, "%sDate: %s",
|
||||||
state->resent, mail_date(state->time));
|
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] ?
|
if ((state->headers_seen & (1 << (state->resent[0] ?
|
||||||
HDR_RESENT_FROM : HDR_FROM))) == 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 ?
|
quote_822_local(state->temp1, *state->sender ?
|
||||||
state->sender : MAIL_ADDR_MAIL_DAEMON);
|
state->sender : MAIL_ADDR_MAIL_DAEMON);
|
||||||
vstring_sprintf(state->temp2, "%sFrom: %s",
|
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_BAD, "Internal protocol error",
|
||||||
CLEANUP_STAT_RCPT, "No recipients specified",
|
CLEANUP_STAT_RCPT, "No recipients specified",
|
||||||
CLEANUP_STAT_HOPS, "Too many hops",
|
CLEANUP_STAT_HOPS, "Too many hops",
|
||||||
|
CLEANUP_STAT_MISS_HDR, "Missing message header",
|
||||||
CLEANUP_STAT_SIZE, "Message file too big",
|
CLEANUP_STAT_SIZE, "Message file too big",
|
||||||
CLEANUP_STAT_CONT, "Message content rejected",
|
CLEANUP_STAT_CONT, "Message content rejected",
|
||||||
CLEANUP_STAT_WRITE, "Error writing message file",
|
CLEANUP_STAT_WRITE, "Error writing message file",
|
||||||
|
@@ -20,13 +20,19 @@
|
|||||||
#define CLEANUP_FLAG_HOLD (1<<2) /* Place message on hold */
|
#define CLEANUP_FLAG_HOLD (1<<2) /* Place message on hold */
|
||||||
#define CLEANUP_FLAG_DISCARD (1<<3) /* Discard message silently */
|
#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_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
|
* These are set on the fly while processing SMTP envelopes or message
|
||||||
* content.
|
* content.
|
||||||
*/
|
*/
|
||||||
#define CLEANUP_FLAG_MASK_EXTRA \
|
#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.
|
* Diagnostics.
|
||||||
@@ -39,6 +45,7 @@
|
|||||||
#define CLEANUP_STAT_SIZE (1<<2) /* Message file too big */
|
#define CLEANUP_STAT_SIZE (1<<2) /* Message file too big */
|
||||||
#define CLEANUP_STAT_CONT (1<<3) /* Message content rejected */
|
#define CLEANUP_STAT_CONT (1<<3) /* Message content rejected */
|
||||||
#define CLEANUP_STAT_HOPS (1<<4) /* Too many hops */
|
#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 */
|
#define CLEANUP_STAT_RCPT (1<<6) /* No recipients found */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -1337,6 +1337,11 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\
|
|||||||
abcdefghijklmnopqrstuvwxyz{|}~"
|
abcdefghijklmnopqrstuvwxyz{|}~"
|
||||||
extern char *var_smtpd_exp_filter;
|
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.
|
* 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
|
* Patches change the patchlevel and the release date. Snapshots change the
|
||||||
* release date only, unless they include the same bugfix as a patch release.
|
* 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 VAR_MAIL_VERSION "mail_version"
|
||||||
#define DEF_MAIL_VERSION "2.0.9-" MAIL_RELEASE_DATE
|
#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));
|
vstring_str(state->scratch));
|
||||||
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
|
if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
|
||||||
next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
|
next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
|
||||||
LMTP_STATE_ABORT : LMTP_STATE_DATA;
|
LMTP_STATE_RSET : LMTP_STATE_DATA;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@@ -369,7 +369,7 @@ void lmtp_sasl_start(LMTP_STATE *state)
|
|||||||
#define NULL_SERVER_ADDR ((char *) 0)
|
#define NULL_SERVER_ADDR ((char *) 0)
|
||||||
#define NULL_CLIENT_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,
|
NULL_CLIENT_ADDR, NULL_SERVER_ADDR,
|
||||||
state->sasl_callbacks, NULL_SECFLAGS,
|
state->sasl_callbacks, NULL_SECFLAGS,
|
||||||
(sasl_conn_t **) &state->sasl_conn) != SASL_OK)
|
(sasl_conn_t **) &state->sasl_conn) != SASL_OK)
|
||||||
|
@@ -98,6 +98,7 @@
|
|||||||
#include <tok822.h>
|
#include <tok822.h>
|
||||||
#include <mail_params.h>
|
#include <mail_params.h>
|
||||||
#include <bounce.h>
|
#include <bounce.h>
|
||||||
|
#include <defer.h>
|
||||||
|
|
||||||
/* Application-specific. */
|
/* Application-specific. */
|
||||||
|
|
||||||
@@ -207,6 +208,10 @@ int deliver_token_stream(LOCAL_STATE state, USER_ATTR usr_attr,
|
|||||||
break;
|
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);
|
vstring_free(buf);
|
||||||
return (status);
|
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)
|
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 *saved_filter;
|
||||||
char *bp;
|
char *bp;
|
||||||
char *type_name;
|
char *type_name;
|
||||||
|
@@ -482,6 +482,9 @@ static void qmqpd_send_status(QMQPD_STATE *state)
|
|||||||
} else if ((state->err & CLEANUP_STAT_RCPT) != 0) {
|
} else if ((state->err & CLEANUP_STAT_RCPT) != 0) {
|
||||||
qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD,
|
qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD,
|
||||||
"Error: no recipients specified");
|
"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 {
|
} else {
|
||||||
qmqpd_reply(state, DO_LOG, QMQPD_STAT_RETRY,
|
qmqpd_reply(state, DO_LOG, QMQPD_STAT_RETRY,
|
||||||
"Error: internal error %d", state->err);
|
"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) {
|
} else if ((state->err & CLEANUP_STAT_WRITE) != 0) {
|
||||||
state->error_mask |= MAIL_ERROR_RESOURCE;
|
state->error_mask |= MAIL_ERROR_RESOURCE;
|
||||||
smtpd_chat_reply(state, "451 Error: queue file write error");
|
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 {
|
} else {
|
||||||
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
state->error_mask |= MAIL_ERROR_SOFTWARE;
|
||||||
smtpd_chat_reply(state, "451 Error: internal error %d", state->err);
|
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
|
/* 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
|
/* at the end of a restriction list in order to make the default
|
||||||
/* action explicit.
|
/* 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
|
/* .IP reject_unknown_client
|
||||||
/* Reject the request when the client hostname could not be found.
|
/* Reject the request when the client hostname could not be found.
|
||||||
/* The \fIunknown_client_reject_code\fR configuration parameter
|
/* 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,
|
DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
|
||||||
"450 <%s>: %s rejected: defer_if_reject requested",
|
"450 <%s>: %s rejected: defer_if_reject requested",
|
||||||
reply_name, reply_class);
|
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 DBM_NO_TRAILING_NULL /* XXX check */
|
||||||
#define USE_STATVFS
|
#define USE_STATVFS
|
||||||
#define STATVFS_IN_SYS_STATVFS_H
|
#define STATVFS_IN_SYS_STATVFS_H
|
||||||
|
#define BROKEN_NON_BLOCKING_WRITE_SELECT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(IRIX5)
|
#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
|
* When flushing a buffer, allow for partial writes. These can happen
|
||||||
* while talking to a network. Update the cached file seek position, if
|
* while talking to a network. Update the cached file seek position, if
|
||||||
* any.
|
* 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) {
|
for (data = (char *) bp->data, len = to_flush; len > 0; len -= n, data += n) {
|
||||||
if (stream->timeout)
|
if (stream->timeout)
|
||||||
stream->iotime = time((time_t *) 0);
|
stream->iotime = time((time_t *) 0);
|
||||||
if ((n = stream->write_fn(stream->fd, data, len, stream->timeout, stream->context)) <= 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;
|
bp->flags |= VSTREAM_FLAG_ERR;
|
||||||
if (errno == ETIMEDOUT)
|
if (errno == ETIMEDOUT)
|
||||||
bp->flags |= VSTREAM_FLAG_TIMEOUT;
|
bp->flags |= VSTREAM_FLAG_TIMEOUT;
|
||||||
|
Reference in New Issue
Block a user