From: Wietse Venema
Date: Fri, 2 Dec 2005 05:00:00 +0000 (-0500)
Subject: postfix-2.3-20051202
X-Git-Tag: v2.3-RC1~38
X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=c085550e825cb9f4e93dd0dd055dc8f8a3c6b7c3;p=thirdparty%2Fpostfix.git
postfix-2.3-20051202
---
diff --git a/postfix/HISTORY b/postfix/HISTORY
index 7dfc871a4..7966419ea 100644
--- a/postfix/HISTORY
+++ b/postfix/HISTORY
@@ -11447,24 +11447,25 @@ Apologies for any names omitted.
trivial-rewrite/resolve.c, trivial-rewrite/transport.c,
*qmgr/qmgr_message.c.
- Also: address_verify_sender_dependent_relayhost_maps for completeness.
+ Also: address_verify_sender_dependent_relayhost_maps for
+ completeness.
20051124
- Feature: specify "smtp_sender_dependent_authentication = yes" to
- enable sender-dependent SASL passwords. This disables SMTP
- connection caching to ensure that mail from different senders
- is delivered with the appropriate credentials. This is an
- extended version of a patch by Mathias Hasselmann. Files:
- smtp/smtp_connect.c, smtp/smtp_sasl_glue.c.
+ Feature: specify "smtp_sender_dependent_authentication =
+ yes" to enable sender-dependent SASL passwords. This disables
+ SMTP connection caching to ensure that mail from different
+ senders is delivered with the appropriate credentials. This
+ is an extended version of a patch by Mathias Hasselmann.
+ Files: smtp/smtp_connect.c, smtp/smtp_sasl_glue.c.
20051126
Workaround: log warning when REDIRECT or FILTER are used
in smtpd_end_of_data_restrictions. File: smtpd/smtpd_check.c.
- Log warning when REDIRECT or FILTER are used in
- smtpd_etrn_restrictions. File: smtpd/smtpd_check.c.
+ Log warning when REDIRECT, FILTER, HOLD and DISCARD are
+ used in smtpd_etrn_restrictions. File: smtpd/smtpd_check.c.
20051128
@@ -11475,6 +11476,22 @@ Apologies for any names omitted.
is received. Files: smtpd/smtpd.c, smtpd/smtpd_check.c,
cleanup/cleanup_extracted.c, pickup/pickup.c.
+ Safety: abort if the SMTP or QMQP server runs with non-postfix
+ privileges while it's connected to the network. Files:
+ smtpd/smtpd_peer.c, qmqpd/qmqpd_peer.c.
+
+20051201
+
+ Bugfix: the LMTP client would reuse a session after negative
+ reply to the RSET command (which may happen when client and
+ server somehow get out of sync). Problem found by Christian
+ Theune. Files: lmtp/lmtp.c, lmtp/lmtp_proto.c.
+
+20051202
+
+ Bugfix: the 20051128 code move for "smtpd_end_of_data_restrictions"
+ broke "postsuper -r".
+
Open problems:
"postsuper -r" no longer resets the message arrival time,
diff --git a/postfix/README_FILES/CONNECTION_CACHE_README b/postfix/README_FILES/CONNECTION_CACHE_README
index 5e8abe15a..976ca8352 100644
--- a/postfix/README_FILES/CONNECTION_CACHE_README
+++ b/postfix/README_FILES/CONNECTION_CACHE_README
@@ -137,8 +137,19 @@ mechanisms:
* The Postfix smtp(8) client reuses a session for only a limited number of
times. This avoids triggering bugs in implementations that do not correctly
- handle multiple deliveries per session. The use count is limited with the
- smtp_connection_cache_reuse_limit configuration parameter.
+ handle multiple deliveries per session.
+
+ With Postfix 2.2 the use count is limited with the
+ smtp_connection_cache_reuse_limit configuration parameter. With Postfix 2.3
+ this is replaced by a time limit which is specified with the
+ smtp_connection_reuse_time_limit parameter. In addition, Postfix 2.3 logs
+ the use count of multiply-used connections, as shown in the following
+ example:
+
+ Nov 3 16:04:31 myname postfix/smtp[30840]: 19B6B2900FE:
+ to=, orig_to=,
+ relay=mail.example.com[1.2.3.4], ccoonnnn__uussee==22, delay=0.22,
+ delays=0.04/0.01/0.05/0.1, dsn=2.0.0, status=sent (250 2.0.0 Ok)
* The connection cache explicitly labels each cached connection with
destination domain and IP address information. A connection cache lookup
diff --git a/postfix/README_FILES/SASL_README b/postfix/README_FILES/SASL_README
index 2cc7da6af..86e0bfee6 100644
--- a/postfix/README_FILES/SASL_README
+++ b/postfix/README_FILES/SASL_README
@@ -127,6 +127,12 @@ In /usr/local/lib/sasl/smtpd.conf (SASL version 1.5.5) or /usr/local/lib/sasl2/
smtpd.conf (SASL version 2.1.1) you need to specify how the server should
validate client passwords.
+Note: some Postfix distributions are modified and look for the smtpd.conf file
+in /etc/postfix.
+
+Note: some Cyrus SASL distributions are modified and look for the smtpd.conf
+file in /etc/sasl2.
+
In order to authenticate against the UNIX password database, try:
(SASL version 1.5.5)
diff --git a/postfix/README_FILES/SMTPD_PROXY_README b/postfix/README_FILES/SMTPD_PROXY_README
index a394a95e1..353d9ceec 100644
--- a/postfix/README_FILES/SMTPD_PROXY_README
+++ b/postfix/README_FILES/SMTPD_PROXY_README
@@ -141,7 +141,12 @@ master.cf file:
* The "-o smtpd_proxy_filter=127.0.0.1:10025" tells the before filter SMTP
server that it should give incoming mail to the content filter that listens
- on localhost port 10025.
+ on localhost TCP port 10025.
+
+ * Postfix 2.3 supports both TCP and UNIX-domain filters. The above filter
+ could be specified as "inet:127.0.0.1:10025". To specify a UNIX-domain
+ filter, specify "unix:pathame". A relative pathname is interpreted relative
+ to the Postfix queue directory.
The after-filter SMTP server is a new master.cf entry:
diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES
index d924ef2d7..d3ff5ff43 100644
--- a/postfix/RELEASE_NOTES
+++ b/postfix/RELEASE_NOTES
@@ -17,6 +17,14 @@ 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 20051202
+======================================
+
+The Postfix SMTP daemon will not receive mail from the network if
+it isn't running with postfix mail_owner privileges. This prevents
+surprises when, for example, "sendmail -bs" is configured to run
+as root from xinetd.
+
Incompatibility with snapshot 20051125
======================================
diff --git a/postfix/html/CONNECTION_CACHE_README.html b/postfix/html/CONNECTION_CACHE_README.html
index 715b28fe6..2c741ced4 100644
--- a/postfix/html/CONNECTION_CACHE_README.html
+++ b/postfix/html/CONNECTION_CACHE_README.html
@@ -162,18 +162,18 @@ or pseudo-destinations:
--
if mail is sent without a relay host: a domain name (the
+
-
if mail is sent without a relay host: a domain name (the
right-hand side of an email address, without the [] around a numeric
IP address),
- -
if mail is sent via a relay host: a relay host name (without
+
-
if mail is sent via a relay host: a relay host name (without
the [] or non-default TCP port), as specified in main.cf or in the
transport map,
- -
a /file/name with domain names and/or relay host names as
+
-
a /file/name with domain names and/or relay host names as
defined above,
- -
a "type:table" with domain names and/or relay host names
+
-
a "type:table" with domain names and/or relay host names
on the left-hand side. The right-hand side result from "type:table"
lookups is ignored.
@@ -211,9 +211,23 @@ configuration parameters. This prevents anti-social behavior.
-
The Postfix smtp(8) client reuses a session for only a
limited number of times. This avoids triggering bugs in implementations
-that do not correctly handle multiple deliveries per session. The
-use count is limited with the smtp_connection_cache_reuse_limit
-configuration parameter.
+that do not correctly handle multiple deliveries per session.
+
+ With Postfix 2.2 the use count is limited with the
+smtp_connection_cache_reuse_limit configuration parameter. With
+Postfix 2.3 this is replaced by a time limit which is specified
+with the smtp_connection_reuse_time_limit parameter. In addition,
+Postfix 2.3 logs the use count of multiply-used connections,
+as shown in the following example:
+
+
+
+Nov 3 16:04:31 myname postfix/smtp[30840]: 19B6B2900FE:
+to=<wietse@test.example.com>, orig_to=<wietse@test>,
+relay=mail.example.com[1.2.3.4], conn_use=2, delay=0.22,
+delays=0.04/0.01/0.05/0.1, dsn=2.0.0, status=sent (250 2.0.0 Ok)
+
+
-
The connection cache explicitly labels each cached connection
with destination domain and IP address information. A connection
diff --git a/postfix/html/SASL_README.html b/postfix/html/SASL_README.html
index f3e53efad..438709dac 100644
--- a/postfix/html/SASL_README.html
+++ b/postfix/html/SASL_README.html
@@ -199,6 +199,12 @@ SMTP server
/usr/local/lib/sasl2/smtpd.conf (SASL version 2.1.1) you need to
specify how the server should validate client passwords.
+ Note: some Postfix distributions are modified and look for
+the smtpd.conf file in /etc/postfix.
+
+ Note: some Cyrus SASL distributions are modified and look for
+the smtpd.conf file in /etc/sasl2.
+
In order to authenticate against the UNIX password database, try:
diff --git a/postfix/html/SMTPD_PROXY_README.html b/postfix/html/SMTPD_PROXY_README.html
index 3b1160731..486daa3d9 100644
--- a/postfix/html/SMTPD_PROXY_README.html
+++ b/postfix/html/SMTPD_PROXY_README.html
@@ -267,7 +267,7 @@ the top of the master.cf file:
-
The "-o smtpd_client_connection_count_limit=10" prevents
one SMTP client from using up all 20 SMTP server processes.
This limit is not necessary if you receive all mail from a
- trusted relay host.
+ trusted relay host.
Note: this setting is ignored by the stable Postfix 2.1
release. The feature will be available only in the experimental
@@ -275,7 +275,13 @@ the top of the master.cf file:
-
The "-o smtpd_proxy_filter=127.0.0.1:10025" tells the
before filter SMTP server that it should give incoming mail to
- the content filter that listens on localhost port 10025.
+ the content filter that listens on localhost TCP port 10025.
+
+ -
Postfix 2.3 supports both TCP and UNIX-domain filters.
+ The above filter could be specified as "inet:127.0.0.1:10025".
+ To specify a UNIX-domain filter, specify "unix:pathame".
+ A relative pathname is interpreted relative to the Postfix queue
+ directory.
diff --git a/postfix/mantools/srctoman b/postfix/mantools/srctoman
index 3a27cc681..42c2291d2 100755
--- a/postfix/mantools/srctoman
+++ b/postfix/mantools/srctoman
@@ -96,6 +96,7 @@ do
s/^'"$B"' *//
s/^ //
s/^[ ]*$//
+ /^\\"/d
' $i
done | expand
diff --git a/postfix/proto/CONNECTION_CACHE_README.html b/postfix/proto/CONNECTION_CACHE_README.html
index 3c6156cf5..17692e713 100644
--- a/postfix/proto/CONNECTION_CACHE_README.html
+++ b/postfix/proto/CONNECTION_CACHE_README.html
@@ -211,9 +211,23 @@ configuration parameters. This prevents anti-social behavior.
The Postfix smtp(8) client reuses a session for only a
limited number of times. This avoids triggering bugs in implementations
-that do not correctly handle multiple deliveries per session. The
-use count is limited with the smtp_connection_cache_reuse_limit
-configuration parameter.
+that do not correctly handle multiple deliveries per session.
+
+ With Postfix 2.2 the use count is limited with the
+smtp_connection_cache_reuse_limit configuration parameter. With
+Postfix 2.3 this is replaced by a time limit which is specified
+with the smtp_connection_reuse_time_limit parameter. In addition,
+Postfix 2.3 logs the use count of multiply-used connections,
+as shown in the following example:
+
+
+
+Nov 3 16:04:31 myname postfix/smtp[30840]: 19B6B2900FE:
+to=<wietse@test.example.com>, orig_to=<wietse@test>,
+relay=mail.example.com[1.2.3.4], conn_use=2, delay=0.22,
+delays=0.04/0.01/0.05/0.1, dsn=2.0.0, status=sent (250 2.0.0 Ok)
+
+
The connection cache explicitly labels each cached connection
with destination domain and IP address information. A connection
diff --git a/postfix/proto/SASL_README.html b/postfix/proto/SASL_README.html
index 8a6aa49c6..b60ba9aea 100644
--- a/postfix/proto/SASL_README.html
+++ b/postfix/proto/SASL_README.html
@@ -199,6 +199,12 @@ SMTP server
/usr/local/lib/sasl2/smtpd.conf (SASL version 2.1.1) you need to
specify how the server should validate client passwords.
+ Note: some Postfix distributions are modified and look for
+the smtpd.conf file in /etc/postfix.
+
+ Note: some Cyrus SASL distributions are modified and look for
+the smtpd.conf file in /etc/sasl2.
+
In order to authenticate against the UNIX password database, try:
diff --git a/postfix/proto/SMTPD_PROXY_README.html b/postfix/proto/SMTPD_PROXY_README.html
index 2992f6df2..23a8899b5 100644
--- a/postfix/proto/SMTPD_PROXY_README.html
+++ b/postfix/proto/SMTPD_PROXY_README.html
@@ -275,7 +275,13 @@ the top of the master.cf file:
The "-o smtpd_proxy_filter=127.0.0.1:10025" tells the
before filter SMTP server that it should give incoming mail to
- the content filter that listens on localhost port 10025.
+ the content filter that listens on localhost TCP port 10025.
+
+ Postfix 2.3 supports both TCP and UNIX-domain filters.
+ The above filter could be specified as "inet:127.0.0.1:10025".
+ To specify a UNIX-domain filter, specify "unix:pathame".
+ A relative pathname is interpreted relative to the Postfix queue
+ directory.
diff --git a/postfix/proto/access b/postfix/proto/access
index 289b68f11..e164c21e9 100644
--- a/postfix/proto/access
+++ b/postfix/proto/access
@@ -148,11 +148,11 @@
# REJECT ACTIONS
# .ad
# .fi
-# Postfix version 2.3 and later support enhanced status codes.
-# When no code is specified at the beginning of the \fItext\fR
-# below, Postfix inserts a default enhanced status code of "5.7.1"
-# in the case of reject actions, and "4.7.1" in the case of
-# defer actions. See "ENHANCED STATUS CODES" below.
+# Postfix version 2.3 and later support enhanced status codes.
+# When no code is specified at the beginning of the \fItext\fR
+# below, Postfix inserts a default enhanced status code of "5.7.1"
+# in the case of reject actions, and "4.7.1" in the case of
+# defer actions. See "ENHANCED STATUS CODES" below.
# .IP "\fB4\fINN text\fR"
# .IP "\fB5\fINN text\fR"
# Reject the address etc. that matches the pattern, and respond with
@@ -183,6 +183,33 @@
# .IP \fIrestriction...\fR
# Apply the named UCE restriction(s) (\fBpermit\fR, \fBreject\fR,
# \fBreject_unauth_destination\fR, and so on).
+# \" .IP "\fBDELAY \fItime\fR"
+# \" Place the message into the deferred queue, and delay the
+# \" initial delivery attempt by \fItime\fR. The time value may
+# \" be followed by a one-character suffix that specifies the
+# \" time unit: s (seconds), m (minutes), h (hours), d (days),
+# \" w (weeks). The default time unit is s (seconds).
+# \" .sp
+# \" Limitations:
+# \" .RS
+# \" .IP \(bu
+# \" This action affects all the recipients of the message.
+# \" .IP \(bu
+# \" The delay value has no effect with remote file systems that
+# \" don't correctly emulate UNIX local file system semantics.
+# \" In that case, the delay will be half of $queue_run_delay
+# \" on average.
+# \" .IP \(bu
+# \" Mail will still be delivered with "sendmail -q", "postfix
+# \" flush" or "postqueue -f".
+# \" .IP \(bu
+# \" Delayed mail increases the amount of disk I/O during deferred
+# \" queue scans. When large amounts of mail are queued for
+# \" delayed delivery it may be preferable to use the HOLD feature
+# \" instead.
+# \" .RE
+# \" .IP
+# \" This feature is available in Postfix 2.3 and later.
# .IP "\fBDISCARD \fIoptional text...\fR
# Claim successful delivery and silently discard the message.
# Log the optional text if specified, otherwise log a generic
diff --git a/postfix/proto/header_checks b/postfix/proto/header_checks
index 736c09e25..97da52b72 100644
--- a/postfix/proto/header_checks
+++ b/postfix/proto/header_checks
@@ -120,6 +120,33 @@
# .fi
# Action names are case insensitive. They are shown in upper case
# for consistency with other Postfix documentation.
+# \" .IP "\fBDELAY \fItime\fR"
+# \" Place the message into the deferred queue, and delay the
+# \" initial delivery attempt by \fItime\fR. The time value may
+# \" be followed by a one-character suffix that specifies the
+# \" time unit: s (seconds), m (minutes), h (hours), d (days),
+# \" w (weeks). The default time unit is s (seconds).
+# \" .sp
+# \" Limitations:
+# \" .RS
+# \" .IP \(bu
+# \" This action affects all the recipients of the message.
+# \" .IP \(bu
+# \" The delay value has no effect with remote file systems that
+# \" don't correctly emulate UNIX local file system semantics.
+# \" In that case, the delay will be half of $queue_run_delay
+# \" on average.
+# \" .IP \(bu
+# \" Mail will still be delivered with "sendmail -q", "postfix
+# \" flush" or "postqueue -f".
+# \" .IP \(bu
+# \" Delayed mail increases the amount of disk I/O during deferred
+# \" queue scans. When large amounts of mail are queued for
+# \" delayed delivery it may be preferable to use the HOLD feature
+# \" instead.
+# \" .RE
+# \" .IP
+# \" This feature is available in Postfix 2.3 and later.
# .IP "\fBDISCARD \fIoptional text...\fR"
# Claim successful delivery and silently discard the message.
# Log the optional text if specified, otherwise log a generic
diff --git a/postfix/src/cleanup/Makefile.in b/postfix/src/cleanup/Makefile.in
index 218c3a481..bb287d094 100644
--- a/postfix/src/cleanup/Makefile.in
+++ b/postfix/src/cleanup/Makefile.in
@@ -412,6 +412,7 @@ cleanup_message.o: ../../include/argv.h
cleanup_message.o: ../../include/attr.h
cleanup_message.o: ../../include/been_here.h
cleanup_message.o: ../../include/cleanup_user.h
+cleanup_message.o: ../../include/conv_time.h
cleanup_message.o: ../../include/dict.h
cleanup_message.o: ../../include/dsn_util.h
cleanup_message.o: ../../include/ext_prop.h
diff --git a/postfix/src/cleanup/cleanup.h b/postfix/src/cleanup/cleanup.h
index f701d3571..04b5bc499 100644
--- a/postfix/src/cleanup/cleanup.h
+++ b/postfix/src/cleanup/cleanup.h
@@ -76,6 +76,9 @@ typedef struct CLEANUP_STATE {
int dsn_notify; /* DSN never/delay/fail/success */
char *dsn_orcpt; /* DSN original recipient */
char *verp_delims; /* VERP delimiters (optional) */
+#ifdef DELAY_ACTION
+ int defer_delay; /* deferred delivery */
+#endif
} CLEANUP_STATE;
/*
diff --git a/postfix/src/cleanup/cleanup_api.c b/postfix/src/cleanup/cleanup_api.c
index 2e6b0756a..4fcaa492f 100644
--- a/postfix/src/cleanup/cleanup_api.c
+++ b/postfix/src/cleanup/cleanup_api.c
@@ -249,13 +249,25 @@ int cleanup_flush(CLEANUP_STATE *state)
* reporting purposes.
*/
if (state->errs == 0 && (state->flags & CLEANUP_FLAG_DISCARD) == 0) {
- if ((state->flags & CLEANUP_FLAG_HOLD) != 0) {
+ if ((state->flags & CLEANUP_FLAG_HOLD) != 0
+#ifdef DELAY_ACTION
+ || state->defer_delay > 0
+#endif
+ ) {
myfree(state->queue_name);
+#ifdef DELAY_ACTION
+ state->queue_name = mystrdup((state->flags & CLEANUP_FLAG_HOLD) ?
+ MAIL_QUEUE_HOLD : MAIL_QUEUE_DEFERRED);
+#else
state->queue_name = mystrdup(MAIL_QUEUE_HOLD);
+#endif
mail_stream_ctl(state->handle,
- MAIL_STREAM_CTL_QUEUE, MAIL_QUEUE_HOLD,
+ MAIL_STREAM_CTL_QUEUE, state->queue_name,
MAIL_STREAM_CTL_CLASS, 0,
MAIL_STREAM_CTL_SERVICE, 0,
+#ifdef DELAY_ACTION
+ MAIL_STREAM_CTL_DELAY, state->defer_delay,
+#endif
MAIL_STREAM_CTL_END);
junk = cleanup_path;
cleanup_path = mystrdup(VSTREAM_PATH(state->handle->stream));
diff --git a/postfix/src/cleanup/cleanup_envelope.c b/postfix/src/cleanup/cleanup_envelope.c
index 002d14f7c..11ec09bc1 100644
--- a/postfix/src/cleanup/cleanup_envelope.c
+++ b/postfix/src/cleanup/cleanup_envelope.c
@@ -118,6 +118,11 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
int mapped_type = type;
const char *mapped_buf = buf;
+#ifdef DELAY_ACTION
+ int defer_delay;
+
+#endif
+
if (msg_verbose)
msg_info("initial envelope %c %.*s", type, (int) len, buf);
@@ -132,6 +137,18 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
return;
}
+#ifdef DELAY_ACTION
+ if (type == REC_TYPE_DELAY) {
+ /* Not part of queue file format. */
+ defer_delay = atoi(buf);
+ if (defer_delay <= 0)
+ msg_warn("%s: ignoring bad delay time: %s", state->queue_id, buf);
+ else
+ state->defer_delay = defer_delay;
+ return;
+ }
+#endif
+
/*
* Map DSN attribute name to pseudo record type so that we don't have to
* pollute the queue file with records that are incompatible with past
diff --git a/postfix/src/cleanup/cleanup_extracted.c b/postfix/src/cleanup/cleanup_extracted.c
index 30ca702d5..0ea738025 100644
--- a/postfix/src/cleanup/cleanup_extracted.c
+++ b/postfix/src/cleanup/cleanup_extracted.c
@@ -105,6 +105,11 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type,
int extra_opts;
int junk;
+#ifdef DELAY_ACTION
+ int defer_delay;
+
+#endif
+
if (msg_verbose)
msg_info("extracted envelope %c %.*s", type, (int) len, buf);
@@ -119,6 +124,18 @@ void cleanup_extracted_process(CLEANUP_STATE *state, int type,
return;
}
+#ifdef DELAY_ACTION
+ if (type == REC_TYPE_DELAY) {
+ /* Not part of queue file format. */
+ defer_delay = atoi(buf);
+ if (defer_delay <= 0)
+ msg_warn("%s: ignoring bad delay time: %s", state->queue_id, buf);
+ else
+ state->defer_delay = defer_delay;
+ return;
+ }
+#endif
+
if (strchr(REC_TYPE_EXTRACT, type) == 0) {
msg_warn("%s: message rejected: "
"unexpected record type %d in extracted envelope",
diff --git a/postfix/src/cleanup/cleanup_message.c b/postfix/src/cleanup/cleanup_message.c
index 751fac5ef..c09764d0f 100644
--- a/postfix/src/cleanup/cleanup_message.c
+++ b/postfix/src/cleanup/cleanup_message.c
@@ -81,6 +81,7 @@
#include
#include
#include
+#include
/* Application-specific. */
@@ -304,6 +305,11 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context,
const char *optional_text = value + strcspn(value, " \t");
int command_len = optional_text - value;
+#ifdef DELAY_ACTION
+ int defer_delay;
+
+#endif
+
while (*optional_text && ISSPACE(*optional_text))
optional_text++;
@@ -357,12 +363,36 @@ static const char *cleanup_act(CLEANUP_STATE *state, char *context,
return (buf);
}
if (STREQUAL(value, "HOLD", command_len)) {
- if ((state->flags & CLEANUP_FLAG_HOLD) == 0) {
+ if ((state->flags & (CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD)) == 0) {
cleanup_act_log(state, "hold", context, buf, optional_text);
state->flags |= CLEANUP_FLAG_HOLD;
}
return (buf);
}
+
+ /*
+ * The DELAY feature is disabled because it has too many problems. 1) It
+ * does not work on some remote file systems; 2) mail will be delivered
+ * anyway with "sendmail -q" etc.; 3) while the mail is queued it bogs
+ * down the deferred queue scan with huge amounts of useless disk I/O
+ * operations.
+ */
+#ifdef DELAY_ACTION
+ if (STREQUAL(value, "DELAY", command_len)) {
+ if ((state->flags & (CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD)) == 0) {
+ if (*optional_text == 0) {
+ msg_warn("missing DELAY argument in %s map", map_class);
+ } else if (conv_time(optional_text, &defer_delay, 's') == 0) {
+ msg_warn("ignoring bad DELAY argument %s in %s map",
+ optional_text, map_class);
+ } else {
+ cleanup_act_log(state, "delay", context, buf, optional_text);
+ state->defer_delay = defer_delay;
+ }
+ }
+ return (buf);
+ }
+#endif
if (STREQUAL(value, "PREPEND", command_len)) {
if (*optional_text == 0) {
msg_warn("PREPEND action without text in %s map", map_class);
@@ -641,7 +671,7 @@ static void cleanup_header_done_callback(void *context)
/*
* XXX 2821: Appendix B: The return address in the MAIL command SHOULD,
* if possible, be derived from the system's identity for the submitting
- * (local) user, and the "From:" header field otherwise. If there is a
+ * (local) user, and the "From:" header field otherwise. If there is a
* system identity available, it SHOULD also be copied to the Sender
* header field if it is different from the address in the From header
* field. (Any Sender field that was already there SHOULD be removed.)
diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in
index a78a4716f..9a9ad6104 100644
--- a/postfix/src/global/Makefile.in
+++ b/postfix/src/global/Makefile.in
@@ -27,7 +27,8 @@ SRCS = abounce.c anvil_clnt.c been_here.c bounce.c bounce_log.c \
ehlo_mask.c \
wildcard_inet_addr.c valid_mailhost_addr.c dsn_util.c dsn_mask.c \
dsn_attr_map.c dsn.c dsn_buf.c rcpt_buf.c rcpt_print.c dsn_print.c \
- dsb_scan.c mail_conf_long.c msg_stats_print.c msg_stats_scan.c
+ dsb_scan.c mail_conf_long.c msg_stats_print.c msg_stats_scan.c \
+ conv_time.c
OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
canon_addr.o cfg_parser.o cleanup_strerror.o cleanup_strflags.o \
clnt_stream.o debug_peer.o debug_process.o defer.o db_common.o \
@@ -56,7 +57,8 @@ OBJS = abounce.o anvil_clnt.o been_here.o bounce.o bounce_log.o \
ehlo_mask.o \
wildcard_inet_addr.o valid_mailhost_addr.o dsn_util.o dsn_mask.o \
dsn_attr_map.o dsn.o dsn_buf.o rcpt_buf.o rcpt_print.o dsn_print.o \
- dsb_scan.o mail_conf_long.o msg_stats_print.o msg_stats_scan.o
+ dsb_scan.o mail_conf_long.o msg_stats_print.o msg_stats_scan.o \
+ conv_time.o
HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
canon_addr.h cfg_parser.h cleanup_user.h clnt_stream.h config.h \
debug_peer.h debug_process.h defer.h deliver_completed.h \
@@ -80,7 +82,7 @@ HDRS = abounce.h anvil_clnt.h been_here.h bounce.h bounce_log.h \
xtext.h scache.h user_acl.h ehlo_mask.h db_common.h \
wildcard_inet_addr.h valid_mailhost_addr.h dsn_util.h dsn_mask.h \
dsn_attr_map.h dsn.h dsn_buf.h rcpt_buf.h rcpt_print.h dsn_print.h \
- dsb_scan.h msg_stats.h
+ dsb_scan.h msg_stats.h conv_time.h
TESTSRC = rec2stream.c stream2rec.c recdump.c
DEFS = -I. -I$(INC_DIR) -D$(SYSTYPE)
CFLAGS = $(DEBUG) $(OPT) $(DEFS)
@@ -545,6 +547,10 @@ clnt_stream.o: clnt_stream.c
clnt_stream.o: clnt_stream.h
clnt_stream.o: mail_params.h
clnt_stream.o: mail_proto.h
+conv_time.o: ../../include/msg.h
+conv_time.o: ../../include/sys_defs.h
+conv_time.o: conv_time.c
+conv_time.o: conv_time.h
db_common.o: ../../include/argv.h
db_common.o: ../../include/dict.h
db_common.o: ../../include/match_list.h
@@ -654,12 +660,61 @@ deliver_request.o: mail_proto.h
deliver_request.o: mail_queue.h
deliver_request.o: msg_stats.h
deliver_request.o: recipient_list.h
+dict_ldap.o: ../../include/argv.h
+dict_ldap.o: ../../include/binhash.h
+dict_ldap.o: ../../include/dict.h
+dict_ldap.o: ../../include/match_list.h
+dict_ldap.o: ../../include/match_ops.h
+dict_ldap.o: ../../include/msg.h
+dict_ldap.o: ../../include/mymalloc.h
+dict_ldap.o: ../../include/stringops.h
dict_ldap.o: ../../include/sys_defs.h
+dict_ldap.o: ../../include/vbuf.h
+dict_ldap.o: ../../include/vstream.h
+dict_ldap.o: ../../include/vstring.h
+dict_ldap.o: cfg_parser.h
+dict_ldap.o: db_common.h
dict_ldap.o: dict_ldap.c
+dict_ldap.o: dict_ldap.h
+dict_ldap.o: string_list.h
+dict_mysql.o: ../../include/argv.h
+dict_mysql.o: ../../include/dict.h
+dict_mysql.o: ../../include/events.h
+dict_mysql.o: ../../include/find_inet.h
+dict_mysql.o: ../../include/match_list.h
+dict_mysql.o: ../../include/match_ops.h
+dict_mysql.o: ../../include/msg.h
+dict_mysql.o: ../../include/mymalloc.h
+dict_mysql.o: ../../include/myrand.h
+dict_mysql.o: ../../include/split_at.h
dict_mysql.o: ../../include/sys_defs.h
+dict_mysql.o: ../../include/vbuf.h
+dict_mysql.o: ../../include/vstream.h
+dict_mysql.o: ../../include/vstring.h
+dict_mysql.o: cfg_parser.h
+dict_mysql.o: db_common.h
dict_mysql.o: dict_mysql.c
+dict_mysql.o: dict_mysql.h
+dict_mysql.o: string_list.h
+dict_pgsql.o: ../../include/argv.h
+dict_pgsql.o: ../../include/dict.h
+dict_pgsql.o: ../../include/events.h
+dict_pgsql.o: ../../include/find_inet.h
+dict_pgsql.o: ../../include/match_list.h
+dict_pgsql.o: ../../include/match_ops.h
+dict_pgsql.o: ../../include/msg.h
+dict_pgsql.o: ../../include/mymalloc.h
+dict_pgsql.o: ../../include/myrand.h
+dict_pgsql.o: ../../include/split_at.h
dict_pgsql.o: ../../include/sys_defs.h
+dict_pgsql.o: ../../include/vbuf.h
+dict_pgsql.o: ../../include/vstream.h
+dict_pgsql.o: ../../include/vstring.h
+dict_pgsql.o: cfg_parser.h
+dict_pgsql.o: db_common.h
dict_pgsql.o: dict_pgsql.c
+dict_pgsql.o: dict_pgsql.h
+dict_pgsql.o: string_list.h
dict_proxy.o: ../../include/argv.h
dict_proxy.o: ../../include/attr.h
dict_proxy.o: ../../include/dict.h
@@ -959,6 +1014,7 @@ mail_conf_time.o: ../../include/sys_defs.h
mail_conf_time.o: ../../include/vbuf.h
mail_conf_time.o: ../../include/vstream.h
mail_conf_time.o: ../../include/vstring.h
+mail_conf_time.o: conv_time.h
mail_conf_time.o: mail_conf.h
mail_conf_time.o: mail_conf_time.c
mail_connect.o: ../../include/attr.h
diff --git a/postfix/src/global/conv_time.c b/postfix/src/global/conv_time.c
new file mode 100644
index 000000000..0640623a3
--- /dev/null
+++ b/postfix/src/global/conv_time.c
@@ -0,0 +1,87 @@
+/*++
+/* NAME
+/* conv_time 3
+/* SUMMARY
+/* time value conversion
+/* SYNOPSIS
+/* #include
+/*
+/* int conv_time(strval, intval, def_unit);
+/* const char *strval;
+/* int *intval;
+/* int def_unit;
+/* DESCRIPTION
+/* conv_time() converts a numerical time value with optional
+/* one-letter suffix that specifies an explicit time unit: s
+/* (seconds), m (minutes), h (hours), d (days) or w (weeks).
+/* Internally, time is represented in seconds.
+/*
+/* Arguments:
+/* .IP strval
+/* Input value.
+/* .IP intval
+/* Result pointer.
+/* .IP def_unit
+/* The default time unit suffix character.
+/* DIAGNOSTICS
+/* The result value is non-zero in case of success, zero in
+/* case of a bad time value or a bad time unit suffix.
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+/* System library. */
+
+#include
+#include /* sscanf() */
+
+/* Utility library. */
+
+#include
+
+/* Global library. */
+
+#include
+
+#define MINUTE (60)
+#define HOUR (60 * MINUTE)
+#define DAY (24 * HOUR)
+#define WEEK (7 * DAY)
+
+/* conv_time - convert time value */
+
+int conv_time(const char *strval, int *intval, int def_unit)
+{
+ char unit;
+ char junk;
+
+ switch (sscanf(strval, "%d%c%c", intval, &unit, &junk)) {
+ case 1:
+ unit = def_unit;
+ case 2:
+ switch (unit) {
+ case 'w':
+ *intval *= WEEK;
+ return (1);
+ case 'd':
+ *intval *= DAY;
+ return (1);
+ case 'h':
+ *intval *= HOUR;
+ return (1);
+ case 'm':
+ *intval *= MINUTE;
+ return (1);
+ case 's':
+ return (1);
+ }
+ }
+ return (0);
+}
diff --git a/postfix/src/global/conv_time.h b/postfix/src/global/conv_time.h
new file mode 100644
index 000000000..565ce3c78
--- /dev/null
+++ b/postfix/src/global/conv_time.h
@@ -0,0 +1,30 @@
+#ifndef _CONV_TIME_INCLUDED_
+#define _CONV_TIME_INCLUDED_
+
+/*++
+/* NAME
+/* conv_time 3h
+/* SUMMARY
+/* time value conversion
+/* SYNOPSIS
+/* #include
+/* DESCRIPTION
+/* .nf
+
+ /*
+ * External interface.
+ */
+extern int conv_time(const char *, int *, int);
+
+/* LICENSE
+/* .ad
+/* .fi
+/* The Secure Mailer license must be distributed with this software.
+/* AUTHOR(S)
+/* Wietse Venema
+/* IBM T.J. Watson Research
+/* P.O. Box 704
+/* Yorktown Heights, NY 10598, USA
+/*--*/
+
+#endif
diff --git a/postfix/src/global/mail_conf_time.c b/postfix/src/global/mail_conf_time.c
index e7c4f0c5a..326d7724c 100644
--- a/postfix/src/global/mail_conf_time.c
+++ b/postfix/src/global/mail_conf_time.c
@@ -82,46 +82,20 @@
/* Global library. */
+#include "conv_time.h"
#include "mail_conf.h"
-#define MINUTE (60)
-#define HOUR (60 * MINUTE)
-#define DAY (24 * HOUR)
-#define WEEK (7 * DAY)
-
/* convert_mail_conf_time - look up and convert integer parameter value */
static int convert_mail_conf_time(const char *name, int *intval, int def_unit)
{
const char *strval;
- char unit;
- char junk;
if ((strval = mail_conf_lookup_eval(name)) == 0)
return (0);
-
- switch (sscanf(strval, "%d%c%c", intval, &unit, &junk)) {
- case 1:
- unit = def_unit;
- case 2:
- switch (unit) {
- case 'w':
- *intval *= WEEK;
- return (1);
- case 'd':
- *intval *= DAY;
- return (1);
- case 'h':
- *intval *= HOUR;
- return (1);
- case 'm':
- *intval *= MINUTE;
- return (1);
- case 's':
- return (1);
- }
- }
- msg_fatal("parameter %s: bad time unit: %s", name, strval);
+ if (conv_time(strval, intval, def_unit) == 0)
+ msg_fatal("parameter %s: bad time unit: %s", name, strval);
+ return (1);
}
/* check_mail_conf_time - validate integer value */
diff --git a/postfix/src/global/mail_stream.c b/postfix/src/global/mail_stream.c
index 1039bddc5..e7e43e1ff 100644
--- a/postfix/src/global/mail_stream.c
+++ b/postfix/src/global/mail_stream.c
@@ -91,6 +91,11 @@
/* .IP "MAIL_STREAM_CTL_MODE (int)"
/* The argument specifies alternate permissions that override
/* the permissions specified with mail_stream_file().
+/* .IP "MAIL_STREAM_CTL_DELAY (int)"
+/* Attempt to postpone initial delivery by advancing the queue
+/* file modification time stamp by this amount. This has
+/* effect only within the deferred mail queue.
+/* This feature may have no effect with remote file systems.
/* LICENSE
/* .ad
/* .fi
@@ -186,11 +191,34 @@ static int mail_stream_finish_file(MAIL_STREAM *info, VSTRING *unused_why)
* This clock drift detection code may not work with file systems that work
* on a local copy of the file and that update the server only after the
* file is closed.
+ *
+ * Optionally set a cooldown time.
+ *
+ * XXX: We assume that utime() does control the file modification time even
+ * when followed by an fchmod(), fsync(), close() sequence. This may fail
+ * with remote file systems when fsync() actually updates the file. Even
+ * then, we still delay the average message by 1/2 of the
+ * queue_run_delay.
+ *
+ * XXX: Victor does not like running utime() after the close(), since this
+ * creates a race even with local filesystems. But Wietse is not
+ * confident that utime() before fsync() and close() will work reliably
+ * with remote file systems.
*/
check_incoming_fs_clock =
(!incoming_fs_clock_ok && !strcmp(info->queue, MAIL_QUEUE_INCOMING));
+#ifdef DELAY_ACTION
+ if (strcmp(info->queue, MAIL_QUEUE_DEFERRED) != 0)
+ info->delay = 0;
+ if (info->delay > 0)
+ tbuf.actime = tbuf.modtime = time(&now) + info->delay;
+#endif
+
if (vstream_fflush(info->stream)
+#ifdef DELAY_ACTION
+ || (info->delay > 0 && utime(VSTREAM_PATH(info->stream), &tbuf))
+#endif
|| fchmod(vstream_fileno(info->stream), 0700 | info->mode)
#ifdef HAS_FSYNC
|| fsync(vstream_fileno(info->stream))
@@ -314,6 +342,9 @@ MAIL_STREAM *mail_stream_file(const char *queue, const char *class,
info->class = mystrdup(class);
info->service = mystrdup(service);
info->mode = mode;
+#ifdef DELAY_ACTION
+ info->delay = 0;
+#endif
info->ctime = tv;
return (info);
}
@@ -452,6 +483,16 @@ void mail_stream_ctl(MAIL_STREAM *info, int op,...)
info->mode = va_arg(ap, int);
break;
+ /*
+ * Advance the (finished) file modification time.
+ */
+#ifdef DELAY_ACTION
+ case MAIL_STREAM_CTL_DELAY:
+ if ((info->delay = va_arg(ap, int)) < 0)
+ msg_panic("%s: bad delay time %d", myname, info->delay);
+ break;
+#endif
+
default:
msg_panic("%s: bad op code %d", myname, op);
}
diff --git a/postfix/src/global/mail_stream.h b/postfix/src/global/mail_stream.h
index cee04bc86..a8e73032e 100644
--- a/postfix/src/global/mail_stream.h
+++ b/postfix/src/global/mail_stream.h
@@ -39,6 +39,9 @@ struct MAIL_STREAM {
char *class; /* trigger class */
char *service; /* trigger service */
int mode; /* additional permissions */
+#ifdef DELAY_ACTION
+ int delay; /* deferred delivery */
+#endif
struct timeval ctime; /* creation time */
};
@@ -47,13 +50,16 @@ struct MAIL_STREAM {
#define MAIL_STREAM_CTL_CLASS 2 /* Change notification class */
#define MAIL_STREAM_CTL_SERVICE 3 /* Change notification service */
#define MAIL_STREAM_CTL_MODE 4 /* Change final queue file mode */
+#ifdef DELAY_ACTION
+#define MAIL_STREAM_CTL_DELAY 5 /* Change final queue file mtime */
+#endif
extern MAIL_STREAM *mail_stream_file(const char *, const char *, const char *, int);
extern MAIL_STREAM *mail_stream_service(const char *, const char *);
extern MAIL_STREAM *mail_stream_command(const char *);
extern void mail_stream_cleanup(MAIL_STREAM *);
extern int mail_stream_finish(MAIL_STREAM *, VSTRING *);
-extern void mail_stream_ctl(MAIL_STREAM *, int, ...);
+extern void mail_stream_ctl(MAIL_STREAM *, int,...);
/* LICENSE
diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h
index 9ddaf21a2..08a7f541d 100644
--- a/postfix/src/global/mail_version.h
+++ b/postfix/src/global/mail_version.h
@@ -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 "20051128"
+#define MAIL_RELEASE_DATE "20051202"
#define MAIL_VERSION_NUMBER "2.3"
#ifdef SNAPSHOT
diff --git a/postfix/src/global/rec_type.h b/postfix/src/global/rec_type.h
index 106c87ef7..4e1b83bc7 100644
--- a/postfix/src/global/rec_type.h
+++ b/postfix/src/global/rec_type.h
@@ -43,6 +43,7 @@
#define REC_TYPE_RDR '>' /* redirect target */
#define REC_TYPE_FLGS 'f' /* cleanup processing flags */
+#define REC_TYPE_DELAY 'd' /* cleanup delay upon arrival */
#define REC_TYPE_MESG 'M' /* start message records */
diff --git a/postfix/src/lmtp/lmtp.c b/postfix/src/lmtp/lmtp.c
index fc252aebd..2af07f753 100644
--- a/postfix/src/lmtp/lmtp.c
+++ b/postfix/src/lmtp/lmtp.c
@@ -376,7 +376,8 @@ static int deliver_message(DELIVER_REQUEST *request, char **unused_argv)
* Disconnect if RSET can't be sent over an existing connection.
* Discard transcript and status information for sending RSET.
*/
- else if (lmtp_rset(state) != 0) {
+ else if (lmtp_rset(state) != 0
+ || (state->features & LMTP_FEATURE_RSET_REJECTED) != 0) {
lmtp_chat_reset(state);
state->session = lmtp_session_free(state->session);
#ifdef USE_SASL_AUTH
diff --git a/postfix/src/lmtp/lmtp.h b/postfix/src/lmtp/lmtp.h
index 22b84f72c..aa4407220 100644
--- a/postfix/src/lmtp/lmtp.h
+++ b/postfix/src/lmtp/lmtp.h
@@ -69,6 +69,7 @@ typedef struct LMTP_STATE {
#define LMTP_FEATURE_XFORWARD_HELO (1<<9)
#define LMTP_FEATURE_XFORWARD_DOMAIN (1<<10)
#define LMTP_FEATURE_DSN (1<<11)
+#define LMTP_FEATURE_RSET_REJECTED (1<<12)
/*
* lmtp.c
diff --git a/postfix/src/lmtp/lmtp_chat.c b/postfix/src/lmtp/lmtp_chat.c
index 621d17d89..4abb0d664 100644
--- a/postfix/src/lmtp/lmtp_chat.c
+++ b/postfix/src/lmtp/lmtp_chat.c
@@ -242,7 +242,7 @@ LMTP_RESP *lmtp_chat_resp(LMTP_STATE *state)
*/
state->error_mask |= MAIL_ERROR_PROTOCOL;
if (state->features & LMTP_FEATURE_PIPELINING) {
- msg_warn("non-SMTP response from %s: %s",
+ msg_warn("non-LMTP response from %s: %.100s",
session->namaddr, STR(state->buffer));
vstream_longjmp(session->stream, SMTP_ERR_PROTO);
}
diff --git a/postfix/src/lmtp/lmtp_proto.c b/postfix/src/lmtp/lmtp_proto.c
index 40eb6cbdd..d051c5331 100644
--- a/postfix/src/lmtp/lmtp_proto.c
+++ b/postfix/src/lmtp/lmtp_proto.c
@@ -31,6 +31,7 @@
/* accordingly.
/*
/* lmtp_rset() sends a lone RSET command and waits for the response.
+/* In case of a negative reply it sets the CANT_RSET_THIS_SESSION flag.
/*
/* lmtp_quit() sends a lone QUIT command and waits for the response
/* only if waiting for QUIT replies is enabled.
@@ -359,6 +360,9 @@ static int lmtp_loop(LMTP_STATE *state, NOCLOBBER int send_state,
#define SENDING_MAIL \
(recv_state <= LMTP_STATE_DOT)
+#define CANT_RSET_THIS_SESSION \
+ (state->features |= LMTP_FEATURE_RSET_REJECTED)
+
/*
* Pipelining support requires two loops: one loop for sending and one
* for receiving. Each loop has its own independent state. Most of the
@@ -751,6 +755,8 @@ static int lmtp_loop(LMTP_STATE *state, NOCLOBBER int send_state,
* Ignore the RSET response.
*/
case LMTP_STATE_RSET:
+ if (resp->code / 100 != 2)
+ CANT_RSET_THIS_SESSION;
recv_state = LMTP_STATE_LAST;
break;
diff --git a/postfix/src/pickup/pickup.c b/postfix/src/pickup/pickup.c
index 29b7bb25a..0a73ec66f 100644
--- a/postfix/src/pickup/pickup.c
+++ b/postfix/src/pickup/pickup.c
@@ -203,6 +203,8 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info,
int time_seen = 0;
char *attr_name;
char *attr_value;
+ char *saved_attr;
+ int skip_attr;
/*
* Limit the input record size. All front-end programs should protect the
@@ -254,12 +256,16 @@ static int copy_segment(VSTREAM *qfile, VSTREAM *cleanup, PICKUP_INFO *info,
if (type == REC_TYPE_ERTO)
/* Discard errors-to record after "postsuper -r". */
continue;
- if (type == REC_TYPE_ATTR
- && split_nameval(vstring_str(buf),
- &attr_name, &attr_value) == 0
- && dsn_attr_map(attr_name) == 0)
+ if (type == REC_TYPE_ATTR) {
+ saved_attr = mystrdup(vstring_str(buf));
+ skip_attr = (split_nameval(saved_attr,
+ &attr_name, &attr_value) == 0
+ && dsn_attr_map(attr_name) == 0);
+ myfree(saved_attr);
/* Discard other/header/body action after "postsuper -r". */
- continue;
+ if (skip_attr)
+ continue;
+ }
}
/*
diff --git a/postfix/src/qmqpd/qmqpd_peer.c b/postfix/src/qmqpd/qmqpd_peer.c
index 332c94f06..e05e77c8e 100644
--- a/postfix/src/qmqpd/qmqpd_peer.c
+++ b/postfix/src/qmqpd/qmqpd_peer.c
@@ -62,6 +62,7 @@
#include
#include
+#include
/* Application-specific. */
@@ -106,6 +107,17 @@ void qmqpd_peer_init(QMQPD_STATE *state)
int aierr;
char *colonp;
+ /*
+ * Sorry, but there are some things that we just cannot do while
+ * connected to the network.
+ */
+ if (geteuid() != var_owner_uid || getuid() != var_owner_uid) {
+ msg_error("incorrect QMQP server privileges: uid=%lu euid=%lu",
+ (unsigned long) getuid(), (unsigned long) geteuid());
+ msg_fatal("the Postfix QMQP server must run with $%s privileges",
+ VAR_MAIL_OWNER);
+ }
+
/*
* Convert the client address to printable form.
*/
diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in
index 78010673d..6b42681f9 100644
--- a/postfix/src/smtpd/Makefile.in
+++ b/postfix/src/smtpd/Makefile.in
@@ -208,6 +208,7 @@ smtpd_check.o: ../../include/argv.h
smtpd_check.o: ../../include/attr.h
smtpd_check.o: ../../include/attr_clnt.h
smtpd_check.o: ../../include/cleanup_user.h
+smtpd_check.o: ../../include/conv_time.h
smtpd_check.o: ../../include/ctable.h
smtpd_check.o: ../../include/deliver_request.h
smtpd_check.o: ../../include/dict.h
diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c
index 952722ae5..6cdeb3a8b 100644
--- a/postfix/src/smtpd/smtpd.c
+++ b/postfix/src/smtpd/smtpd.c
@@ -1742,6 +1742,9 @@ static void mail_reset(SMTPD_STATE *state)
state->saved_redirect = 0;
}
state->saved_flags = 0;
+#ifdef DELAY_ACTION
+ state->saved_delay = 0;
+#endif
#ifdef USE_SASL_AUTH
if (var_smtpd_sasl_enable)
smtpd_sasl_mail_reset(state);
@@ -2314,6 +2317,11 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
if (state->saved_flags)
rec_fprintf(state->cleanup, REC_TYPE_FLGS, "%d",
state->saved_flags);
+#ifdef DELAY_ACTION
+ if (state->saved_delay)
+ rec_fprintf(state->cleanup, REC_TYPE_DELAY, "%d",
+ state->saved_delay);
+#endif
if (vstream_ferror(state->cleanup))
state->err = CLEANUP_STAT_WRITE;
}
diff --git a/postfix/src/smtpd/smtpd.h b/postfix/src/smtpd/smtpd.h
index 6dac74262..cb061f416 100644
--- a/postfix/src/smtpd/smtpd.h
+++ b/postfix/src/smtpd/smtpd.h
@@ -140,6 +140,9 @@ typedef struct SMTPD_STATE {
char *saved_filter; /* postponed filter action */
char *saved_redirect; /* postponed redirect action */
int saved_flags; /* postponed hold/discard */
+#ifdef DELAY_ACTION
+ int saved_delay; /* postponed deferred delay */
+#endif
VSTRING *expand_buf; /* scratch space for $name expansion */
ARGV *prepend; /* prepended headers */
VSTRING *instance; /* policy query correlation */
diff --git a/postfix/src/smtpd/smtpd_check.c b/postfix/src/smtpd/smtpd_check.c
index 8910cd905..86e2c4df0 100644
--- a/postfix/src/smtpd/smtpd_check.c
+++ b/postfix/src/smtpd/smtpd_check.c
@@ -236,6 +236,7 @@
#include
#include
#include
+#include
/* Application-specific. */
@@ -1895,6 +1896,11 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
static char def_dsn[] = "5.7.1";
DSN_SPLIT dp;
+#ifdef DELAY_ACTION
+ int defer_delay;
+
+#endif
+
/*
* Parse into command and text. Do not change the input.
*/
@@ -1984,6 +1990,41 @@ static int check_table_result(SMTPD_STATE *state, const char *table,
return (SMTPD_CHECK_DUNNO);
}
+ /*
+ * DELAY means deliver later. But we may still change our mind, and
+ * reject/discard the message for other reasons.
+ *
+ * This feature is deleted because it has too many problems. 1) It does not
+ * work on some remote file systems; 2) mail will be delivered anyway
+ * with "sendmail -q" etc.; 3) while the mail is queued it bogs down the
+ * deferred queue scan with huge amounts of useless disk I/O operations.
+ */
+#ifdef DELAY_ACTION
+ if (STREQUAL(value, "DELAY", cmd_len)) {
+#ifndef TEST
+ if (can_delegate_action(state, table, "DELAY", reply_class) == 0)
+ return (SMTPD_CHECK_DUNNO);
+#endif
+ if (*cmd_text == 0) {
+ msg_warn("access table %s entry \"%s\" has DELAY entry without value",
+ table, datum);
+ return (SMTPD_CHECK_DUNNO);
+ }
+ if (conv_time(cmd_text, &defer_delay, 's') == 0) {
+ msg_warn("access table %s entry \"%s\" has invalid DELAY argument \"%s\"",
+ table, datum, cmd_text);
+ return (SMTPD_CHECK_DUNNO);
+ }
+ vstring_sprintf(error_text, "<%s>: %s %s", reply_name, reply_class,
+ *cmd_text ? cmd_text : "triggers DELAY action");
+ log_whatsup(state, "delay", STR(error_text));
+#ifndef TEST
+ state->saved_delay = defer_delay;
+#endif
+ return (SMTPD_CHECK_DUNNO);
+ }
+#endif
+
/*
* DISCARD means silently discard and claim successful delivery.
*/
@@ -3157,7 +3198,6 @@ static int reject_auth_sender_login_mismatch(SMTPD_STATE *state, const char *sen
static int reject_unauth_sender_login_mismatch(SMTPD_STATE *state, const char *sender)
{
const RESOLVE_REPLY *reply;
- const char *login = 0;
/*
* Reject if the client is not logged in and the sender address has an
diff --git a/postfix/src/smtpd/smtpd_peer.c b/postfix/src/smtpd/smtpd_peer.c
index 473577f59..034f9cefe 100644
--- a/postfix/src/smtpd/smtpd_peer.c
+++ b/postfix/src/smtpd/smtpd_peer.c
@@ -165,6 +165,17 @@ void smtpd_peer_init(SMTPD_STATE *state)
int aierr;
char *colonp;
+ /*
+ * Sorry, but there are some things that we just cannot do while
+ * connected to the network.
+ */
+ if (geteuid() != var_owner_uid || getuid() != var_owner_uid) {
+ msg_error("incorrect SMTP server privileges: uid=%lu euid=%lu",
+ (unsigned long) getuid(), (unsigned long) geteuid());
+ msg_fatal("the Postfix SMTP server must run with $%s privileges",
+ VAR_MAIL_OWNER);
+ }
+
/*
* Convert the client address to printable form.
*/
diff --git a/postfix/src/smtpd/smtpd_state.c b/postfix/src/smtpd/smtpd_state.c
index bd443f0bd..184dafc27 100644
--- a/postfix/src/smtpd/smtpd_state.c
+++ b/postfix/src/smtpd/smtpd_state.c
@@ -123,6 +123,9 @@ void smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream,
state->saved_filter = 0;
state->saved_redirect = 0;
state->saved_flags = 0;
+#ifdef DELAY_ACTION
+ state->saved_delay = 0;
+#endif
state->instance = vstring_alloc(10);
state->seqno = 0;
state->rewrite_context = 0;