Bugfix: in Received: headers, the "for <recipient>"
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.
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
-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:
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...".
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)
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);
# 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
# 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
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
}
# 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
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
/* Global library. */
+#include "mail_params.h"
#include "mail_proto.h"
#include "defer.h"
#include "bounce.h"
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");
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) {
/* 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;
#include <unistd.h>
#include <string.h>
#include <pwd.h>
+#include <time.h>
#ifdef STRCASECMP_IN_STRINGS_H
#include <strings.h>
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
};
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,
};
*/
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.
*/
#endif
extern char *var_pid_dir;
+ /*
+ * Program startup time.
+ */
+extern time_t var_starttime;
+
/*
* Location of configuration files.
*/
#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.
*/
#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
#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"
#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
* 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
/* 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
char *split_addr(char *localpart, int delimiter)
{
- int len;
+ int len;
/*
* Don't split these, regardless of what the delimiter is.
/*
* 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.
ALIASES(5) ALIASES(5)
+ <b>owner</b><i>_</i><b>request</b><i>_</i><b>special</b>
+ Give special treatment to <b>owner-</b><i>xxx</i> and <i>xxx</i><b>-request</b>
+ addresses.
+
<b>recipient</b><i>_</i><b>delimiter</b>
- Delimiter that separates recipients from address
+ Delimiter that separates recipients from address
extensions.
<b>STANDARDS</b>
<a href="postalias.1.html">postalias(1)</a> alias database management
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
-
-
-
-
<b>myorigin</b>
The domain that is appended to locally-posted mail.
+ <b>owner</b><i>_</i><b>request</b><i>_</i><b>special</b>
+ Give special treatment to <b>owner-</b><i>xxx</i> and <i>xxx</i><b>-request</b>
+ addresses.
+
<b>SEE</b> <b>ALSO</b>
<a href="cleanup.8.html">cleanup(8)</a> canonicalize and enqueue mail
<a href="postmap.1.html">postmap(1)</a> create mapping table
<a href="virtual.5.html">virtual(5)</a> virtual domain mapping
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
-
-
-
-
<p>
Postfix supports the <b>maildir</b> mailbox format. Edit <b>main.cf</b>
-and specify a line with: <b>home_mailbox = maildir</b>.
+and specify a line with: <b>home_mailbox = Maildir/</b> (any relative
+pathname that ends in <b>/</b> will do).
+
+<p>
+
+The maildir format is also supported for delivery from aliases or
+<b>.forward</b> files. Specify <i>/file/name/</i> as destination.
+The trailing <b>/</b> turns on <b>maildir</b> delivery.
<hr>
<pre>
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)
</pre>
<p>
<pre>
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)
</pre>
This runs the <b>uux</b> command, and substitutes the next-hop
mailbox directory (<b>/var/mail/</b><i>user</i> or <b>/var/spool/mail/</b><i>user</i>)
or it is a file in the user's home directory with a name
specified via the <b>home</b><i>_</i><b>mailbox</b> configuration parameter.
- Mailbox delivery can be delegated to an external command
- specified with the <b>mailbox</b><i>_</i><b>command</b> configuration parame-
- ter.
+ Specify a path name ending in <b>/</b> for <b>qmail</b>-compatible
+ <b>maildir</b> delivery. Mailbox delivery can be delegated to an
+ external command specified with the <b>mailbox</b><i>_</i><b>command</b> con-
+ figuration parameter.
The <b>local</b> daemon prepends a "<b>From</b> <i>sender</i> <i>time_stamp</i>" enve-
- lope header to each message, prepends a <b>Delivered-To:</b>
- header with the envelope recipient address, prepends a >
- character to lines beginning with "<b>From</b> ", 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 <b>Delivered-To:</b>
+ header with the envelope recipient address, prepends a >
+ character to lines beginning with "<b>From</b> ", and appends an
+ empty line. The envelope sender address is available in
+ the <b>Return-Path:</b> 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 <b>maildir</b> delivery, the local daemon prepends
+ a <b>Delivered-To:</b> header with the envelope recipient
+ address. The envelope sender address is available in the
+ <b>Return-Path:</b> header.
<b>EXTERNAL</b> <b>COMMAND</b> <b>DELIVERY</b>
- The <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b> configuration parameter
- restricts delivery to external commands. The default set-
- ting (<b>alias,</b> <b>forward</b>) forbids command destinations in
+ The <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b> configuration parameter
+ restricts delivery to external commands. The default set-
+ ting (<b>alias,</b> <b>forward</b>) forbids command destinations in
<b>:include:</b> files.
- The command is executed directly where possible. Assis-
- tance by the shell (<b>/bin/sh</b> 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 (<b>/bin/sh</b> 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 <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> 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 <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b> seconds.
+ Command exit status codes are expected to follow the con-
ventions defined in <<b>sysexits.h</b>>.
When mail is delivered on behalf of a user, the <b>HOME</b>, <b>LOG-</b>
dependent default path, and the <b>TZ</b> (time zone) environment
variable is always passed on without change.
- The current working directory is the mail queue directory.
-
- The <b>local</b> daemon prepends a "<b>From</b> <i>sender</i> <i>time_stamp</i>" enve-
- lope header to each message, prepends a <b>Delivered-To:</b>
- header with the recipient envelope address, and appends an
- empty line.
-
LOCAL(8) LOCAL(8)
+ The current working directory is the mail queue directory.
+
+ The <b>local</b> daemon prepends a "<b>From</b> <i>sender</i> <i>time_stamp</i>" enve-
+ lope header to each message, prepends a <b>Delivered-To:</b>
+ header with the recipient envelope address, and appends an
+ empty line. The envelope sender address is available in
+ the <b>Return-Path:</b> header.
+
<b>EXTERNAL</b> <b>FILE</b> <b>DELIVERY</b>
The <b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>files</b> configuration parameter restricts
delivery to external files. The default setting (<b>alias,</b>
- <b>forward</b>) forbids file destinations in <b>:include:</b> files.
+ <b>forward</b>) forbids file destinations in <b>:include:</b> files.
+ Specify a pathname ending in <b>/</b> for <b>qmail</b>-compatible
+ <b>maildir</b> delivery.
The <b>local</b> daemon prepends a "<b>From</b> <i>sender</i> <i>time_stamp</i>" enve-
lope header to each message, prepends a <b>Delivered-To:</b>
header with the recipient envelope address, prepends a >
character to lines beginning with "<b>From</b> ", 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 <b>Return-Path:</b> 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 <b>maildir</b> delivery, the local daemon prepends
+ a <b>Delivered-To:</b> header with the envelope recipient
+ address. The envelope sender address is available in the
+ <b>Return-Path:</b> header.
<b>ADDRESS</b> <b>EXTENSION</b>
The optional <b>recipient</b><i>_</i><b>delimiter</b> configuration parameter
superuser, delivery is made with the rights specified with
the <b>default</b><i>_</i><b>privs</b> configuration parameter.
+
+
+
+
+ 3
+
+
+
+
+
+LOCAL(8) LOCAL(8)
+
+
<b>STANDARDS</b>
RFC 822 (ARPA Internet Text Messages)
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 ~/.<b>forward</b> files are not
detected early. The resulting mail forwarding loop is
<b>home</b><i>_</i><b>mailbox</b>
Pathname of a mailbox relative to a user's home
- directory. Specify <b>maildir</b> for maildir-style
- delivery.
+ directory. Specify a path ending in <b>/</b> for maildir-
+ style delivery.
<b>local</b><i>_</i><b>command</b><i>_</i><b>shell</b>
Shell to use for external command execution (for
<b>mailbox</b><i>_</i><b>command</b>
External command to use for mailbox delivery.
+ <b>owner</b><i>_</i><b>request</b><i>_</i><b>special</b>
+ Give special treatment to <b>owner-</b><i>xxx</i> and <i>xxx</i><b>-request</b>
+ addresses.
+
<b>recipient</b><i>_</i><b>delimiter</b>
Separator between username and address extension.
+
+
+ 4
+
+
+
+
+
+LOCAL(8) LOCAL(8)
+
+
<b>Locking</b> <b>controls</b>
<b>deliver</b><i>_</i><b>lock</b><i>_</i><b>attempts</b>
- Limit the number of attempts to acquire an exclu-
+ Limit the number of attempts to acquire an exclu-
sive lock on a mailbox or external file.
<b>deliver</b><i>_</i><b>lock</b><i>_</i><b>delay</b>
- Time in seconds between successive attempts to
+ Time in seconds between successive attempts to
acquire an exclusive lock.
<b>stale</b><i>_</i><b>lock</b><i>_</i><b>time</b>
<b>Resource</b> <b>controls</b>
<b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b>
- Limit the amount of time for delivery to external
+ Limit the amount of time for delivery to external
command.
<b>duplicate</b><i>_</i><b>filter</b><i>_</i><b>limit</b>
- Limit the size of the duplicate filter for results
+ Limit the size of the duplicate filter for results
from alias etc. expansion.
-
-
- 4
-
-
-
-
-
-LOCAL(8) LOCAL(8)
-
-
<b>line</b><i>_</i><b>length</b><i>_</i><b>limit</b>
- Limit the amount of memory used for processing a
+ Limit the amount of memory used for processing a
partial input line.
<b>local</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b>
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
<b>default</b><i>_</i><b>destination</b><i>_</i><b>concurrency</b><i>_</i><b>limit</b> parameter.
<b>local</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
- 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
<b>default</b><i>_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b> parameter.
<b>Security</b> <b>controls</b>
<b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>commands</b>
- Restrict the usage of mail delivery to external
+ Restrict the usage of mail delivery to external
command.
<b>allow</b><i>_</i><b>mail</b><i>_</i><b>to</b><i>_</i><b>files</b>
- Restrict the usage of mail delivery to external
+ Restrict the usage of mail delivery to external
file.
<b>default</b><i>_</i><b>privs</b>
- Default rights for delivery to external file or
+ Default rights for delivery to external file or
command.
<b>HISTORY</b>
- The <b>Delivered-To:</b> header appears in the <b>qmail</b> system by
+ The <b>Delivered-To:</b> header appears in the <b>qmail</b> system by
Daniel Bernstein.
- The <i>maildir</i> structure appears in the <b>qmail</b> system by
+ The <i>maildir</i> structure appears in the <b>qmail</b> system by
Daniel Bernstein.
+
+
+ 5
+
+
+
+
+
+LOCAL(8) LOCAL(8)
+
+
<b>SEE</b> <b>ALSO</b>
<a href="aliases.5.html">aliases(5)</a> format of alias database
<a href="bounce.8.html">bounce(8)</a> non-delivery status reports
<a href="qmgr.8.html">qmgr(8)</a> queue manager
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
- 5
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 6
</pre> </body> </html>
Restrict what recipient addresses are allowed in
<b>RCPT</b> <b>TO</b> commands.
+ <b>smtpd</b><i>_</i><b>etrn</b><i>_</i><b>restrictions</b>
+ Restrict what domain names can be used in <b>ETRN</b> com-
+ mands, and what clients may issue <b>ETRN</b> commands.
+
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b>
- List of DNS domains that publish the addresses of
+ List of DNS domains that publish the addresses of
blacklisted hosts.
<b>relay</b><i>_</i><b>domains</b>
- Restrict what domains or networks this mail system
+ Restrict what domains or networks this mail system
will relay mail from or to.
<b>UCE</b> <b>control</b> <b>responses</b>
- <b>access</b><i>_</i><b>map</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates an access
- database restriction.
-
SMTPD(8) SMTPD(8)
+ <b>access</b><i>_</i><b>map</b><i>_</i><b>reject</b><i>_</i><b>code</b>
+ Server response when a client violates an access
+ database restriction.
+
<b>invalid</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>invalid</b><i>_</i><b>hostname</b> restriction.
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>maps</b><i>_</i><b>rbl</b><i>_</i><b>domains</b> restriction.
<b>reject</b><i>_</i><b>code</b>
- Response code when the client matches a <b>reject</b>
+ Response code when the client matches a <b>reject</b>
restriction.
<b>relay</b><i>_</i><b>domains</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client attempts to violate
+ Server response when a client attempts to violate
the mail relay policy.
<b>unknown</b><i>_</i><b>address</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>address</b> restriction.
<b>unknown</b><i>_</i><b>client</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client without address to
- name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
+ Server response when a client without address to
+ name mapping violates the <b>reject</b><i>_</i><b>unknown</b><i>_</i><b>clients</b>
restriction.
<b>unknown</b><i>_</i><b>hostname</b><i>_</i><b>reject</b><i>_</i><b>code</b>
- Server response when a client violates the
+ Server response when a client violates the
<b>reject</b><i>_</i><b>unknown</b><i>_</i><b>hostname</b> restriction.
<b>SEE</b> <b>ALSO</b>
syslogd(8) system logging
<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
+ The Secure Mailer license must be distributed with this
software.
<b>AUTHOR(S)</b>
-
-
-
-
4
<p>
+<li> <a href="#smtpd_etrn_restrictions">ETRN command restrictions</a>
+
+<p>
+
<li> <a href="#generic">Generic restrictions</a>
<p>
</dl>
+<a name="smtpd_etrn_restrictions">
+
+<h2> ETRN command restrictions</h2>
+
+Not really an UCE restriction, the <b>smtpd_etrn_restrictions</b>
+parameter restricts what domains may be specified in ETRN commands,
+and what clients may issue ETRN commands.
+
+<dl>
+
+<dt>Default:
+
+<dd>By default, the Postfix <a href="smtpd.8.html">SMTP server</a>
+accepts any ETRN command from any client.
+
+<p>
+
+<dt>Syntax:
+
+<dd>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.
+
+<p>
+
+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.
+
+<p>
+
+<dt> Example:
+
+<dd> <b>smtpd_etrn_restrictions = permit_mynetworks, reject</b>
+
+<p>
+
+<dt> Restrictions:
+
+<dl>
+
+<a name="check_etrn_access">
+
+<dt> <b>check_etrn_access</b> <i>maptype</i>:<i>mapname</i>
+
+<dt> <i>maptype</i>:<i>mapname</i> <dd> Search the named <a
+href="access.5.html">access database</a> for the domain specified
+in the ETRN command, or its parent domains. Reject the request if
+the result is <b>REJECT</b> or "[<b>45</b>]<i>XX text</i>". Permit
+the request if the result is anything else. The <b>access_map_reject_code
+</b> parameter specifies the result code for rejected requests
+(default: <b>550</b>).
+
+<p>
+
+<dt> <b><a href="#permit_naked_ip_address">permit_naked_ip_address</a></b>
+
+<dt> <b><a href="#reject_invalid_hostname">reject_invalid_hostname</a></b>
+
+<dt> <b><a href="#reject_unknown_hostname">reject_unknown_hostname</a></b>
+
+<dt> <b><a href="#check_helo_access">check_helo_access</a></b> <i>maptype</i>:<i>mapname</i>
+
+<dd> See HELO (EHLO) hostname restrictions.
+
+<p>
+
+<dt> <b><a href="#reject_unknown_client">reject_unknown_client</a></b>
+
+<dt> <b><a href="#permit_mynetworks">permit_mynetworks</a></b>
+
+<dt> <b><a href="#check_client_access">check_client_access</a></b> <i>maptype</i>:<i>mapname</i>
+
+<dd> See client name/address restrictions.
+
+<p>
+
+<dt> <b><a href="#permit">permit</a></b>
+
+<dt> <b><a href="#reject">reject</a></b>
+
+<dd> See generic restrictions.
+
+</dl>
+
+</dl>
+
<a name="generic">
<h2> Generic restrictions</h2>
<b>myorigin</b>
The domain that is appended to locally-posted mail.
+ <b>owner</b><i>_</i><b>request</b><i>_</i><b>special</b>
+ Give special treatment to <b>owner-</b><i>xxx</i> and <i>xxx</i><b>-request</b>
+ addresses.
+
<b>SEE</b> <b>ALSO</b>
<a href="cleanup.8.html">cleanup(8)</a> canonicalize and enqueue mail
<a href="postmap.1.html">postmap(1)</a> create mapping table
-<b>LICENSE</b>
- The Secure Mailer license must be distributed with this
- software.
-
VIRTUAL(5) VIRTUAL(5)
+<b>LICENSE</b>
+ The Secure Mailer license must be distributed with this
+ software.
+
<b>AUTHOR(S)</b>
Wietse Venema
IBM T.J. Watson Research
-
-
-
-
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 \
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
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
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
/* 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
* 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 {
"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)
--- /dev/null
+/*++
+/* NAME
+/* biff_notify 3
+/* SUMMARY
+/* send biff notification
+/* SYNOPSIS
+/* #include <biff_notify.h>
+/*
+/* 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 <sys/socket.h>
+#include <netinet/in.h>
+#include <netdb.h>
+#include <string.h>
+
+/* Utility library. */
+
+#include <msg.h>
+
+/* Application-specific. */
+
+#include <biff_notify.h>
+
+/* 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");
+}
--- /dev/null
+#ifndef _BIFF_H_INCLUDED_
+#define _BIFF_H_INCLUDED_
+
+/*++
+/* NAME
+/* biff_notify 3h
+/* SUMMARY
+/* read logical line
+/* SYNOPSIS
+/* #include <biff_notify.h>
+/* 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
/* 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.
/*
/* 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
/* 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
/* 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).
/* 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"
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;
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);
}
/* Application-specific. */
#include "local.h"
+#include "biff_notify.h"
/* deliver_mailbox_file - deliver to recipient mailbox */
VSTREAM *dst;
int status;
int copy_flags;
+ VSTRING *biff;
+ long end;
if (msg_verbose)
msg_info("deliver_mailbox_file: %s", state.msg_attr.recipient);
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);
{
char *newdir;
char *tmpdir;
+ char *curdir;
char *tmpfile;
char *newfile;
VSTRING *why;
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
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 {
vstring_free(why);
myfree(newdir);
myfree(tmpdir);
+ myfree(curdir);
myfree(tmpfile);
myfree(newfile);
return (0);
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
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
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
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.
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
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
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
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).
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"
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.
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
#include <split_at.h>
#include <valid_hostname.h>
#include <argv.h>
+#include <stringops.h>
/* Global library. */
const char *newloc;
char *at;
char **cpp;
+ char *domain;
+ const char *junk;
#define STREQ(x,y) (strcasecmp(x,y) == 0)
#define STR vstring_str
*/
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;
+ }
}
/*
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");
/*
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:
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);
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);
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);
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
/* 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.
#include <events.h>
#include <smtp_stream.h>
#include <peer_name.h>
+#include <valid_hostname.h>
/* Global library. */
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;
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);
}
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,
};
/* 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.
/* .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:
static ARGV *helo_restrctions;
static ARGV *mail_restrctions;
static ARGV *rcpt_restrctions;
+static ARGV *etrn_restrctions;
#define STR vstring_str
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 */
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
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
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.
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
/*
* Initialize.
*/
- VSTRING_RESET(reply.recipient);
status = setjmp(smtpd_check_buf);
if (status != 0)
return (0);
/*
* Initialize.
*/
- VSTRING_RESET(reply.recipient);
status = setjmp(smtpd_check_buf);
if (status != 0)
return (0);
/*
* Initialize.
*/
- VSTRING_RESET(reply.recipient);
status = setjmp(smtpd_check_buf);
if (status != 0)
return (0);
/*
* Initialize.
*/
- VSTRING_RESET(reply.recipient);
status = setjmp(smtpd_check_buf);
if (status != 0)
return (0);
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)
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,
};
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
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
+#ifdef USE_SYS_SELECT_H
+#include <sys/select.h>
+#endif
/* Utility library. */