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;