From: Wietse Venema Date: Mon, 26 Nov 2001 05:00:00 +0000 (-0500) Subject: snapshot-20011126 X-Git-Tag: v1.1.0~22 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=4528dca4bcbb3ddd5a2c3b2ff730ba8ba6274f38;p=thirdparty%2Fpostfix.git snapshot-20011126 --- diff --git a/postfix/HISTORY b/postfix/HISTORY index 89100032f..7ab7c2bd2 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -5690,6 +5690,21 @@ Apologies for any names omitted. file so people can keep track of the difference between the Postfix LMTP client and the non-Postfix LMTP server. +20011126 + + Feature: smtpd_noop_commands specifies a list of commands + that are treated as NOOP (no operation) commands, without + syntax check or state change. File: smtpd/smtpd.c. + + Bugfix: the "mark queue file as corrupt" code did not work + because it was never used. Files: global/mark_corrupt.c, + global/mail_copy.c, global/pipe_command.c, *qmgr/qmgr_active.c, + local/maildir.c, local/mailbox.c, local/command.c, pipe/pipe.c, + virtual/mailbox.c, virtual/maildir.c. + + Bugfix: the bounce daemon broke in case of a non-existing + message queue file. File: bounce/bounce_notify_util.c. + Open problems: Medium: need in-process caching for map lookups. LDAP diff --git a/postfix/conf/sample-smtpd.cf b/postfix/conf/sample-smtpd.cf index 524ca22d1..4a5ec1995 100644 --- a/postfix/conf/sample-smtpd.cf +++ b/postfix/conf/sample-smtpd.cf @@ -77,6 +77,13 @@ smtpd_banner = $myhostname ESMTP $mail_name # warn_if_reject: next restriction logs a warning instead of rejecting. smtpd_etrn_restrictions = +# The smtpd_noop_commands parameter specifies a list of commands that +# the Postfix SMTP server replies to with "250 Ok", without doing any +# syntax checks and without changing state. This list overrides any +# commands built into the Postfix SMTP server. +# +smtpd_noop_commands = + # The smtpd_recipient_limit parameter restricts the number of recipients # that the SMTP server accepts per message delivery. # diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index eb8779b9a..96fa20b5f 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -75,10 +75,16 @@ SMTPD(8) SMTPD(8) same syntax as the right-hand side of a Postfix transport table. + smtpd_noop_commands + List of commands that are treated as NOOP (no oper- + ation) commands without any parameter syntax check- + ing. This list overrides built-in command defini- + tions. + Authentication controls enable_sasl_authentication - Enable per-session authentication as per RFC 2554 - (SASL). This functionality is available only when + Enable per-session authentication as per RFC 2554 + (SASL). This functionality is available only when explicitly selected at program build time and explicitly enabled at runtime. @@ -104,14 +110,14 @@ SMTPD(8) SMTPD(8) Disallow anonymous logins. smtpd_sender_login_maps - Maps that specify the SASL login name that owns a - MAIL FROM sender address. Used by the + Maps that specify the SASL login name that owns a + MAIL FROM sender address. Used by the reject_sender_login_mismatch sender anti-spoofing restriction. Miscellaneous always_bcc - Address to send a copy of each message that enters + Address to send a copy of each message that enters the system. command_directory @@ -119,71 +125,71 @@ SMTPD(8) SMTPD(8) $program_directory). debug_peer_level - Increment in verbose logging level when a remote + Increment in verbose logging level when a remote host matches a pattern in the debug_peer_list parameter. debug_peer_list - List of domain or network patterns. When a remote - host matches a pattern, increase the verbose log- - ging level by the amount specified in the + List of domain or network patterns. When a remote + host matches a pattern, increase the verbose log- + ging level by the amount specified in the debug_peer_level parameter. default_verp_delimiters The default VERP delimiter characters that are used - when the XVERP command is specified without + when the XVERP command is specified without explicit delimiters. error_notice_recipient - Recipient of protocol/policy/resource/software + Recipient of protocol/policy/resource/software error notices. hopcount_limit Limit the number of Received: message headers. local_recipient_maps - List of maps with user names that are local to + List of maps with user names that are local to $myorigin or $inet_interfaces. If this parameter is - defined, then the SMTP server rejects mail for + defined, then the SMTP server rejects mail for unknown local users. notify_classes List of error classes. Of special interest are: - policy When a client violates any policy, mail a + policy When a client violates any policy, mail a transcript of the entire SMTP session to the postmaster. protocol - When a client violates the SMTP protocol or + When a client violates the SMTP protocol or issues an unimplemented command, mail a transcript of the entire SMTP session to the postmaster. smtpd_banner - Text that follows the 220 status code in the SMTP + Text that follows the 220 status code in the SMTP greeting banner. smtpd_recipient_limit - Restrict the number of recipients that the SMTP + Restrict the number of recipients that the SMTP server accepts per message delivery. smtpd_timeout - Limit the time to send a server response and to + Limit the time to send a server response and to receive a client request. soft_bounce - Change hard (5xx) reject responses into soft (4xx) - reject responses. This can be useful for testing + Change hard (5xx) reject responses into soft (4xx) + reject responses. This can be useful for testing purposes. verp_delimiter_filter - The characters that Postfix accepts as VERP delim- + The characters that Postfix accepts as VERP delim- iter characters. Resource controls line_length_limit - Limit the amount of memory in bytes used for the + Limit the amount of memory in bytes used for the handling of partial input lines. message_size_limit @@ -191,8 +197,8 @@ SMTPD(8) SMTPD(8) ing on-disk storage for envelope information. queue_minfree - Minimal amount of free space in bytes in the queue - file system for the SMTP server to accept any mail + Minimal amount of free space in bytes in the queue + file system for the SMTP server to accept any mail at all. Tarpitting @@ -202,22 +208,22 @@ SMTPD(8) SMTPD(8) smtpd_soft_error_limit When an SMTP client has made this number of errors, - wait error_count seconds before responding to any + wait error_count seconds before responding to any client request. smtpd_hard_error_limit - Disconnect after a client has made this number of + Disconnect after a client has made this number of errors. smtpd_junk_command_limit Limit the number of times a client can issue a junk - command such as NOOP, VRFY, ETRN or RSET in one - SMTP session before it is penalized with tarpit + command such as NOOP, VRFY, ETRN or RSET in one + SMTP session before it is penalized with tarpit delays. UCE control restrictions parent_domain_matches_subdomains (versions >= 20011119) - List of Postfix features that use domain.name pat- + List of Postfix features that use domain.name pat- terns to match sub.domain.name (as opposed to requiring .domain.name patterns). @@ -226,19 +232,19 @@ SMTPD(8) SMTPD(8) tem. smtpd_helo_required - Require that clients introduce themselves at the + Require that clients introduce themselves at the beginning of an SMTP session. smtpd_helo_restrictions - Restrict what client hostnames are allowed in HELO + Restrict what client hostnames are allowed in HELO and EHLO commands. smtpd_sender_restrictions - Restrict what sender addresses are allowed in MAIL + Restrict what sender addresses are allowed in MAIL FROM commands. smtpd_recipient_restrictions - Restrict what recipient addresses are allowed in + Restrict what recipient addresses are allowed in RCPT TO commands. smtpd_etrn_restrictions @@ -246,62 +252,62 @@ SMTPD(8) SMTPD(8) mands, and what clients may issue ETRN commands. allow_untrusted_routing - Allow untrusted clients to specify addresses with - sender-specified routing. Enabling this opens up - nasty relay loopholes involving trusted backup MX + Allow untrusted clients to specify addresses with + sender-specified routing. Enabling this opens up + nasty relay loopholes involving trusted backup MX hosts. smtpd_restriction_classes - Declares the name of zero or more parameters that - contain a list of UCE restrictions. The names of - these parameters can then be used instead of the + Declares the name of zero or more parameters that + contain a list of UCE restrictions. The names of + these parameters can then be used instead of the restriction lists that they represent. maps_rbl_domains - List of DNS domains that publish the addresses of + List of DNS domains that publish the addresses of blacklisted hosts. permit_mx_backup_networks - Only domains whose primary MX hosts match the - listed networks are eligible for the per- + Only domains whose primary MX hosts match the + listed networks are eligible for the per- mit_mx_backup feature. relay_domains - Restrict what domains or networks this mail system + Restrict what domains or networks this mail system will relay mail from or to. UCE control responses access_map_reject_code - Server response when a client violates an access + Server response when a client violates an access database restriction. invalid_hostname_reject_code - Server response when a client violates the + Server response when a client violates the reject_invalid_hostname restriction. maps_rbl_reject_code - Server response when a client violates the + Server response when a client violates the maps_rbl_domains restriction. reject_code - Response code when the client matches a reject + Response code when the client matches a reject restriction. relay_domains_reject_code - Server response when a client attempts to violate + Server response when a client attempts to violate the mail relay policy. unknown_address_reject_code - Server response when a client violates the + Server response when a client violates the reject_unknown_address restriction. unknown_client_reject_code - Server response when a client without address to - name mapping violates the reject_unknown_clients + Server response when a client without address to + name mapping violates the reject_unknown_clients restriction. unknown_hostname_reject_code - Server response when a client violates the + Server response when a client violates the reject_unknown_hostname restriction. SEE ALSO @@ -310,7 +316,7 @@ SMTPD(8) SMTPD(8) syslogd(8) system logging LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) diff --git a/postfix/html/uce.html b/postfix/html/uce.html index 72fea6be0..663dfe392 100644 --- a/postfix/html/uce.html +++ b/postfix/html/uce.html @@ -546,13 +546,14 @@ response code to rejected requests (default: 504). -
reject_sender_login_mismatch
Reject the request -when $smtpd_sender_owner_maps -specifies an owner for the MAIL FROM address, but the client is -not (SASL) logged in as that MAIL FROM address owner; or when the -client is (SASL) logged in, but the client login name doesn't own -the MAIL FROM address according to -$smtpd_sender_login_maps. +
reject_sender_login_mismatch (Postfix versions >= 20011125) + +
Reject the request when +$smtpd_sender_owner_maps specifies an owner for the MAIL FROM +address, but the client is not (SASL) logged in as that MAIL FROM +address owner; or when the client is (SASL) logged in, but the +client login name doesn't own the MAIL FROM address according to + $smtpd_sender_login_maps.

diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index 74c72b186..257d12554 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -82,6 +82,10 @@ The name of a mail delivery transport that filters mail and that either bounces mail or re-injects the result back into Postfix. This parameter uses the same syntax as the right-hand side of a Postfix transport table. +.IP \fBsmtpd_noop_commands\fR +List of commands that are treated as NOOP (no operation) commands +without any parameter syntax checking. This list overrides built-in +command definitions. .SH "Authentication controls" .IP \fBenable_sasl_authentication\fR Enable per-session authentication as per RFC 2554 (SASL). diff --git a/postfix/src/bounce/bounce_notify_util.c b/postfix/src/bounce/bounce_notify_util.c index 599d516f8..f2dc04156 100644 --- a/postfix/src/bounce/bounce_notify_util.c +++ b/postfix/src/bounce/bounce_notify_util.c @@ -222,14 +222,16 @@ BOUNCE_INFO *bounce_mail_init(const char *service, const char *queue_name, * corrupted just send whatever we can (remember this is a best effort, * it does not have to be perfect). */ - while ((rec_type = rec_get(bounce_info->orig_fp, - bounce_info->buf, 0)) > 0) { - if (rec_type == REC_TYPE_TIME && bounce_info->arrival_time == 0) { - if ((bounce_info->arrival_time = atol(STR(bounce_info->buf))) < 0) - bounce_info->arrival_time = 0; - } else if (rec_type == REC_TYPE_MESG) { - bounce_info->orig_offs = vstream_ftell(bounce_info->orig_fp); - break; + if (bounce_info->orig_fp != 0) { + while ((rec_type = rec_get(bounce_info->orig_fp, + bounce_info->buf, 0)) > 0) { + if (rec_type == REC_TYPE_TIME && bounce_info->arrival_time == 0) { + if ((bounce_info->arrival_time = atol(STR(bounce_info->buf))) < 0) + bounce_info->arrival_time = 0; + } else if (rec_type == REC_TYPE_MESG) { + bounce_info->orig_offs = vstream_ftell(bounce_info->orig_fp); + break; + } } } return (bounce_info); diff --git a/postfix/src/global/Makefile.in b/postfix/src/global/Makefile.in index 92773fe68..6ce1247a6 100644 --- a/postfix/src/global/Makefile.in +++ b/postfix/src/global/Makefile.in @@ -722,8 +722,12 @@ mark_corrupt.o: ../../include/sys_defs.h mark_corrupt.o: ../../include/msg.h mark_corrupt.o: ../../include/vstream.h mark_corrupt.o: ../../include/vbuf.h +mark_corrupt.o: ../../include/set_eugid.h mark_corrupt.o: mail_queue.h mark_corrupt.o: ../../include/vstring.h +mark_corrupt.o: mail_params.h +mark_corrupt.o: deliver_request.h +mark_corrupt.o: recipient_list.h mark_corrupt.o: mark_corrupt.h match_parent_style.o: match_parent_style.c match_parent_style.o: ../../include/sys_defs.h diff --git a/postfix/src/global/deliver_request.h b/postfix/src/global/deliver_request.h index 2406085ff..e7cb43356 100644 --- a/postfix/src/global/deliver_request.h +++ b/postfix/src/global/deliver_request.h @@ -41,6 +41,10 @@ typedef struct DELIVER_REQUEST { char *hop_status; /* reason if unavailable */ } DELIVER_REQUEST; +#define DEL_STAT_OK (0) /* success including bounced */ +#define DEL_STAT_DEFER (-1) /* deferred */ +#define DEL_STAT_CORRUPT (-1) /* corrupt */ + #define DEL_REQ_FLAG_DEFLT (DEL_REQ_FLAG_SUCCESS | DEL_REQ_FLAG_BOUNCE) #define DEL_REQ_FLAG_SUCCESS (1<<0) /* delete successful recipients */ #define DEL_REQ_FLAG_BOUNCE (1<<1) /* unimplemented */ diff --git a/postfix/src/global/mail_copy.c b/postfix/src/global/mail_copy.c index e08d301f5..8156cd88e 100644 --- a/postfix/src/global/mail_copy.c +++ b/postfix/src/global/mail_copy.c @@ -62,6 +62,14 @@ /* DIAGNOSTICS /* A non-zero result means the operation failed. Warnings: corrupt /* message file. A corrupt message is marked as corrupt. +/* +/* The result is the bit-wise OR of zero or more of the following: +/* .IP MAIL_COPY_STAT_CORRUPT +/* The queue file is marked as corrupt. +/* .IP MAIL_COPY_STAT_READ +/* A read error was detected; errno specifies the nature of the problem. +/* .IP MAIL_COPY_STAT_WRITE +/* A write error was detected; errno specifies the nature of the problem. /* SEE ALSO /* mark_corrupt(3), mark queue file as corrupted. /* LICENSE @@ -81,6 +89,7 @@ #include #include #include +#include /* Utility library. */ @@ -210,7 +219,7 @@ int mail_copy(const char *sender, const char *delivered, #endif #ifndef NO_TRUNCATE if ((flags & MAIL_COPY_TOFILE) != 0) - if (read_error || write_error) + if (corrupt_error || read_error || write_error) ftruncate(vstream_fileno(dst), (off_t) orig_length); #endif write_error |= vstream_fclose(dst); @@ -218,5 +227,7 @@ int mail_copy(const char *sender, const char *delivered, vstring_sprintf(why, "error reading message: %m"); if (why && write_error) vstring_sprintf(why, "error writing message: %m"); - return (corrupt_error || read_error || write_error); + return ((corrupt_error ? MAIL_COPY_STAT_CORRUPT : 0) + | (read_error ? MAIL_COPY_STAT_READ : 0) + | (write_error ? MAIL_COPY_STAT_WRITE : 0)); } diff --git a/postfix/src/global/mail_copy.h b/postfix/src/global/mail_copy.h index 2d8c6ae39..efa1957c5 100644 --- a/postfix/src/global/mail_copy.h +++ b/postfix/src/global/mail_copy.h @@ -35,6 +35,11 @@ extern int mail_copy(const char *, const char *, VSTREAM *, VSTREAM *, MAIL_COPY_RETURN_PATH | MAIL_COPY_BLANK) #define MAIL_COPY_NONE 0 /* all turned off */ +#define MAIL_COPY_STAT_OK 0 +#define MAIL_COPY_STAT_CORRUPT (1<<0) +#define MAIL_COPY_STAT_READ (1<<1) +#define MAIL_COPY_STAT_WRITE (1<<2) + /* LICENSE /* .ad /* .fi diff --git a/postfix/src/global/mail_params.h b/postfix/src/global/mail_params.h index 2091f0ab3..26248bdf7 100644 --- a/postfix/src/global/mail_params.h +++ b/postfix/src/global/mail_params.h @@ -766,6 +766,10 @@ extern int var_smtpd_err_sleep; #define DEF_SMTPD_JUNK_CMD 1000 extern int var_smtpd_junk_cmd_limit; +#define VAR_SMTPD_NOOP_CMDS "smtpd_noop_commands" +#define DEF_SMTPD_NOOP_CMDS "" +extern char *var_smtpd_noop_cmds; + /* * SASL authentication support, SMTP server side. */ diff --git a/postfix/src/global/mail_version.h b/postfix/src/global/mail_version.h index 924dd1e86..9fa31ea5e 100644 --- a/postfix/src/global/mail_version.h +++ b/postfix/src/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Snapshot-20011125" +#define DEF_MAIL_VERSION "Snapshot-20011126" extern char *var_mail_version; /* LICENSE diff --git a/postfix/src/global/mark_corrupt.c b/postfix/src/global/mark_corrupt.c index 994492ef1..e27cc1e3b 100644 --- a/postfix/src/global/mark_corrupt.c +++ b/postfix/src/global/mark_corrupt.c @@ -27,15 +27,19 @@ #include #include +#include /* Utility library. */ #include #include +#include /* Global library. */ #include +#include +#include #include /* mark_corrupt - mark queue file as corrupt */ @@ -43,6 +47,16 @@ int mark_corrupt(VSTREAM *src) { char *myname = "mark_corrupt"; + uid_t saved_uid; + gid_t saved_gid; + + /* + * If not running as the mail system, change privileges first. + */ + if ((saved_uid = geteuid()) != var_owner_uid) { + saved_gid = getegid(); + set_eugid(var_owner_uid, var_owner_gid); + } /* * For now, the result value is -1; this may become a bit mask, or @@ -52,5 +66,12 @@ int mark_corrupt(VSTREAM *src) msg_warn("corrupted queue file: %s", VSTREAM_PATH(src)); if (fchmod(vstream_fileno(src), MAIL_QUEUE_STAT_CORRUPT)) msg_fatal("%s: fchmod %s: %m", myname, VSTREAM_PATH(src)); - return (-1); + + /* + * Restore privileges. + */ + if (saved_uid != var_owner_uid) + set_eugid(saved_uid, saved_gid); + + return (DEL_STAT_CORRUPT); } diff --git a/postfix/src/global/pipe_command.c b/postfix/src/global/pipe_command.c index 766a41360..11f68b325 100644 --- a/postfix/src/global/pipe_command.c +++ b/postfix/src/global/pipe_command.c @@ -88,8 +88,11 @@ /* The command indicated that the message was not acceptable, /* or the command did not finish within the time limit. /* The reason is given via the \fIwhy\fR argument. +/* .IP PIPE_STAT_CORRUPT +/* The queue file is corrupted. /* SEE ALSO /* mail_copy(3) deliver to any. +/* mark_corrupt(3) mark queue file as corrupt. /* sys_exits(3) sendmail-compatible exit status codes. /* LICENSE /* .ad @@ -509,6 +512,8 @@ int pipe_command(VSTREAM *src, VSTRING *why,...) log_len ? ". Command output: " : "", log_buf); return (PIPE_STAT_BOUNCE); } + } else if (write_status & MAIL_COPY_STAT_CORRUPT) { + return (PIPE_STAT_CORRUPT); } else if (write_status && errno != EPIPE) { vstring_sprintf(why, "Command failed: %m: \"%s\"", args.command); return (PIPE_STAT_DEFER); diff --git a/postfix/src/global/pipe_command.h b/postfix/src/global/pipe_command.h index cf8d59892..1750ccc7b 100644 --- a/postfix/src/global/pipe_command.h +++ b/postfix/src/global/pipe_command.h @@ -45,6 +45,7 @@ #define PIPE_STAT_OK 0 /* success */ #define PIPE_STAT_DEFER 1 /* try again */ #define PIPE_STAT_BOUNCE 2 /* failed */ +#define PIPE_STAT_CORRUPT 3 /* corrupted file */ extern int pipe_command(VSTREAM *, VSTRING *,...); diff --git a/postfix/src/local/command.c b/postfix/src/local/command.c index ca2f151df..56e9bace8 100644 --- a/postfix/src/local/command.c +++ b/postfix/src/local/command.c @@ -195,6 +195,9 @@ int deliver_command(LOCAL_STATE state, USER_ATTR usr_attr, const char *comma BOUNCE_ATTR(state.msg_attr), "%s", vstring_str(why)); break; + case PIPE_STAT_CORRUPT: + deliver_status = DEL_STAT_CORRUPT; + break; default: msg_panic("%s: bad status %d", myname, cmd_status); /* NOTREACHED */ diff --git a/postfix/src/local/file.c b/postfix/src/local/file.c index 610b1a61d..3f1f7f1d9 100644 --- a/postfix/src/local/file.c +++ b/postfix/src/local/file.c @@ -86,7 +86,8 @@ int deliver_file(LOCAL_STATE state, USER_ATTR usr_attr, char *path) struct stat st; MBOX *mp; VSTRING *why; - int status = -1; + int mail_copy_status = MAIL_COPY_STAT_WRITE; + int deliver_status; int copy_flags; /* @@ -157,10 +158,10 @@ int deliver_file(LOCAL_STATE state, USER_ATTR usr_attr, char *path) vstring_sprintf(why, "destination file is executable"); errno = 0; } else { - status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp, - S_ISREG(st.st_mode) ? copy_flags : - (copy_flags & ~MAIL_COPY_TOFILE), - "\n", why); + mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp, + S_ISREG(st.st_mode) ? copy_flags : + (copy_flags & ~MAIL_COPY_TOFILE), + "\n", why); } mbox_release(mp); } @@ -169,19 +170,21 @@ int deliver_file(LOCAL_STATE state, USER_ATTR usr_attr, char *path) /* * As the mail system, bounce, defer delivery, or report success. */ - if (status != 0) { - status = (errno == EAGAIN || errno == ENOSPC || errno == ESTALE ? - defer_append : bounce_append) + if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) { + deliver_status = DEL_STAT_CORRUPT; + } else if (mail_copy_status != 0) { + deliver_status = (errno == EAGAIN || errno == ENOSPC || errno == ESTALE ? + defer_append : bounce_append) (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr), "cannot append message to destination file %s: %s", path, STR(why)); } else { - sent(SENT_ATTR(state.msg_attr), "%s", path); + deliver_status = sent(SENT_ATTR(state.msg_attr), "%s", path); } /* * Clean up. */ vstring_free(why); - return (status); + return (deliver_status); } diff --git a/postfix/src/local/mailbox.c b/postfix/src/local/mailbox.c index a07d11389..f92394533 100644 --- a/postfix/src/local/mailbox.c +++ b/postfix/src/local/mailbox.c @@ -95,7 +95,8 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) char *mailbox; VSTRING *why; MBOX *mp; - int status; + int mail_copy_status; + int deliver_status; int copy_flags; VSTRING *biff; long end; @@ -119,7 +120,7 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0) msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp)); state.msg_attr.delivered = state.msg_attr.recipient; - status = -1; + mail_copy_status = MAIL_COPY_STAT_WRITE; why = vstring_alloc(100); if (*var_home_mailbox) { spool_dir = 0; @@ -190,8 +191,8 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) errno = 0; } else { end = vstream_fseek(mp->fp, (off_t) 0, SEEK_END); - status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp, - copy_flags, "\n", why); + mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp, + copy_flags, "\n", why); } if (spool_uid != usr_attr.uid || spool_gid != usr_attr.gid) set_eugid(spool_uid, spool_gid); @@ -202,14 +203,16 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) /* * As the mail system, bounce, defer delivery, or report success. */ - if (status != 0) { - status = (errno == EAGAIN || errno == ENOSPC || errno == ESTALE ? - defer_append : bounce_append) + if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) { + deliver_status = DEL_STAT_CORRUPT; + } else if (mail_copy_status != 0) { + deliver_status = (errno == EAGAIN || errno == ENOSPC || errno == ESTALE ? + defer_append : bounce_append) (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr), "cannot access mailbox %s for user %s. %s", mailbox, state.msg_attr.user, vstring_str(why)); } else { - sent(SENT_ATTR(state.msg_attr), "mailbox"); + deliver_status = sent(SENT_ATTR(state.msg_attr), "mailbox"); if (var_biff) { biff = vstring_alloc(100); vstring_sprintf(biff, "%s@%ld", usr_attr.logname, (long) end); @@ -223,7 +226,7 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) */ myfree(mailbox); vstring_free(why); - return (status); + return (deliver_status); } /* deliver_mailbox - deliver to recipient mailbox */ diff --git a/postfix/src/local/maildir.c b/postfix/src/local/maildir.c index 195e0bfdb..12128cd02 100644 --- a/postfix/src/local/maildir.c +++ b/postfix/src/local/maildir.c @@ -80,7 +80,8 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) VSTRING *why; VSTRING *buf; VSTREAM *dst; - int status; + int mail_copy_status; + int deliver_status; int copy_flags; static int count; @@ -98,7 +99,7 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0) msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp)); state.msg_attr.delivered = state.msg_attr.recipient; - status = -1; + mail_copy_status = MAIL_COPY_STAT_WRITE; buf = vstring_alloc(100); why = vstring_alloc(100); @@ -137,14 +138,14 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) { vstring_sprintf(why, "create %s: %m", tmpfile); } else { - if (mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why) == 0) { + if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), + dst, copy_flags, "\n", why)) == 0) { if (sane_link(tmpfile, newfile) < 0 && (errno != ENOENT || (make_dirs(curdir, 0700), make_dirs(newdir, 0700)) < 0 || sane_link(tmpfile, newfile) < 0)) { vstring_sprintf(why, "link to %s: %m", newfile); - } else { - status = 0; + mail_copy_status = MAIL_COPY_STAT_WRITE; } } if (unlink(tmpfile) < 0) @@ -152,13 +153,19 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) } set_eugid(var_owner_uid, var_owner_gid); - if (status) - status = (errno == ENOSPC || errno == ESTALE ? - defer_append : bounce_append) + /* + * As the mail system, bounce or defer delivery. + */ + if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) { + deliver_status = DEL_STAT_CORRUPT; + } else if (mail_copy_status != 0) { + deliver_status = (errno == ENOSPC || errno == ESTALE ? + defer_append : bounce_append) (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr), "maildir delivery failed: %s", vstring_str(why)); - else - status = sent(SENT_ATTR(state.msg_attr), "maildir"); + } else { + deliver_status = sent(SENT_ATTR(state.msg_attr), "maildir"); + } vstring_free(buf); vstring_free(why); myfree(newdir); @@ -166,5 +173,5 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) myfree(curdir); myfree(tmpfile); myfree(newfile); - return (status); + return (deliver_status); } diff --git a/postfix/src/master/Makefile.in b/postfix/src/master/Makefile.in index a88350584..93a10e380 100644 --- a/postfix/src/master/Makefile.in +++ b/postfix/src/master/Makefile.in @@ -82,6 +82,7 @@ depend: $(MAKES) mail_flow.o: mail_flow.c mail_flow.o: ../../include/sys_defs.h mail_flow.o: ../../include/msg.h +mail_flow.o: ../../include/iostuff.h mail_flow.o: mail_flow.h mail_flow.o: master_proto.h master.o: master.c diff --git a/postfix/src/master/mail_flow.c b/postfix/src/master/mail_flow.c index 292e84a4c..626ce095c 100644 --- a/postfix/src/master/mail_flow.c +++ b/postfix/src/master/mail_flow.c @@ -50,6 +50,7 @@ /* Utility library. */ #include +#include /* Global library. */ diff --git a/postfix/src/nqmgr/qmgr_active.c b/postfix/src/nqmgr/qmgr_active.c index bb3e5a420..722d81073 100644 --- a/postfix/src/nqmgr/qmgr_active.c +++ b/postfix/src/nqmgr/qmgr_active.c @@ -131,7 +131,8 @@ static void qmgr_active_corrupt(const char *queue_id) msg_warn("%s: save corrupt file queue %s id %s: %m", myname, MAIL_QUEUE_ACTIVE, queue_id); } else { - msg_warn("corrupt file queue %s id %s", MAIL_QUEUE_ACTIVE, queue_id); + msg_warn("saving corrupt file \"%s\" from queue \"%s\" to queue \"%s\"", + queue_id, MAIL_QUEUE_ACTIVE, MAIL_QUEUE_CORRUPT); } } @@ -329,7 +330,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message) * attributes, and by pretending that delivery was deferred. */ if (message->flags - && !mail_open_ok(MAIL_QUEUE_ACTIVE, message->queue_id, &st, &path)) { + && mail_open_ok(MAIL_QUEUE_ACTIVE, message->queue_id, &st, &path) == MAIL_OPEN_NO) { qmgr_active_corrupt(message->queue_id); qmgr_message_free(message); return; diff --git a/postfix/src/pipe/pipe.c b/postfix/src/pipe/pipe.c index 6503905db..53cb7363d 100644 --- a/postfix/src/pipe/pipe.c +++ b/postfix/src/pipe/pipe.c @@ -11,8 +11,8 @@ /* This program expects to be run from the \fBmaster\fR(8) process /* manager. /* -/* Message attributes such as sender address, recipient address and -/* next-hop host name can be specified as command-line macros that are +/* Message attributes such as sender address, recipient address and +/* next-hop host name can be specified as command-line macros that are /* expanded before the external command is executed. /* /* The \fBpipe\fR daemon updates queue files and marks recipients @@ -56,13 +56,13 @@ /* Prepend a \fBReturn-Path:\fR message header with the envelope sender /* address. /* .IP \fBh\fR -/* Fold the command-line \fB$recipient\fR domain name and \fB$nexthop\fR +/* Fold the command-line \fB$recipient\fR domain name and \fB$nexthop\fR /* host name to lower case. /* This is recommended for delivery via \fBUUCP\fR. /* .IP \fBq\fR /* Quote white space and other special characters in the command-line -/* \fB$sender\fR and \fB$recipient\fR address localparts (text to the -/* left of the right-most \fB@\fR character), according to an 8-bit +/* \fB$sender\fR and \fB$recipient\fR address localparts (text to the +/* left of the right-most \fB@\fR character), according to an 8-bit /* transparent version of RFC 822. /* This is recommended for delivery via \fBUUCP\fR or \fBBSMTP\fR. /* .sp @@ -73,7 +73,7 @@ /* address information from the \fB$user\fR, \fB$extension\fR or /* \fB$mailbox\fR command-line macros. /* .IP \fBu\fR -/* Fold the command-line \fB$recipient\fR address localpart (text to +/* Fold the command-line \fB$recipient\fR address localpart (text to /* the left of the right-most \fB@\fR character) to lower case. /* This is recommended for delivery via \fBUUCP\fR. /* .IP \fB.\fR @@ -717,6 +717,9 @@ static int eval_command_status(int command_status, char *service, service, request->arrival_time, "%s", why); } break; + case PIPE_STAT_CORRUPT: + result |= DEL_STAT_CORRUPT; + break; default: msg_panic("eval_command_status: bad status %d", command_status); /* NOTREACHED */ diff --git a/postfix/src/qmgr/qmgr_active.c b/postfix/src/qmgr/qmgr_active.c index bb3e5a420..722d81073 100644 --- a/postfix/src/qmgr/qmgr_active.c +++ b/postfix/src/qmgr/qmgr_active.c @@ -131,7 +131,8 @@ static void qmgr_active_corrupt(const char *queue_id) msg_warn("%s: save corrupt file queue %s id %s: %m", myname, MAIL_QUEUE_ACTIVE, queue_id); } else { - msg_warn("corrupt file queue %s id %s", MAIL_QUEUE_ACTIVE, queue_id); + msg_warn("saving corrupt file \"%s\" from queue \"%s\" to queue \"%s\"", + queue_id, MAIL_QUEUE_ACTIVE, MAIL_QUEUE_CORRUPT); } } @@ -329,7 +330,7 @@ static void qmgr_active_done_2_generic(QMGR_MESSAGE *message) * attributes, and by pretending that delivery was deferred. */ if (message->flags - && !mail_open_ok(MAIL_QUEUE_ACTIVE, message->queue_id, &st, &path)) { + && mail_open_ok(MAIL_QUEUE_ACTIVE, message->queue_id, &st, &path) == MAIL_OPEN_NO) { qmgr_active_corrupt(message->queue_id); qmgr_message_free(message); return; diff --git a/postfix/src/smtpd/Makefile.in b/postfix/src/smtpd/Makefile.in index f94336be3..f1f0e4255 100644 --- a/postfix/src/smtpd/Makefile.in +++ b/postfix/src/smtpd/Makefile.in @@ -127,6 +127,9 @@ smtpd.o: ../../include/mail_queue.h smtpd.o: ../../include/tok822.h smtpd.o: ../../include/resolve_clnt.h smtpd.o: ../../include/verp_sender.h +smtpd.o: ../../include/string_list.h +smtpd.o: ../../include/match_list.h +smtpd.o: ../../include/match_ops.h smtpd.o: ../../include/mail_server.h smtpd.o: smtpd_token.h smtpd.o: smtpd.h diff --git a/postfix/src/smtpd/smtpd.c b/postfix/src/smtpd/smtpd.c index 9a775ae2b..ca5f0d6c5 100644 --- a/postfix/src/smtpd/smtpd.c +++ b/postfix/src/smtpd/smtpd.c @@ -68,6 +68,10 @@ /* either bounces mail or re-injects the result back into Postfix. /* This parameter uses the same syntax as the right-hand side of /* a Postfix transport table. +/* .IP \fBsmtpd_noop_commands\fR +/* List of commands that are treated as NOOP (no operation) commands +/* without any parameter syntax checking. This list overrides built-in +/* command definitions. /* .SH "Authentication controls" /* .IP \fBenable_sasl_authentication\fR /* Enable per-session authentication as per RFC 2554 (SASL). @@ -301,6 +305,7 @@ #include #include #include +#include /* Single-threaded server skeleton. */ @@ -369,6 +374,7 @@ char *var_filter_xport; bool var_broken_auth_clients; char *var_perm_mx_networks; char *var_smtpd_snd_auth_maps; +char *var_smtpd_noop_cmds; /* * Global state, for stand-alone mode queue file cleanup. When this is @@ -1329,6 +1335,8 @@ static SMTPD_CMD smtpd_cmd_table[] = { 0, }; +static STRING_LIST *smtpd_noop_cmds; + /* smtpd_proto - talk the SMTP protocol */ static void smtpd_proto(SMTPD_STATE *state) @@ -1389,6 +1397,13 @@ static void smtpd_proto(SMTPD_STATE *state) state->error_count++; continue; } + if (*var_smtpd_noop_cmds + && string_list_match(smtpd_noop_cmds, argv[0].strval)) { + smtpd_chat_reply(state, "250 Ok"); + if (state->junk_cmds++ > var_smtpd_junk_cmd_limit) + state->error_count++; + continue; + } for (cmdp = smtpd_cmd_table; cmdp->name != 0; cmdp++) if (strcasecmp(argv[0].strval, cmdp->name) == 0) break; @@ -1555,6 +1570,7 @@ static void pre_jail_init(char *unused_name, char **unused_argv) * Initialize blacklist/etc. patterns before entering the chroot jail, in * case they specify a filename pattern. */ + smtpd_noop_cmds = string_list_init(MATCH_FLAG_NONE, var_smtpd_noop_cmds); smtpd_check_init(); debug_peer_init(); msg_cleanup(smtpd_cleanup); @@ -1628,6 +1644,7 @@ int main(int argc, char **argv) VAR_FILTER_XPORT, DEF_FILTER_XPORT, &var_filter_xport, 0, 0, VAR_PERM_MX_NETWORKS, DEF_PERM_MX_NETWORKS, &var_perm_mx_networks, 0, 0, VAR_SMTPD_SND_AUTH_MAPS, DEF_SMTPD_SND_AUTH_MAPS, &var_smtpd_snd_auth_maps, 0, 0, + VAR_SMTPD_NOOP_CMDS, DEF_SMTPD_NOOP_CMDS, &var_smtpd_noop_cmds, 0, 0, 0, }; diff --git a/postfix/src/util/Makefile.in b/postfix/src/util/Makefile.in index eb0523dcd..e2e2af311 100644 --- a/postfix/src/util/Makefile.in +++ b/postfix/src/util/Makefile.in @@ -397,16 +397,6 @@ argv_split.o: stringops.h argv_split.o: vstring.h argv_split.o: vbuf.h argv_split.o: argv.h -attr_print.o: attr_print.c -attr_print.o: sys_defs.h -attr_print.o: msg.h -attr_print.o: mymalloc.h -attr_print.o: vstream.h -attr_print.o: vbuf.h -attr_print.o: htable.h -attr_print.o: base64_code.h -attr_print.o: vstring.h -attr_print.o: attr.h attr_print0.o: attr_print0.c attr_print0.o: sys_defs.h attr_print0.o: msg.h @@ -425,16 +415,6 @@ attr_print64.o: htable.h attr_print64.o: base64_code.h attr_print64.o: vstring.h attr_print64.o: attr.h -attr_scan.o: attr_scan.c -attr_scan.o: sys_defs.h -attr_scan.o: msg.h -attr_scan.o: mymalloc.h -attr_scan.o: vstream.h -attr_scan.o: vbuf.h -attr_scan.o: vstring.h -attr_scan.o: htable.h -attr_scan.o: base64_code.h -attr_scan.o: attr.h attr_scan0.o: attr_scan0.c attr_scan0.o: sys_defs.h attr_scan0.o: msg.h diff --git a/postfix/src/virtual/mailbox.c b/postfix/src/virtual/mailbox.c index 58894538e..4f65f8025 100644 --- a/postfix/src/virtual/mailbox.c +++ b/postfix/src/virtual/mailbox.c @@ -79,7 +79,8 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) char *myname = "deliver_mailbox_file"; VSTRING *why; MBOX *mp; - int status; + int mail_copy_status; + int deliver_status; int copy_flags; long end; struct stat st; @@ -98,7 +99,7 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0) msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp)); state.msg_attr.delivered = state.msg_attr.recipient; - status = -1; + mail_copy_status = MAIL_COPY_STAT_WRITE; why = vstring_alloc(100); /* @@ -119,8 +120,8 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) errno = 0; } else { end = vstream_fseek(mp->fp, (off_t) 0, SEEK_END); - status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp, - copy_flags, "\n", why); + mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), mp->fp, + copy_flags, "\n", why); } mbox_release(mp); } @@ -129,16 +130,18 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) /* * As the mail system, bounce, defer delivery, or report success. */ - if (status != 0) - status = (errno == EDQUOT || errno == EFBIG ? - bounce_append : defer_append) + if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) { + deliver_status = DEL_STAT_CORRUPT; + } else if (mail_copy_status != 0) { + deliver_status = (errno == EDQUOT || errno == EFBIG ? + bounce_append : defer_append) (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr), "mailbox %s: %s", usr_attr.mailbox, vstring_str(why)); - else - sent(SENT_ATTR(state.msg_attr), "mailbox"); - + } else { + deliver_status = sent(SENT_ATTR(state.msg_attr), "mailbox"); + } vstring_free(why); - return (status); + return (deliver_status); } /* deliver_mailbox - deliver to recipient mailbox */ diff --git a/postfix/src/virtual/maildir.c b/postfix/src/virtual/maildir.c index 6522d28f7..19738c5e4 100644 --- a/postfix/src/virtual/maildir.c +++ b/postfix/src/virtual/maildir.c @@ -78,7 +78,8 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr) VSTRING *why; VSTRING *buf; VSTREAM *dst; - int status; + int mail_copy_status; + int deliver_status; int copy_flags; static int count; @@ -96,7 +97,7 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr) if (vstream_fseek(state.msg_attr.fp, state.msg_attr.offset, SEEK_SET) < 0) msg_fatal("seek message file %s: %m", VSTREAM_PATH(state.msg_attr.fp)); state.msg_attr.delivered = state.msg_attr.recipient; - status = -1; + mail_copy_status = MAIL_COPY_STAT_WRITE; buf = vstring_alloc(100); why = vstring_alloc(100); @@ -133,14 +134,14 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr) || (dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0)) { vstring_sprintf(why, "create %s: %m", tmpfile); } else { - if (mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, "\n", why) == 0) { + if ((mail_copy_status = mail_copy(COPY_ATTR(state.msg_attr), + dst, copy_flags, "\n", why)) == 0) { if (sane_link(tmpfile, newfile) < 0 && (errno != ENOENT || (make_dirs(curdir, 0700), make_dirs(newdir, 0700)) < 0 || sane_link(tmpfile, newfile) < 0)) { vstring_sprintf(why, "link to %s: %m", newfile); - } else { - status = 0; + mail_copy_status = MAIL_COPY_STAT_WRITE; } } if (unlink(tmpfile) < 0) @@ -153,14 +154,17 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr) * delivery fails, try again later. We would just bounce when the maildir * location possibly under user control. */ - if (status) - status = (errno == EDQUOT || errno == EFBIG ? - bounce_append : defer_append) + if (mail_copy_status & MAIL_COPY_STAT_CORRUPT) { + deliver_status = DEL_STAT_CORRUPT; + } else if (mail_copy_status != 0) { + deliver_status = (errno == EDQUOT || errno == EFBIG ? + bounce_append : defer_append) (BOUNCE_FLAG_KEEP, BOUNCE_ATTR(state.msg_attr), "maildir delivery failed: %s", vstring_str(why)); - else - status = sent(SENT_ATTR(state.msg_attr), "maildir"); + } else { + deliver_status = sent(SENT_ATTR(state.msg_attr), "maildir"); + } vstring_free(buf); vstring_free(why); myfree(newdir); @@ -168,5 +172,5 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr) myfree(curdir); myfree(tmpfile); myfree(newfile); - return (status); + return (deliver_status); }