diff --git a/postfix/HISTORY b/postfix/HISTORY index 468f02cc5..33722da0f 100644 --- a/postfix/HISTORY +++ b/postfix/HISTORY @@ -1999,3 +1999,67 @@ Apologies for any names omitted. Bugfix: in Received: headers, the "for " information was in the wrong place. Pointed out by Jon Ribbens, Oaktree Internet Solutions Ltd. + +19990124 + + Portability: more workarounds for GNU getopt() by Liviu + Daia, Institute of Mathematics, Romanian Academy. File: + sendmail/sendmail.c. + +19990125 + + Bugfix: Postfix should not masquerade recipient addresses + extracted from message headers. Problem reported by David + Blacka, Network Solutions. File: cleanup/cleanup_message.c. + +19990126 + + Feature: smtpd_etrn_restrictions parameter to restrict who + may use ETRN and what domains may be specified. Example: + "smtpd_etrn_restrictions = permit_mynetworks, reject". + Requested by Jon Ribbens, Oaktree Internet Solutions Ltd. + File: smtpd/smtpd_check.c. + +19990127 + + Bugfix: in an attempt to shave some cycles, the anti junk + mail routines would use the wrong resolved address. This + "optimization" is now turned off. Problem reported by Sam + Eaton, Pavilion Internet Plc. File: smtpd/smtpd_check.c. + + Feature: BIFF notifications. For compatibility reasons + this feature is on by default. This "protocol" can be a + real performance pig. Specify "biff = no" in main.cf if + your machine has lots of shell users. Feature requested by + Dan Farmer - it's one of the things one does for friends. + Files: local/mailbox.c, local/biff_notify.c. + + Bugfix: another case sensitivity problem, this time with + virtual lookups to recognize unknown@virtual.domain. + Problem reported by Bo Kleve, Linkoping University. File: + qmgr/qmgr_message.c. + +19990128 + + Feature: with "soft_bounce = yes", defer delivery instead + of bouncing mail. This is a safety net for configuration + errors with delivery agents. It has no effect on errors in + virtual maps, canonical maps, or in junk mail restrictions. + Feature requested by Bennett Todd. File: global/bounce.c. + +19990129 + + Compatibility: the qmail maildir.5 documentation prescribes + maildir file names of the form time.pid.hostname, which is + wrong because Postfix processes perform multiple deliveries. + Elsewhere the qmail author has documented how maildir files + should be named under such conditions. Postfix has been + changed to be conformant. File: local/maildir.c. + +19990131 + + Feature: special treatment of owner-foo and foo-request + can be turned off. Specify "owner_request_special = no". + Requested by Matthew Green and others. Files: local/alias.c, + global/split_addr.c. This affects canonical, virtual and + alias lookups. diff --git a/postfix/INSTALL b/postfix/INSTALL index 8404fa4c3..126049c85 100644 --- a/postfix/INSTALL +++ b/postfix/INSTALL @@ -479,7 +479,7 @@ Postfix offers a choice of submission mechanims. and to make maildrop non-writable for unprivileged users: # chgrp maildrop /var/spool/postfix/maildrop /some/where/postdrop - # chmod 730 /var/spool/postfix/maildrop + # chmod 1730 /var/spool/postfix/maildrop # chmod 2755 /some/where/postdrop The sendmail posting program will automatically invoke the diff --git a/postfix/RELEASE_NOTES b/postfix/RELEASE_NOTES index be41fe925..0e9cef7ce 100644 --- a/postfix/RELEASE_NOTES +++ b/postfix/RELEASE_NOTES @@ -1,8 +1,28 @@ -This release introduces lots of new functionality in response to feedback -from users. +Incompatible changes with postfix-beta-19990122-pl01: +===================================================== -Incompatible changes: -===================== +None. + +Major changes with postfix-beta-19990122-pl01: +============================================== + +- Restrict who may use ETRN and what domains may be specified. +Example: "smtpd_etrn_restrictions = permit_mynetworks, reject". + +- BIFF notifications. For compatibility reasons this feature is +on by default. Specify "biff = no" in main.cf if your machine has +lots of shell users. + +- With "soft_bounce = yes", defer delivery instead of bouncing +mail. This is a safety net for configuration errors with delivery +agents. It has no effect on errors in virtual maps, canonical maps, +or in junk mail restrictions. + +- Specify "owner_request_special = no" to turn off special treatment +of owner-foo and foo-request addresses. + +Incompatible changes with postfix-beta-19990122: +================================================ - The syntax of the transport table has changed. An entry like: @@ -21,8 +41,8 @@ Incompatible changes: logged as hostname[address]; the pickup daemon logs queue file uid and sender address. -Major changes over the previous version: -======================================== +Major changes with postfix-beta-19990122: +========================================= - Junk mail restrictions can now be postoned to the RCPT TO command. Specify: "smtpd_recipient_restrictions = reject_maps_rbl...". diff --git a/postfix/cleanup/cleanup_message.c b/postfix/cleanup/cleanup_message.c index e357f52a9..32ec19327 100644 --- a/postfix/cleanup/cleanup_message.c +++ b/postfix/cleanup/cleanup_message.c @@ -197,6 +197,11 @@ static void cleanup_rewrite_recip(HEADER_OPTS *hdr_opts) cleanup_map11_tree(*tpp, cleanup_rcpt_canon_maps); if (cleanup_comm_canon_maps) cleanup_map11_tree(*tpp, cleanup_comm_canon_maps); + tok822_internalize(cleanup_temp1, tpp[0]->head, TOK822_STR_DEFL); + if (cleanup_recip == 0 && (hdr_opts->flags & HDR_OPT_EXTRACT) != 0) + argv_add((hdr_opts->flags & HDR_OPT_RR) ? + cleanup_resent_recip : cleanup_recipients, + vstring_str(cleanup_temp1), (char *) 0); if (cleanup_masq_domains) cleanup_masquerade_tree(*tpp, cleanup_masq_domains); if (hdr_opts->type == HDR_RETURN_RECEIPT_TO && !cleanup_return_receipt) @@ -205,11 +210,6 @@ static void cleanup_rewrite_recip(HEADER_OPTS *hdr_opts) if (hdr_opts->type == HDR_ERRORS_TO && !cleanup_errors_to) cleanup_errors_to = cleanup_extract_internal(cleanup_header_buf, *tpp); - tok822_internalize(cleanup_temp1, tpp[0]->head, TOK822_STR_DEFL); - if (cleanup_recip == 0 && (hdr_opts->flags & HDR_OPT_EXTRACT) != 0) - argv_add((hdr_opts->flags & HDR_OPT_RR) ? - cleanup_resent_recip : cleanup_recipients, - vstring_str(cleanup_temp1), (char *) 0); } vstring_sprintf(cleanup_header_buf, "%s: ", hdr_opts->name); tok822_externalize(cleanup_header_buf, tree, TOK822_STR_HEAD); diff --git a/postfix/conf/aliases b/postfix/conf/aliases index 4199c3087..e51097246 100644 --- a/postfix/conf/aliases +++ b/postfix/conf/aliases @@ -96,6 +96,9 @@ # Restrict the usage of mail delivery to external command. # .IP \fBallow_mail_to_files\fR # Restrict the usage of mail delivery to external file. +# .IP \fBowner_request_special\fR +# Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +# addresses. # .IP \fBrecipient_delimiter\fR # Delimiter that separates recipients from address extensions. # STANDARDS diff --git a/postfix/conf/canonical b/postfix/conf/canonical index 9cfde8d63..9ac1bc0fb 100644 --- a/postfix/conf/canonical +++ b/postfix/conf/canonical @@ -94,6 +94,9 @@ # List of domains that this mail system considers local. # .IP \fBmyorigin\fR # The domain that is appended to locally-posted mail. +# .IP \fBowner_request_special\fR +# Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +# addresses. # SEE ALSO # cleanup(8) canonicalize and enqueue mail # postmap(1) create mapping table diff --git a/postfix/conf/postfix-script-sgid b/postfix/conf/postfix-script-sgid index 7e6b9861c..62ba510fd 100755 --- a/postfix/conf/postfix-script-sgid +++ b/postfix/conf/postfix-script-sgid @@ -170,7 +170,7 @@ check) test -d maildrop || { $WARN creating missing Postfix maildrop directory mkdir maildrop || exit 1 - chmod 730 maildrop + chmod 1730 maildrop chown $mail_owner maildrop chgrp maildrop maildrop } diff --git a/postfix/conf/virtual b/postfix/conf/virtual index a0e6dda49..01c0aab8a 100644 --- a/postfix/conf/virtual +++ b/postfix/conf/virtual @@ -87,6 +87,9 @@ # List of domains that this mail system considers local. # .IP \fBmyorigin\fR # The domain that is appended to locally-posted mail. +# .IP \fBowner_request_special\fR +# Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +# addresses. # SEE ALSO # cleanup(8) canonicalize and enqueue mail # postmap(1) create mapping table diff --git a/postfix/global/Makefile.in b/postfix/global/Makefile.in index 3fe66c8fb..9a077980d 100644 --- a/postfix/global/Makefile.in +++ b/postfix/global/Makefile.in @@ -222,6 +222,7 @@ bounce.o: ../include/sys_defs.h bounce.o: ../include/msg.h bounce.o: ../include/vstring.h bounce.o: ../include/vbuf.h +bounce.o: mail_params.h bounce.o: mail_proto.h bounce.o: ../include/vstream.h bounce.o: ../include/iostuff.h diff --git a/postfix/global/bounce.c b/postfix/global/bounce.c index c0a741c23..e5e6def48 100644 --- a/postfix/global/bounce.c +++ b/postfix/global/bounce.c @@ -105,6 +105,7 @@ /* Global library. */ +#include "mail_params.h" #include "mail_proto.h" #include "defer.h" #include "bounce.h" @@ -128,17 +129,29 @@ int bounce_append(int flags, const char *id, const char *recipient, int vbounce_append(int flags, const char *id, const char *recipient, const char *relay, time_t entry, const char *fmt, va_list ap) { - VSTRING *why = vstring_alloc(100); + VSTRING *why; int status; - int delay = time((time_t *) 0) - entry; + int delay; + /* + * When we're pretending that we can't bounce, don't create a defer log + * file when we wouldn't keep the bounce log file. That's a lot of + * negatives in one sentence. + */ + if (var_soft_bounce && (flags & BOUNCE_FLAG_CLEAN)) + return (-1); + + why = vstring_alloc(100); + delay = time((time_t *) 0) - entry; vstring_vsprintf(why, fmt, ap); - if (mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_BOUNCE, + if (mail_command_write(MAIL_CLASS_PRIVATE, var_soft_bounce ? + MAIL_SERVICE_DEFER : MAIL_SERVICE_BOUNCE, "%d %d %s %s %s", BOUNCE_CMD_APPEND, flags, id, recipient, vstring_str(why)) == 0) { - msg_info("%s: to=<%s>, relay=%s, delay=%d, status=bounced (%s)", - id, recipient, relay, delay, vstring_str(why)); - status = 0; + msg_info("%s: to=<%s>, relay=%s, delay=%d, status=%s (%s)", + id, recipient, relay, delay, var_soft_bounce ? "deferred" : + "bounced", vstring_str(why)); + status = (var_soft_bounce ? -1 : 0); } else if ((flags & BOUNCE_FLAG_CLEAN) == 0) { status = defer_append(flags, id, recipient, "bounce", delay, "bounce failed"); @@ -154,6 +167,13 @@ int vbounce_append(int flags, const char *id, const char *recipient, int bounce_flush(int flags, const char *queue, const char *id, const char *sender) { + + /* + * When we're pretending that we can't bounce, don't send a bounce + * message. + */ + if (var_soft_bounce) + return (-1); if (mail_command_write(MAIL_CLASS_PRIVATE, MAIL_SERVICE_BOUNCE, "%d %d %s %s %s", BOUNCE_CMD_FLUSH, flags, queue, id, sender) == 0) { diff --git a/postfix/global/mail_params.c b/postfix/global/mail_params.c index b27cee4ff..189434003 100644 --- a/postfix/global/mail_params.c +++ b/postfix/global/mail_params.c @@ -52,6 +52,9 @@ /* int var_flock_delay; /* int var_flock_stale; /* int var_disable_dns; +/* int var_soft_bounce; +/* time_t var_starttime; +/* int var_ownreq_special; /* /* char *var_ldap_server_host; /* char *var_ldap_search_base; @@ -86,6 +89,7 @@ #include #include #include +#include #ifdef STRCASECMP_IN_STRINGS_H #include @@ -153,6 +157,9 @@ int var_flock_tries; int var_flock_delay; int var_flock_stale; int var_disable_dns; +int var_soft_bounce; +time_t var_starttime; +int var_ownreq_special; #ifdef HAS_LDAP @@ -285,6 +292,8 @@ void mail_params_init() }; static CONFIG_BOOL_TABLE bool_defaults[] = { VAR_DISABLE_DNS, DEF_DISABLE_DNS, &var_disable_dns, + VAR_SOFT_BOUNCE, DEF_SOFT_BOUNCE, &var_soft_bounce, + VAR_OWNREQ_SPECIAL, DEF_OWNREQ_SPECIAL, &var_ownreq_special, 0, }; @@ -319,6 +328,11 @@ void mail_params_init() */ set_config_int(VAR_PID, var_pid = getpid()); + /* + * Neither can the start time variable. It isn't even visible. + */ + time(&var_starttime); + /* * If have seen this happen just too often. */ diff --git a/postfix/global/mail_params.h b/postfix/global/mail_params.h index af729d97e..f07cb73f1 100644 --- a/postfix/global/mail_params.h +++ b/postfix/global/mail_params.h @@ -147,6 +147,11 @@ extern char *var_command_dir; #endif extern char *var_pid_dir; + /* + * Program startup time. + */ +extern time_t var_starttime; + /* * Location of configuration files. */ @@ -243,6 +248,13 @@ extern int var_ldap_timeout; #endif extern char *var_alias_maps; + /* + * Local delivery: to BIFF or not to BIFF. + */ +#define VAR_BIFF "biff" +#define DEF_BIFF 1 +extern bool var_biff; + /* * Local delivery: mail to files/commands. */ @@ -597,6 +609,10 @@ extern char *var_mail_checks; #define DEF_RCPT_CHECKS PERMIT_MYNETWORKS "," CHECK_RELAY_DOMAINS extern char *var_rcpt_checks; +#define VAR_ETRN_CHECKS "smtpd_etrn_restrictions" +#define DEF_ETRN_CHECKS "" +extern char *var_etrn_checks; + /* * Names of specific restrictions, and the corresponding configuration * parameters that control the status codes sent in response to rejected @@ -647,6 +663,7 @@ extern int var_access_map_code; #define CHECK_HELO_ACL "check_helo_access" #define CHECK_SENDER_ACL "check_sender_access" #define CHECK_RECIP_ACL "check_recipient_access" +#define CHECK_ETRN_ACL "check_etrn_access" #define REJECT_MAPS_RBL "reject_maps_rbl" #define VAR_MAPS_RBL_CODE "maps_rbl_reject_code" @@ -675,6 +692,20 @@ extern int var_pid; #define DEF_DONT_REMOVE 0 extern bool var_dont_remove; + /* + * Paranoia: defer messages instead of bouncing them. + */ +#define VAR_SOFT_BOUNCE "soft_bounce" +#define DEF_SOFT_BOUNCE 0 +extern bool var_soft_bounce; + + /* + * Give special treatment to owner- and -request. + */ +#define VAR_OWNREQ_SPECIAL "owner_request_special" +#define DEF_OWNREQ_SPECIAL 1 +extern bool var_ownreq_special; + extern void mail_params_init(void); /* LICENSE diff --git a/postfix/global/mail_version.h b/postfix/global/mail_version.h index 81ba2ba06..b53b9f47d 100644 --- a/postfix/global/mail_version.h +++ b/postfix/global/mail_version.h @@ -15,7 +15,7 @@ * Version of this program. */ #define VAR_MAIL_VERSION "mail_version" -#define DEF_MAIL_VERSION "Beta-19990122" +#define DEF_MAIL_VERSION "Beta-19990122-pl01" extern char *var_mail_version; /* LICENSE diff --git a/postfix/global/split_addr.c b/postfix/global/split_addr.c index 4dbb3580d..a52760fdf 100644 --- a/postfix/global/split_addr.c +++ b/postfix/global/split_addr.c @@ -15,8 +15,9 @@ /* returns a pointer to the remainder. /* /* Reserved addresses are not split: postmaster, mailer-daemon, -/* double-bounce, addresses that begin with owner-, or addresses -/* that end in -request. +/* double-bounce. Addresses that begin with owner-, or addresses +/* that end in -request are not split, unless the owner_request_special +/* parameter is set. /* LICENSE /* .ad /* .fi @@ -51,7 +52,7 @@ char *split_addr(char *localpart, int delimiter) { - int len; + int len; /* * Don't split these, regardless of what the delimiter is. @@ -66,11 +67,13 @@ char *split_addr(char *localpart, int delimiter) /* * Backwards compatibility: don't split owner-foo or foo-request. */ - if (strncasecmp(localpart, "owner-", 6) == 0) - return (0); - if ((len = strlen(localpart) - 8) > 0 - && strcasecmp(localpart + len, "-request") == 0) - return (0); + if (var_ownreq_special != 0) { + if (strncasecmp(localpart, "owner-", 6) == 0) + return (0); + if ((len = strlen(localpart) - 8) > 0 + && strcasecmp(localpart + len, "-request") == 0) + return (0); + } /* * Safe to split this address. diff --git a/postfix/html/aliases.5.html b/postfix/html/aliases.5.html index 9f52d1656..887e9ec31 100644 --- a/postfix/html/aliases.5.html +++ b/postfix/html/aliases.5.html @@ -137,8 +137,12 @@ ALIASES(5) ALIASES(5) ALIASES(5) ALIASES(5) + owner_request_special + Give special treatment to owner-xxx and xxx-request + addresses. + recipient_delimiter - Delimiter that separates recipients from address + Delimiter that separates recipients from address extensions. STANDARDS @@ -149,7 +153,7 @@ ALIASES(5) ALIASES(5) postalias(1) alias database management LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -185,10 +189,6 @@ ALIASES(5) ALIASES(5) - - - - diff --git a/postfix/html/canonical.5.html b/postfix/html/canonical.5.html index f36f69808..fdfc525b6 100644 --- a/postfix/html/canonical.5.html +++ b/postfix/html/canonical.5.html @@ -144,13 +144,17 @@ CANONICAL(5) CANONICAL(5) myorigin The domain that is appended to locally-posted mail. + owner_request_special + Give special treatment to owner-xxx and xxx-request + addresses. + SEE ALSO cleanup(8) canonicalize and enqueue mail postmap(1) create mapping table virtual(5) virtual domain mapping LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -185,10 +189,6 @@ CANONICAL(5) CANONICAL(5) - - - - diff --git a/postfix/html/faq.html b/postfix/html/faq.html index 5d24b58d0..3e38aa5bb 100644 --- a/postfix/html/faq.html +++ b/postfix/html/faq.html @@ -197,7 +197,14 @@ was introduced with the qmail system by Daniel Bernstein.

Postfix supports the maildir mailbox format. Edit main.cf -and specify a line with: home_mailbox = maildir. +and specify a line with: home_mailbox = Maildir/ (any relative +pathname that ends in / will do). + +

+ +The maildir format is also supported for delivery from aliases or +.forward files. Specify /file/name/ as destination. +The trailing / turns on maildir delivery.


@@ -347,7 +354,7 @@ you change the transport file.
     uucp      unix  -       n       n       -       -       pipe
-      flags=F user=uucp argv=uux -n -z -a$sender - $nexthop!rmail ($recipient)
+      flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
 

@@ -425,7 +432,7 @@ via the uucp message transport:

     uucp      unix  -       n       n       -       -       pipe
-      flags=F user=uucp argv=uux -n -z -a$sender - $nexthop!rmail ($recipient)
+      flags=F user=uucp argv=uux -r -n -z -a$sender - $nexthop!rmail ($recipient)
 
This runs the uux command, and substitutes the next-hop diff --git a/postfix/html/local.8.html b/postfix/html/local.8.html index c2b28458d..f7b0aebb4 100644 --- a/postfix/html/local.8.html +++ b/postfix/html/local.8.html @@ -81,35 +81,42 @@ LOCAL(8) LOCAL(8) mailbox directory (/var/mail/user or /var/spool/mail/user) or it is a file in the user's home directory with a name specified via the home_mailbox configuration parameter. - Mailbox delivery can be delegated to an external command - specified with the mailbox_command configuration parame- - ter. + Specify a path name ending in / for qmail-compatible + maildir delivery. Mailbox delivery can be delegated to an + external command specified with the mailbox_command con- + figuration parameter. The local daemon prepends a "From sender time_stamp" enve- - lope header to each message, prepends a Delivered-To: - header with the envelope recipient address, prepends a > - character to lines beginning with "From ", and appends an - empty line. The mailbox is locked for exclusive access - while delivery is in progress. In case of problems, an - attempt is made to truncate the mailbox to its original - length. + lope header to each message, prepends a Delivered-To: + header with the envelope recipient address, prepends a > + character to lines beginning with "From ", and appends an + empty line. The envelope sender address is available in + the Return-Path: header. The mailbox is locked for exclu- + sive access while delivery is in progress. In case of + problems, an attempt is made to truncate the mailbox to + its original length. + + In the case of maildir delivery, the local daemon prepends + a Delivered-To: header with the envelope recipient + address. The envelope sender address is available in the + Return-Path: header. EXTERNAL COMMAND DELIVERY - The allow_mail_to_commands configuration parameter - restricts delivery to external commands. The default set- - ting (alias, forward) forbids command destinations in + The allow_mail_to_commands configuration parameter + restricts delivery to external commands. The default set- + ting (alias, forward) forbids command destinations in :include: files. - The command is executed directly where possible. Assis- - tance by the shell (/bin/sh on UNIX systems) is used only - when the command contains shell magic characters, or when + The command is executed directly where possible. Assis- + tance by the shell (/bin/sh on UNIX systems) is used only + when the command contains shell magic characters, or when the command invokes a shell built-in command. - A limited amount of command output (standard output and - standard error) is captured for inclusion with non-deliv- - ery status reports. A command is forcibly terminated if - it does not complete within command_time_limit seconds. - Command exit status codes are expected to follow the con- + A limited amount of command output (standard output and + standard error) is captured for inclusion with non-deliv- + ery status reports. A command is forcibly terminated if + it does not complete within command_time_limit seconds. + Command exit status codes are expected to follow the con- ventions defined in <sysexits.h>. When mail is delivered on behalf of a user, the HOME, LOG- @@ -118,13 +125,6 @@ LOCAL(8) LOCAL(8) dependent default path, and the TZ (time zone) environment variable is always passed on without change. - The current working directory is the mail queue directory. - - The local daemon prepends a "From sender time_stamp" enve- - lope header to each message, prepends a Delivered-To: - header with the recipient envelope address, and appends an - empty line. - @@ -137,19 +137,35 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) + The current working directory is the mail queue directory. + + The local daemon prepends a "From sender time_stamp" enve- + lope header to each message, prepends a Delivered-To: + header with the recipient envelope address, and appends an + empty line. The envelope sender address is available in + the Return-Path: header. + EXTERNAL FILE DELIVERY The allow_mail_to_files configuration parameter restricts delivery to external files. The default setting (alias, - forward) forbids file destinations in :include: files. + forward) forbids file destinations in :include: files. + Specify a pathname ending in / for qmail-compatible + maildir delivery. The local daemon prepends a "From sender time_stamp" enve- lope header to each message, prepends a Delivered-To: header with the recipient envelope address, prepends a > character to lines beginning with "From ", and appends an - empty line. When the destination is a regular file, it is - locked for exclusive access while delivery is in progress. - In case of problems, an attempt is made to truncate a reg- - ular file to its original length. + empty line. The envelope sender address is available in + the Return-Path: header. When the destination is a regu- + lar file, it is locked for exclusive access while delivery + is in progress. In case of problems, an attempt is made to + truncate a regular file to its original length. + + In the case of maildir delivery, the local daemon prepends + a Delivered-To: header with the envelope recipient + address. The envelope sender address is available in the + Return-Path: header. ADDRESS EXTENSION The optional recipient_delimiter configuration parameter @@ -174,6 +190,19 @@ LOCAL(8) LOCAL(8) superuser, delivery is made with the rights specified with the default_privs configuration parameter. + + + + + 3 + + + + + +LOCAL(8) LOCAL(8) + + STANDARDS RFC 822 (ARPA Internet Text Messages) @@ -190,20 +219,8 @@ LOCAL(8) LOCAL(8) For security reasons, the message delivery status of external commands or of external files is never check- pointed to file. As a result, the program may occasionally - deliver more than once to a command or external file. - - - - 3 - - - - - -LOCAL(8) LOCAL(8) - - - Better safe than sorry. + deliver more than once to a command or external file. Bet- + ter safe than sorry. Mutually-recursive aliases or ~/.forward files are not detected early. The resulting mail forwarding loop is @@ -221,8 +238,8 @@ LOCAL(8) LOCAL(8) home_mailbox Pathname of a mailbox relative to a user's home - directory. Specify maildir for maildir-style - delivery. + directory. Specify a path ending in / for maildir- + style delivery. local_command_shell Shell to use for external command execution (for @@ -234,30 +251,13 @@ LOCAL(8) LOCAL(8) mailbox_command External command to use for mailbox delivery. + owner_request_special + Give special treatment to owner-xxx and xxx-request + addresses. + recipient_delimiter Separator between username and address extension. -Locking controls - deliver_lock_attempts - Limit the number of attempts to acquire an exclu- - sive lock on a mailbox or external file. - - deliver_lock_delay - Time in seconds between successive attempts to - acquire an exclusive lock. - - stale_lock_time - Limit the time after which a stale lock is removed. - -Resource controls - command_time_limit - Limit the amount of time for delivery to external - command. - - duplicate_filter_limit - Limit the size of the duplicate filter for results - from alias etc. expansion. - 4 @@ -269,40 +269,72 @@ LOCAL(8) LOCAL(8) LOCAL(8) LOCAL(8) +Locking controls + deliver_lock_attempts + Limit the number of attempts to acquire an exclu- + sive lock on a mailbox or external file. + + deliver_lock_delay + Time in seconds between successive attempts to + acquire an exclusive lock. + + stale_lock_time + Limit the time after which a stale lock is removed. + +Resource controls + command_time_limit + Limit the amount of time for delivery to external + command. + + duplicate_filter_limit + Limit the size of the duplicate filter for results + from alias etc. expansion. + line_length_limit - Limit the amount of memory used for processing a + Limit the amount of memory used for processing a partial input line. local_destination_concurrency_limit Limit the number of parallel deliveries to the same - user. The default limit is taken from the + user. The default limit is taken from the default_destination_concurrency_limit parameter. local_destination_recipient_limit - Limit the number of recipients per message deliv- - ery. The default limit is taken from the + Limit the number of recipients per message deliv- + ery. The default limit is taken from the default_destination_recipient_limit parameter. Security controls allow_mail_to_commands - Restrict the usage of mail delivery to external + Restrict the usage of mail delivery to external command. allow_mail_to_files - Restrict the usage of mail delivery to external + Restrict the usage of mail delivery to external file. default_privs - Default rights for delivery to external file or + Default rights for delivery to external file or command. HISTORY - The Delivered-To: header appears in the qmail system by + The Delivered-To: header appears in the qmail system by Daniel Bernstein. - The maildir structure appears in the qmail system by + The maildir structure appears in the qmail system by Daniel Bernstein. + + + 5 + + + + + +LOCAL(8) LOCAL(8) + + SEE ALSO aliases(5) format of alias database bounce(8) non-delivery status reports @@ -311,7 +343,7 @@ LOCAL(8) LOCAL(8) qmgr(8) queue manager LICENSE - The Secure Mailer license must be distributed with this + The Secure Mailer license must be distributed with this software. AUTHOR(S) @@ -326,7 +358,41 @@ LOCAL(8) LOCAL(8) - 5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 6 diff --git a/postfix/html/smtpd.8.html b/postfix/html/smtpd.8.html index 2d990dd18..497fd1c20 100644 --- a/postfix/html/smtpd.8.html +++ b/postfix/html/smtpd.8.html @@ -177,19 +177,19 @@ SMTPD(8) SMTPD(8) Restrict what recipient addresses are allowed in RCPT TO commands. + smtpd_etrn_restrictions + Restrict what domain names can be used in ETRN com- + mands, and what clients may issue ETRN commands. + maps_rbl_domains - List of DNS domains that publish the addresses of + List of DNS domains that publish the addresses of blacklisted hosts. 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 - database restriction. - @@ -203,33 +203,37 @@ SMTPD(8) SMTPD(8) SMTPD(8) SMTPD(8) + access_map_reject_code + 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 @@ -238,7 +242,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) @@ -256,10 +260,6 @@ SMTPD(8) SMTPD(8) - - - - 4 diff --git a/postfix/html/uce.html b/postfix/html/uce.html index 51865405e..b86c7f79f 100644 --- a/postfix/html/uce.html +++ b/postfix/html/uce.html @@ -68,6 +68,10 @@ restrictions

+

  • ETRN command restrictions + +

    +

  • Generic restrictions

    @@ -522,6 +526,94 @@ for rejected requests (default: 550). + + +

    ETRN command restrictions

    + +Not really an UCE restriction, the smtpd_etrn_restrictions +parameter restricts what domains may be specified in ETRN commands, +and what clients may issue ETRN commands. + +
    + +
    Default: + +
    By default, the Postfix SMTP server +accepts any ETRN command from any client. + +

    + +

    Syntax: + +
    Specify a list of zero or more restrictions, separated by +whitespace or commas. Restrictions are applied in the order as +specified; the first restriction that matches wins. + +

    + +In addition to restrictions that are specific to ETRN domain names, +you can also specify restrictions based on the information passed +with the HELO/EHLO command, and on the client hostname or network +address. + +

    + +

    Example: + +
    smtpd_etrn_restrictions = permit_mynetworks, reject + +

    + +

    Restrictions: + +
    + + + +
    check_etrn_access maptype:mapname + +
    maptype:mapname
    Search the named access database for the domain specified +in the ETRN command, or its parent domains. Reject the request if +the result is REJECT or "[45]XX text". Permit +the request if the result is anything else. The access_map_reject_code + parameter specifies the result code for rejected requests +(default: 550). + +

    + +

    permit_naked_ip_address + +
    reject_invalid_hostname + +
    reject_unknown_hostname + +
    check_helo_access maptype:mapname + +
    See HELO (EHLO) hostname restrictions. + +

    + +

    reject_unknown_client + +
    permit_mynetworks + +
    check_client_access maptype:mapname + +
    See client name/address restrictions. + +

    + +

    permit + +
    reject + +
    See generic restrictions. + +
    + +
    +

    Generic restrictions

    diff --git a/postfix/html/virtual.5.html b/postfix/html/virtual.5.html index 9b518d62e..5e8de75f7 100644 --- a/postfix/html/virtual.5.html +++ b/postfix/html/virtual.5.html @@ -116,14 +116,14 @@ VIRTUAL(5) VIRTUAL(5) myorigin The domain that is appended to locally-posted mail. + owner_request_special + Give special treatment to owner-xxx and xxx-request + addresses. + SEE ALSO
    cleanup(8) canonicalize and enqueue mail postmap(1) create mapping table -LICENSE - The Secure Mailer license must be distributed with this - software. - @@ -137,6 +137,10 @@ VIRTUAL(5) VIRTUAL(5) VIRTUAL(5) VIRTUAL(5) +LICENSE + The Secure Mailer license must be distributed with this + software. + AUTHOR(S) Wietse Venema IBM T.J. Watson Research @@ -185,10 +189,6 @@ VIRTUAL(5) VIRTUAL(5) - - - - diff --git a/postfix/local/Makefile.in b/postfix/local/Makefile.in index 568b32f16..99c60e1ec 100644 --- a/postfix/local/Makefile.in +++ b/postfix/local/Makefile.in @@ -1,10 +1,10 @@ SHELL = /bin/sh SRCS = alias.c command.c delivered.c dotforward.c file.c forward.c \ include.c indirect.c local.c mailbox.c recipient.c resolve.c token.c \ - deliver_attr.c feature.c maildir.c + deliver_attr.c feature.c maildir.c biff_notify.c OBJS = alias.o command.o delivered.o dotforward.o file.o forward.o \ include.o indirect.o local.o mailbox.o recipient.o resolve.o token.o \ - deliver_attr.o feature.o maildir.o + deliver_attr.o feature.o maildir.o biff_notify.o HDRS = local.h TESTSRC = WARN = -W -Wformat -Wimplicit -Wmissing-prototypes \ @@ -81,6 +81,10 @@ alias.o: local.h alias.o: ../include/been_here.h alias.o: ../include/tok822.h alias.o: ../include/resolve_clnt.h +biff_notify.o: biff_notify.c +biff_notify.o: ../include/sys_defs.h +biff_notify.o: ../include/msg.h +biff_notify.o: biff_notify.h command.o: command.c command.o: ../include/sys_defs.h command.o: ../include/msg.h @@ -270,8 +274,6 @@ mailbox.o: ../include/vstream.h mailbox.o: ../include/mymalloc.h mailbox.o: ../include/stringops.h mailbox.o: ../include/set_eugid.h -mailbox.o: ../include/get_hostname.h -mailbox.o: ../include/make_dirs.h mailbox.o: ../include/mail_copy.h mailbox.o: ../include/safe_open.h mailbox.o: ../include/deliver_flock.h @@ -284,6 +286,7 @@ mailbox.o: ../include/mail_params.h mailbox.o: local.h mailbox.o: ../include/tok822.h mailbox.o: ../include/resolve_clnt.h +mailbox.o: biff_notify.h maildir.o: maildir.c maildir.o: ../include/sys_defs.h maildir.o: ../include/msg.h diff --git a/postfix/local/alias.c b/postfix/local/alias.c index aa94434c4..15654e6e8 100644 --- a/postfix/local/alias.c +++ b/postfix/local/alias.c @@ -26,7 +26,8 @@ /* When an alias exists for recipient \fIname\fR, and an alias /* exists for \fIowner-name\fR, the sender address is changed /* to \fIowner-name\fR, and the owner delivery attribute is -/* set accordingly. +/* set accordingly. This feature is disabled with +/* "owner_request_special = no". /* .PP /* Arguments: /* .IP state @@ -229,10 +230,12 @@ int deliver_alias(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) * Save the dict_lookup() result before something clobbers it. */ #define STR(x) vstring_str(x) +#define OWNER_ASSIGN(own) \ + (own = (var_ownreq_special == 0 ? 0 : \ + concatenate("owner-", state.msg_attr.local, (char *) 0))) expansion = mystrdup(alias_result); - owner = concatenate("owner-", state.msg_attr.local, (char *) 0); - if (maps_find(maps, owner)) { + if (OWNER_ASSIGN(owner) != 0 && maps_find(maps, owner)) { canon_owner = canon_addr_internal(vstring_alloc(10), owner); SET_OWNER_ATTR(state.msg_attr, STR(canon_owner), state.level); } else { @@ -257,7 +260,8 @@ int deliver_alias(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp) "alias database unavailable") : deliver_token_string(state, usr_attr, expansion, (int *) 0)); myfree(expansion); - myfree(owner); + if (owner) + myfree(owner); if (canon_owner) vstring_free(canon_owner); if (alias_pwd) diff --git a/postfix/local/biff_notify.c b/postfix/local/biff_notify.c new file mode 100644 index 000000000..2b02508d3 --- /dev/null +++ b/postfix/local/biff_notify.c @@ -0,0 +1,94 @@ +/*++ +/* NAME +/* biff_notify 3 +/* SUMMARY +/* send biff notification +/* SYNOPSIS +/* #include +/* +/* void biff_notify(text, len) +/* const char *text; +/* int len; +/* DESCRIPTION +/* biff_notify() sends a \fBBIFF\fR notification request to the +/* \fBcomsat\fR daemon. +/* +/* Arguments: +/* .IP text +/* Null-terminated text (username@mailbox-offset). +/* .IP len +/* Length of text, including null terminator. +/* BUGS +/* The \fBBIFF\fR "service" can be a noticeable load for +/* systems that have many logged-in users. +/* 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 "sys_defs.h" +#include +#include +#include +#include + +/* Utility library. */ + +#include + +/* Application-specific. */ + +#include + +/* biff_notify - notify recipient via the biff "protocol" */ + +void biff_notify(const char *text, int len) +{ + static struct sockaddr_in sin; + static int sock = -1; + struct hostent *hp; + struct servent *sp; + + /* + * Initialize a socket address structure, or re-use an existing one. + */ + if (sin.sin_family == 0) { + if ((sp = getservbyname("biff", "udp")) == 0) { + msg_warn("service not found: biff/udp"); + return; + } + if ((hp = gethostbyname("localhost")) == 0) { + msg_warn("host not found: localhost"); + return; + } + if ((int) hp->h_length > (int) sizeof(sin.sin_addr)) { + msg_warn("bad address size %d for localhost", hp->h_length); + return; + } + sin.sin_family = hp->h_addrtype; + sin.sin_port = sp->s_port; + memcpy((char *) &sin.sin_addr, hp->h_addr_list[0], hp->h_length); + } + + /* + * Open a socket, or re-use an existing one. + */ + if (sock < 0 && (sock = socket(AF_INET, SOCK_DGRAM, 0)) < 0) { + msg_warn("socket: %m"); + return; + } + + /* + * Biff! + */ + if (sendto(sock, text, len, 0, (struct sockaddr *) & sin, sizeof(sin)) != len) + msg_warn("biff_notify: %m"); +} diff --git a/postfix/local/biff_notify.h b/postfix/local/biff_notify.h new file mode 100644 index 000000000..b2b8548f9 --- /dev/null +++ b/postfix/local/biff_notify.h @@ -0,0 +1,30 @@ +#ifndef _BIFF_H_INCLUDED_ +#define _BIFF_H_INCLUDED_ + +/*++ +/* NAME +/* biff_notify 3h +/* SUMMARY +/* read logical line +/* SYNOPSIS +/* #include +/* DESCRIPTION +/* .nf + + /* + * External interface. + */ +extern void biff_notify(const char *, 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/local/local.c b/postfix/local/local.c index 8f0d9f6c1..22dcccbe3 100644 --- a/postfix/local/local.c +++ b/postfix/local/local.c @@ -65,7 +65,9 @@ /* The per-user mailbox is either a file in the default UNIX mailbox /* directory (\fB/var/mail/\fIuser\fR or \fB/var/spool/mail/\fIuser\fR) /* or it is a file in the user's home directory with a name specified -/* via the \fBhome_mailbox\fR configuration parameter. +/* via the \fBhome_mailbox\fR configuration parameter. Specify a path +/* name ending in \fB/\fR for \fBqmail\fR-compatible \fBmaildir\fR +/* delivery. /* Mailbox delivery can be delegated to an external command specified /* with the \fBmailbox_command\fR configuration parameter. /* @@ -73,9 +75,16 @@ /* envelope header to each message, prepends a \fBDelivered-To:\fR header /* with the envelope recipient address, prepends a \fB>\fR character to /* lines beginning with "\fBFrom \fR", and appends an empty line. +/* The envelope sender address is available in the \fBReturn-Path:\fR +/* header. /* The mailbox is locked for exclusive access while delivery is in /* progress. In case of problems, an attempt is made to truncate the /* mailbox to its original length. +/* +/* In the case of \fBmaildir\fR delivery, the local daemon prepends +/* a \fBDelivered-To:\fR header with the envelope recipient address. +/* The envelope sender address is available in the \fBReturn-Path:\fR +/* header. /* EXTERNAL COMMAND DELIVERY /* .ad /* .fi @@ -106,21 +115,32 @@ /* The \fBlocal\fR daemon prepends a "\fBFrom \fIsender time_stamp\fR" /* envelope header to each message, prepends a \fBDelivered-To:\fR /* header with the recipient envelope address, and appends an empty line. +/* The envelope sender address is available in the \fBReturn-Path:\fR +/* header. /* EXTERNAL FILE DELIVERY /* .ad /* .fi /* The \fBallow_mail_to_files\fR configuration parameter restricts /* delivery to external files. The default setting (\fBalias, /* forward\fR) forbids file destinations in \fB:include:\fR files. +/* Specify a pathname ending in \fB/\fR for \fBqmail\fR-compatible +/* \fBmaildir\fR delivery. /* /* The \fBlocal\fR daemon prepends a "\fBFrom \fIsender time_stamp\fR" /* envelope header to each message, prepends a \fBDelivered-To:\fR /* header with the recipient envelope address, prepends a \fB>\fR /* character to lines beginning with "\fBFrom \fR", and appends an /* empty line. +/* The envelope sender address is available in the \fBReturn-Path:\fR +/* header. /* When the destination is a regular file, it is locked for exclusive /* access while delivery is in progress. In case of problems, an attempt /* is made to truncate a regular file to its original length. +/* +/* In the case of \fBmaildir\fR delivery, the local daemon prepends +/* a \fBDelivered-To:\fR header with the envelope recipient address. +/* The envelope sender address is available in the \fBReturn-Path:\fR +/* header. /* ADDRESS EXTENSION /* .ad /* .fi @@ -179,7 +199,7 @@ /* List of alias databases. /* .IP \fBhome_mailbox\fR /* Pathname of a mailbox relative to a user's home directory. -/* Specify \fBmaildir\fR for maildir-style delivery. +/* Specify a path ending in \fB/\fR for maildir-style delivery. /* .IP \fBlocal_command_shell\fR /* Shell to use for external command execution (for example, /* /some/where/smrsh -c). @@ -187,6 +207,9 @@ /* contains no shell built-in commands or meta characters. /* .IP \fBmailbox_command\fR /* External command to use for mailbox delivery. +/* .IP \fBowner_request_special\fR +/* Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +/* addresses. /* .IP \fBrecipient_delimiter\fR /* Separator between username and address extension. /* .SH "Locking controls" @@ -303,6 +326,7 @@ char *var_home_mailbox; char *var_mailbox_command; char *var_rcpt_fdelim; char *var_local_cmd_shell; +int var_biff; int local_cmd_deliver_mask; int local_file_deliver_mask; @@ -458,10 +482,15 @@ int main(int argc, char **argv) VAR_LOCAL_CMD_SHELL, DEF_LOCAL_CMD_SHELL, &var_local_cmd_shell, 0, 0, 0, }; + static CONFIG_BOOL_TABLE bool_table[] = { + VAR_BIFF, DEF_BIFF, &var_biff, + 0, + }; single_server_main(argc, argv, local_service, MAIL_SERVER_INT_TABLE, int_table, MAIL_SERVER_STR_TABLE, str_table, + MAIL_SERVER_BOOL_TABLE, bool_table, MAIL_SERVER_POST_INIT, post_init, 0); } diff --git a/postfix/local/mailbox.c b/postfix/local/mailbox.c index 6781c51fa..576bca22b 100644 --- a/postfix/local/mailbox.c +++ b/postfix/local/mailbox.c @@ -76,6 +76,7 @@ /* Application-specific. */ #include "local.h" +#include "biff_notify.h" /* deliver_mailbox_file - deliver to recipient mailbox */ @@ -86,6 +87,8 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) VSTREAM *dst; int status; int copy_flags; + VSTRING *biff; + long end; if (msg_verbose) msg_info("deliver_mailbox_file: %s", state.msg_attr.recipient); @@ -124,11 +127,20 @@ static int deliver_mailbox_file(LOCAL_STATE state, USER_ATTR usr_attr) S_IRUSR | S_IWUSR, usr_attr.uid, usr_attr.gid, why); set_eugid(usr_attr.uid, usr_attr.gid); if (dst != 0) { + end = vstream_fseek(dst, (off_t) 0, SEEK_END); if (deliver_flock(vstream_fileno(dst), why) < 0) vstream_fclose(dst); else if (mail_copy(COPY_ATTR(state.msg_attr), dst, - copy_flags, why) == 0) + copy_flags, why) == 0) { status = 0; + if (var_biff) { + biff = vstring_alloc(100); + vstring_sprintf(biff, "%s@%ld", usr_attr.logname, + (long) end); + biff_notify(vstring_str(biff), VSTRING_LEN(biff) + 1); + vstring_free(biff); + } + } } #ifdef USE_DOT_LOCK set_eugid(0, 0); diff --git a/postfix/local/maildir.c b/postfix/local/maildir.c index a67ce0c09..0cbad5a9b 100644 --- a/postfix/local/maildir.c +++ b/postfix/local/maildir.c @@ -71,6 +71,7 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) { char *newdir; char *tmpdir; + char *curdir; char *tmpfile; char *newfile; VSTRING *why; @@ -100,16 +101,27 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) newdir = concatenate(path, "new/", (char *) 0); tmpdir = concatenate(path, "tmp/", (char *) 0); + curdir = concatenate(path, "cur/", (char *) 0); /* * Create and write the file as the recipient, so that file quota work. - * Create any missing directories on the fly. + * Create any missing directories on the fly. The file name is chosen + * according to ftp://koobera.math.uic.edu/www/proto/maildir.html: + * + * "A unique name has three pieces, separated by dots. On the left is the + * result of time(). On the right is the result of gethostname(). In the + * middle is something that doesn't repeat within one second on a single + * host. I fork a new process for each delivery, so I just use the + * process ID. If you're delivering several messages from one process, + * use starttime.pid_count.host, where starttime is the time that your + * process started, and count is the number of messages you've + * delivered." */ #define STR vstring_str set_eugid(usr_attr.uid, usr_attr.gid); - vstring_sprintf(buf, "%ld.%d.%s.%d", (long) time((time_t *) 0), - var_pid, get_hostname(), count++); + vstring_sprintf(buf, "%ld.%d_%d.%s", (long) var_starttime, + var_pid, count++, get_hostname()); tmpfile = concatenate(tmpdir, STR(buf), (char *) 0); newfile = concatenate(newdir, STR(buf), (char *) 0); if ((dst = vstream_fopen(tmpfile, O_WRONLY | O_CREAT | O_EXCL, 0600)) == 0 @@ -121,7 +133,7 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) if (mail_copy(COPY_ATTR(state.msg_attr), dst, copy_flags, why) == 0) { if (link(tmpfile, newfile) < 0 && (errno != ENOENT - || make_dirs(newdir, 0700) < 0 + || (make_dirs(curdir,0700), make_dirs(newdir, 0700)) < 0 || link(tmpfile, newfile) < 0)) { vstring_sprintf(why, "link to %s: %m", newfile); } else { @@ -142,6 +154,7 @@ int deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path) vstring_free(why); myfree(newdir); myfree(tmpdir); + myfree(curdir); myfree(tmpfile); myfree(newfile); return (0); diff --git a/postfix/man/man5/aliases.5 b/postfix/man/man5/aliases.5 index 8be356658..e9e860cad 100644 --- a/postfix/man/man5/aliases.5 +++ b/postfix/man/man5/aliases.5 @@ -106,6 +106,9 @@ List of alias databases. Restrict the usage of mail delivery to external command. .IP \fBallow_mail_to_files\fR Restrict the usage of mail delivery to external file. +.IP \fBowner_request_special\fR +Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +addresses. .IP \fBrecipient_delimiter\fR Delimiter that separates recipients from address extensions. .SH STANDARDS diff --git a/postfix/man/man5/canonical.5 b/postfix/man/man5/canonical.5 index 8ddaa6e81..6c1c6dfdb 100644 --- a/postfix/man/man5/canonical.5 +++ b/postfix/man/man5/canonical.5 @@ -106,6 +106,9 @@ List of user names that are not subject to address masquerading. List of domains that this mail system considers local. .IP \fBmyorigin\fR The domain that is appended to locally-posted mail. +.IP \fBowner_request_special\fR +Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +addresses. .SH SEE ALSO .na .nf diff --git a/postfix/man/man5/virtual.5 b/postfix/man/man5/virtual.5 index c969af7d2..b9ee2157f 100644 --- a/postfix/man/man5/virtual.5 +++ b/postfix/man/man5/virtual.5 @@ -99,6 +99,9 @@ The network interface addresses that this system receives mail on. List of domains that this mail system considers local. .IP \fBmyorigin\fR The domain that is appended to locally-posted mail. +.IP \fBowner_request_special\fR +Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +addresses. .SH SEE ALSO .na .nf diff --git a/postfix/man/man8/local.8 b/postfix/man/man8/local.8 index 3ecd49db2..4fd9efaa4 100644 --- a/postfix/man/man8/local.8 +++ b/postfix/man/man8/local.8 @@ -77,7 +77,9 @@ mail arrives for a recipient that is already listed in a The per-user mailbox is either a file in the default UNIX mailbox directory (\fB/var/mail/\fIuser\fR or \fB/var/spool/mail/\fIuser\fR) or it is a file in the user's home directory with a name specified -via the \fBhome_mailbox\fR configuration parameter. +via the \fBhome_mailbox\fR configuration parameter. Specify a path +name ending in \fB/\fR for \fBqmail\fR-compatible \fBmaildir\fR +delivery. Mailbox delivery can be delegated to an external command specified with the \fBmailbox_command\fR configuration parameter. @@ -85,9 +87,16 @@ The \fBlocal\fR daemon prepends a "\fBFrom \fIsender time_stamp\fR" envelope header to each message, prepends a \fBDelivered-To:\fR header with the envelope recipient address, prepends a \fB>\fR character to lines beginning with "\fBFrom \fR", and appends an empty line. +The envelope sender address is available in the \fBReturn-Path:\fR +header. The mailbox is locked for exclusive access while delivery is in progress. In case of problems, an attempt is made to truncate the mailbox to its original length. + +In the case of \fBmaildir\fR delivery, the local daemon prepends +a \fBDelivered-To:\fR header with the envelope recipient address. +The envelope sender address is available in the \fBReturn-Path:\fR +header. .SH EXTERNAL COMMAND DELIVERY .na .nf @@ -120,6 +129,8 @@ The current working directory is the mail queue directory. The \fBlocal\fR daemon prepends a "\fBFrom \fIsender time_stamp\fR" envelope header to each message, prepends a \fBDelivered-To:\fR header with the recipient envelope address, and appends an empty line. +The envelope sender address is available in the \fBReturn-Path:\fR +header. .SH EXTERNAL FILE DELIVERY .na .nf @@ -128,15 +139,24 @@ header with the recipient envelope address, and appends an empty line. The \fBallow_mail_to_files\fR configuration parameter restricts delivery to external files. The default setting (\fBalias, forward\fR) forbids file destinations in \fB:include:\fR files. +Specify a pathname ending in \fB/\fR for \fBqmail\fR-compatible +\fBmaildir\fR delivery. The \fBlocal\fR daemon prepends a "\fBFrom \fIsender time_stamp\fR" envelope header to each message, prepends a \fBDelivered-To:\fR header with the recipient envelope address, prepends a \fB>\fR character to lines beginning with "\fBFrom \fR", and appends an empty line. +The envelope sender address is available in the \fBReturn-Path:\fR +header. When the destination is a regular file, it is locked for exclusive access while delivery is in progress. In case of problems, an attempt is made to truncate a regular file to its original length. + +In the case of \fBmaildir\fR delivery, the local daemon prepends +a \fBDelivered-To:\fR header with the envelope recipient address. +The envelope sender address is available in the \fBReturn-Path:\fR +header. .SH ADDRESS EXTENSION .na .nf @@ -207,7 +227,7 @@ a configuration change. List of alias databases. .IP \fBhome_mailbox\fR Pathname of a mailbox relative to a user's home directory. -Specify \fBmaildir\fR for maildir-style delivery. +Specify a path ending in \fB/\fR for maildir-style delivery. .IP \fBlocal_command_shell\fR Shell to use for external command execution (for example, /some/where/smrsh -c). @@ -215,6 +235,9 @@ When a shell is specified, it is invoked even when the command contains no shell built-in commands or meta characters. .IP \fBmailbox_command\fR External command to use for mailbox delivery. +.IP \fBowner_request_special\fR +Give special treatment to \fBowner-\fIxxx\fR and \fIxxx\fB-request\fR +addresses. .IP \fBrecipient_delimiter\fR Separator between username and address extension. .SH "Locking controls" diff --git a/postfix/man/man8/smtpd.8 b/postfix/man/man8/smtpd.8 index c2923b75e..af86f29f0 100644 --- a/postfix/man/man8/smtpd.8 +++ b/postfix/man/man8/smtpd.8 @@ -140,6 +140,9 @@ Restrict what client hostnames are allowed in \fBHELO\fR and Restrict what sender addresses are allowed in \fBMAIL FROM\fR commands. .IP \fBsmtpd_recipient_restrictions\fR Restrict what recipient addresses are allowed in \fBRCPT TO\fR commands. +.IP \fBsmtpd_etrn_restrictions\fR +Restrict what domain names can be used in \fBETRN\fR commands, +and what clients may issue \fBETRN\fR commands. .IP \fBmaps_rbl_domains\fR List of DNS domains that publish the addresses of blacklisted hosts. diff --git a/postfix/qmgr/Makefile.in b/postfix/qmgr/Makefile.in index 645ea3a27..4688f33bf 100644 --- a/postfix/qmgr/Makefile.in +++ b/postfix/qmgr/Makefile.in @@ -149,6 +149,7 @@ qmgr_message.o: ../include/vstream.h qmgr_message.o: ../include/split_at.h qmgr_message.o: ../include/valid_hostname.h qmgr_message.o: ../include/argv.h +qmgr_message.o: ../include/stringops.h qmgr_message.o: ../include/dict.h qmgr_message.o: ../include/mail_queue.h qmgr_message.o: ../include/mail_params.h diff --git a/postfix/qmgr/qmgr_message.c b/postfix/qmgr/qmgr_message.c index 3d185959e..4d4cfa48a 100644 --- a/postfix/qmgr/qmgr_message.c +++ b/postfix/qmgr/qmgr_message.c @@ -88,6 +88,7 @@ #include #include #include +#include /* Global library. */ @@ -381,6 +382,8 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) const char *newloc; char *at; char **cpp; + char *domain; + const char *junk; #define STREQ(x,y) (strcasecmp(x,y) == 0) #define STR vstring_str @@ -443,11 +446,15 @@ static void qmgr_message_resolve(QMGR_MESSAGE *message) */ if (VSTRING_LEN(reply.nexthop) > 0 && qmgr_virtual != 0 - && (at = strrchr(recipient->address, '@')) != 0 - && maps_find(qmgr_virtual, at + 1)) { - qmgr_bounce_recipient(message, recipient, + && (at = strrchr(recipient->address, '@')) != 0) { + domain = lowercase(mystrdup(at + 1)); + junk = maps_find(qmgr_virtual, domain); + myfree(domain); + if (junk) { + qmgr_bounce_recipient(message, recipient, "unknown user: \"%s\"", recipient->address); - continue; + continue; + } } /* diff --git a/postfix/sendmail/sendmail.c b/postfix/sendmail/sendmail.c index 2df9d7110..a7db22a4c 100644 --- a/postfix/sendmail/sendmail.c +++ b/postfix/sendmail/sendmail.c @@ -726,7 +726,7 @@ int main(int argc, char **argv) if (extract_recipients && mode != SM_MODE_ENQUEUE) msg_fatal("-t can be used only in delivery mode"); - if (extract_recipients && argv[optind]) + if (extract_recipients && argv[OPTIND]) msg_fatal("cannot delete recipients with -t"); /* @@ -739,7 +739,7 @@ int main(int argc, char **argv) msg_panic("unknown operation mode: %d", mode); /* NOTREACHED */ case SM_MODE_ENQUEUE: - enqueue(sender, full_name, argv + optind); + enqueue(sender, full_name, argv + OPTIND); exit(0); break; case SM_MODE_MAILQ: @@ -751,7 +751,7 @@ int main(int argc, char **argv) exit(0); break; case SM_MODE_DAEMON: - if (argv[optind]) + if (argv[OPTIND]) msg_fatal("daemon mode requires no recipient"); ext_argv = argv_alloc(2); argv_add(ext_argv, "postfix", (char *) 0); @@ -764,7 +764,7 @@ int main(int argc, char **argv) exit(err); break; case SM_MODE_NEWALIAS: - if (argv[optind]) + if (argv[OPTIND]) msg_fatal("alias initialization mode requires no recipient"); ext_argv = argv_alloc(2); argv_add(ext_argv, "postalias", (char *) 0); @@ -774,7 +774,7 @@ int main(int argc, char **argv) mail_run_replace(var_command_dir, ext_argv->argv); /* NOTREACHED */ case SM_MODE_USER: - if (argv[optind]) + if (argv[OPTIND]) msg_fatal("stand-alone mode requires no recipient"); ext_argv = argv_alloc(2); argv_add(ext_argv, "smtpd", "-S", (char *) 0); diff --git a/postfix/smtpd/Makefile.in b/postfix/smtpd/Makefile.in index a8736d8c8..ad0665084 100644 --- a/postfix/smtpd/Makefile.in +++ b/postfix/smtpd/Makefile.in @@ -78,6 +78,7 @@ smtpd.o: ../include/stringops.h smtpd.o: ../include/events.h smtpd.o: ../include/smtp_stream.h smtpd.o: ../include/peer_name.h +smtpd.o: ../include/valid_hostname.h smtpd.o: ../include/mail_params.h smtpd.o: ../include/record.h smtpd.o: ../include/rec_type.h diff --git a/postfix/smtpd/smtpd.c b/postfix/smtpd/smtpd.c index 795941e36..a19fe013a 100644 --- a/postfix/smtpd/smtpd.c +++ b/postfix/smtpd/smtpd.c @@ -124,6 +124,9 @@ /* Restrict what sender addresses are allowed in \fBMAIL FROM\fR commands. /* .IP \fBsmtpd_recipient_restrictions\fR /* Restrict what recipient addresses are allowed in \fBRCPT TO\fR commands. +/* .IP \fBsmtpd_etrn_restrictions\fR +/* Restrict what domain names can be used in \fBETRN\fR commands, +/* and what clients may issue \fBETRN\fR commands. /* .IP \fBmaps_rbl_domains\fR /* List of DNS domains that publish the addresses of blacklisted /* hosts. @@ -203,6 +206,7 @@ #include #include #include +#include /* Global library. */ @@ -253,6 +257,7 @@ char *var_client_checks; char *var_helo_checks; char *var_mail_checks; char *var_rcpt_checks; +char *var_etrn_checks; int var_unk_client_code; int var_bad_name_code; int var_unk_name_code; @@ -789,13 +794,43 @@ static int vrfy_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) static int etrn_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv) { + char *err; /* * Sanity checks. */ + if (var_helo_required && state->helo_name == 0) { + state->error_mask |= MAIL_ERROR_POLICY; + smtpd_chat_reply(state, "503 Error: send HELO/EHLO first"); + return (-1); + } + if (state->cleanup != 0) { + state->error_mask |= MAIL_ERROR_PROTOCOL; + smtpd_chat_reply(state, "503 Error: MAIL transaction in progress"); + return (-1); + } if (argc != 2) { state->error_mask |= MAIL_ERROR_PROTOCOL; - smtpd_chat_reply(state, "501 Syntax: ETRN domain"); + smtpd_chat_reply(state, "500 Syntax: ETRN domain"); + return (-1); + } + if (!ISALNUM(argv[1].strval[0])) + argv[1].strval++; + if (!valid_hostname(argv[1].strval)) { + state->error_mask |= MAIL_ERROR_PROTOCOL; + smtpd_chat_reply(state, "501 Error: invalid parameter syntax"); + return (-1); + } + + /* + * XXX The implementation borrows heavily from the code that implements + * UCE restrictions. These typically return 450 or 550 when a request is + * rejected. RFC 1985 requires that 459 be sent when the server refuses + * to perform the request. + */ + if (SMTPD_STAND_ALONE(state) == 0 + && (err = smtpd_check_etrn(state, argv[1].strval)) != 0) { + smtpd_chat_reply(state, "%s", err); return (-1); } @@ -1103,6 +1138,7 @@ int main(int argc, char **argv) VAR_HELO_CHECKS, DEF_HELO_CHECKS, &var_helo_checks, 0, 0, VAR_MAIL_CHECKS, DEF_MAIL_CHECKS, &var_mail_checks, 0, 0, VAR_RCPT_CHECKS, DEF_RCPT_CHECKS, &var_rcpt_checks, 0, 0, + VAR_ETRN_CHECKS, DEF_ETRN_CHECKS, &var_etrn_checks, 0, 0, VAR_MAPS_RBL_DOMAINS, DEF_MAPS_RBL_DOMAINS, &var_maps_rbl_domains, 0, 0, 0, }; diff --git a/postfix/smtpd/smtpd_check.c b/postfix/smtpd/smtpd_check.c index c88a76ab6..b4c407798 100644 --- a/postfix/smtpd/smtpd_check.c +++ b/postfix/smtpd/smtpd_check.c @@ -23,6 +23,10 @@ /* char *smtpd_check_rcpt(state, recipient) /* SMTPD_STATE *state; /* char *recipient; +/* +/* char *smtpd_check_etrn(state, recipient) +/* SMTPD_STATE *state; +/* char *recipient; /* DESCRIPTION /* This module implements additional checks on SMTP client requests. /* A client request is validated in the context of the session state. @@ -116,28 +120,35 @@ /* .PP /* smtpd_check_client() validates the client host name or address. /* Relevant configuration parameters: -/* .IP client_restrictions +/* .IP smtpd_client_restrictions /* Restrictions on the names or addresses of clients that may connect /* to this SMTP server. /* .PP /* smtpd_check_helo() validates the hostname provided with the /* HELO/EHLO commands. Relevant configuration parameters: -/* .IP helo_restrictions +/* .IP smtpd_helo_restrictions /* Restrictions on the hostname that is sent with the HELO/EHLO /* command. /* .PP /* smtpd_check_mail() validates the sender address provided with /* a MAIL FROM request. Relevant configuration parameters: -/* .IP sender_restrictions +/* .IP smtpd_sender_restrictions /* Restrictions on the sender address that is sent with the MAIL FROM /* command. /* .PP /* smtpd_check_rcpt() validates the recipient address provided /* with an RCPT TO request. Relevant configuration parameters: -/* .IP recipient_restrictions +/* .IP smtpd_recipient_restrictions /* Restrictions on the recipient address that is sent with the RCPT /* TO command. /* .PP +/* smtpd_check_etrn() validates the domain name provided with the +/* ETRN command, and other client-provided information. Relevant +/* configuration parameters: +/* .IP smtpd_etrn_restrictions +/* Restrictions on the hostname that is sent with the HELO/EHLO +/* command. +/* .PP /* smtpd_check_size() checks if a message with the given size can /* be received (zero means that the message size is unknown). The /* message is rejected when: @@ -268,6 +279,7 @@ static ARGV *client_restrctions; static ARGV *helo_restrctions; static ARGV *mail_restrctions; static ARGV *rcpt_restrctions; +static ARGV *etrn_restrctions; #define STR vstring_str @@ -325,6 +337,7 @@ void smtpd_check_init(void) helo_restrctions = smtpd_check_parse(var_helo_checks); mail_restrctions = smtpd_check_parse(var_mail_checks); rcpt_restrctions = smtpd_check_parse(var_rcpt_checks); + etrn_restrctions = smtpd_check_parse(var_etrn_checks); } /* smtpd_check_reject - do the boring things that must be done */ @@ -493,12 +506,10 @@ static int check_relay_domains(SMTPD_STATE *state, char *recipient) return (SMTPD_CHECK_OK); /* - * Resolve the address if not yet done. + * Resolve the address. */ - if (VSTRING_LEN(reply.recipient) == 0) { - canon_addr_internal(reply.recipient, recipient); - resolve_clnt_query(STR(reply.recipient), &reply); - } + canon_addr_internal(reply.recipient, recipient); + resolve_clnt_query(STR(reply.recipient), &reply); /* * Permit if destination is local. XXX This must be generalized for @@ -578,12 +589,10 @@ static int permit_mx_backup(SMTPD_STATE *unused_state, const char *recipient) msg_info("%s: %s", myname, recipient); /* - * Resolve the address if not yet done. + * Resolve the address. */ - if (VSTRING_LEN(reply.recipient) == 0) { - canon_addr_internal(reply.recipient, recipient); - resolve_clnt_query(STR(reply.recipient), &reply); - } + canon_addr_internal(reply.recipient, recipient); + resolve_clnt_query(STR(reply.recipient), &reply); /* * If the destination is local, it is acceptable, because we are @@ -661,12 +670,10 @@ static int reject_unknown_address(SMTPD_STATE *state, char *addr) msg_info("%s: %s", myname, addr); /* - * Resolve the address if not yet done. + * Resolve the address. */ - if (VSTRING_LEN(reply.recipient) == 0) { - canon_addr_internal(reply.recipient, addr); - resolve_clnt_query(STR(reply.recipient), &reply); - } + canon_addr_internal(reply.recipient, addr); + resolve_clnt_query(STR(reply.recipient), &reply); /* * Skip local destinations and non-DNS forms. @@ -833,12 +840,10 @@ static int check_mail_access(SMTPD_STATE *state, char *table, char *addr) msg_info("%s: %s", myname, addr); /* - * Resolve the address if not yet done. + * Resolve the address. */ - if (VSTRING_LEN(reply.recipient) == 0) { - canon_addr_internal(reply.recipient, addr); - resolve_clnt_query(STR(reply.recipient), &reply); - } + canon_addr_internal(reply.recipient, addr); + resolve_clnt_query(STR(reply.recipient), &reply); /* * Garbage in, garbage out. Every address from canon_addr_internal() and @@ -1051,7 +1056,6 @@ char *smtpd_check_client(SMTPD_STATE *state) /* * Initialize. */ - VSTRING_RESET(reply.recipient); status = setjmp(smtpd_check_buf); if (status != 0) return (0); @@ -1083,7 +1087,6 @@ char *smtpd_check_helo(SMTPD_STATE *state, char *helohost) /* * Initialize. */ - VSTRING_RESET(reply.recipient); status = setjmp(smtpd_check_buf); if (status != 0) return (0); @@ -1119,7 +1122,6 @@ char *smtpd_check_mail(SMTPD_STATE *state, char *sender) /* * Initialize. */ - VSTRING_RESET(reply.recipient); status = setjmp(smtpd_check_buf); if (status != 0) return (0); @@ -1155,7 +1157,6 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) /* * Initialize. */ - VSTRING_RESET(reply.recipient); status = setjmp(smtpd_check_buf); if (status != 0) return (0); @@ -1182,6 +1183,39 @@ char *smtpd_check_rcpt(SMTPD_STATE *state, char *recipient) return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); } +/* smtpd_check_etrn - validate ETRN request */ + +char *smtpd_check_etrn(SMTPD_STATE *state, char *domain) +{ + char **cpp; + char *name; + int status; + + /* + * Initialize. + */ + status = setjmp(smtpd_check_buf); + if (status != 0) + return (0); + + /* + * Apply restrictions in the order as specified. + */ + for (cpp = etrn_restrctions->argv; (name = *cpp) != 0; cpp++) { + if (strchr(name, ':') != 0) { + status = check_domain_access(state, name, domain); + } else if (is_map_command(name, CHECK_ETRN_ACL, &cpp)) { + status = check_domain_access(state, *cpp, domain); + } else if (generic_checks(state, name, &cpp, &status, domain) == 0) { + msg_warn("unknown %s check: \"%s\"", VAR_RCPT_CHECKS, name); + break; + } + if (status != 0) + break; + } + return (status == SMTPD_CHECK_REJECT ? STR(error_text) : 0); +} + /* smtpd_check_size - check optional SIZE parameter value */ char *smtpd_check_size(SMTPD_STATE *state, off_t size) @@ -1358,13 +1392,14 @@ static int int_update(char **argv) typedef struct { char *name; ARGV **target; -} REST_TABLE; +} REST_TABLE; static REST_TABLE rest_table[] = { "client_restrictions", &client_restrctions, "helo_restrictions", &helo_restrctions, "sender_restrictions", &mail_restrctions, "recipient_restrictions", &rcpt_restrctions, + "etrn_restrictions", &etrn_restrctions, 0, }; diff --git a/postfix/smtpd/smtpd_check.h b/postfix/smtpd/smtpd_check.h index 966889325..74f013b09 100644 --- a/postfix/smtpd/smtpd_check.h +++ b/postfix/smtpd/smtpd_check.h @@ -18,6 +18,7 @@ extern char *smtpd_check_helo(SMTPD_STATE *, char *); extern char *smtpd_check_mail(SMTPD_STATE *, char *); extern char *smtpd_check_size(SMTPD_STATE *, off_t); extern char *smtpd_check_rcpt(SMTPD_STATE *, char *); +extern char *smtpd_check_etrn(SMTPD_STATE *, char *); /* LICENSE /* .ad diff --git a/postfix/util/doze.c b/postfix/util/doze.c index ac34529c2..d33da8ad9 100644 --- a/postfix/util/doze.c +++ b/postfix/util/doze.c @@ -30,6 +30,9 @@ #include #include #include +#ifdef USE_SYS_SELECT_H +#include +#endif /* Utility library. */