]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
snapshot-20000625
authorWietse Venema <wietse@porcupine.org>
Sun, 25 Jun 2000 00:00:00 +0000 (00:00 +0000)
committerWietse Venema <wietse@porcupine.org>
Thu, 17 Jan 2013 23:10:57 +0000 (18:10 -0500)
43 files changed:
postfix/FILTER_README
postfix/HISTORY
postfix/INSPECT_README [new file with mode: 0644]
postfix/RELEASE_NOTES
postfix/base64/base64decode [new file with mode: 0755]
postfix/base64/base64encode [new file with mode: 0755]
postfix/cleanup/Makefile.in
postfix/conf/sample-ldap.cf
postfix/global/deliver_pass.c
postfix/global/deliver_request.c
postfix/global/deliver_request.h
postfix/global/header_opts.c
postfix/global/header_opts.h
postfix/global/mail_copy.c
postfix/global/mail_copy.h
postfix/global/mail_params.h
postfix/global/mail_version.h
postfix/html/faq.html
postfix/html/local.8.html
postfix/html/pipe.8.html
postfix/html/smtp.8.html
postfix/lmtp/lmtp_proto.c
postfix/local/dotforward.c
postfix/local/local.c
postfix/local/maildir.c
postfix/local/recipient.c
postfix/makedefs
postfix/man/man8/local.8
postfix/man/man8/pipe.8
postfix/man/man8/smtp.8
postfix/pipe/pipe.c
postfix/qmgr/Makefile.in
postfix/qmgr/qmgr.h
postfix/qmgr/qmgr_deliver.c
postfix/qmgr/qmgr_message.c
postfix/smtp/smtp.c
postfix/smtp/smtp_proto.c
postfix/smtp/smtp_unalias.c
postfix/smtpd/smtpd.c
postfix/smtpd/smtpd_state.c
postfix/util/dict_pcre.c
postfix/util/dict_regexp.c
postfix/util/vstream.c

index 7c2284566aed3cc47a309f038d61b9dbe9c777c0..c6a3a71c01a131217c0913e49118c4d38808862c 100644 (file)
@@ -1,4 +1,8 @@
 This is a very first implementation of Postfix content filtering.
+A Postfix content filter re-injects filtered mail back into Postfix.
+If all you want is content _inspection_, see the INSPECT_README
+file instead.
+
 It involves an incompatible change to queue file formats.  Older
 Postfix versions will reject mail that needs to be content filtered,
 and will move the queue file to the "corrupt" mail queue subdirectory.
@@ -76,18 +80,19 @@ content through run a third-party content filter program.  If the
 mail cannot be captured to file, mail delivery is deferred by
 terminating with exit status 75 (EX_TEMPFAIL).  If the content
 filter program finds a problem, the mail is bounced by terminating
-the filter command with exit status 69 (EX_UNAVAILABLE).  If the
+the shell script with exit status 69 (EX_UNAVAILABLE).  If the
 content is OK, it is given as input to Postfix sendmail, and the
 exit status of the filter command is whatever exit status Postfix
 sendmail produces.
 
-The problem with content filterings like this is that they are not
-very robust, because they do not talk a well-defined protocol with
-Postfix. If the filter command aborts because of some memory
-allocation problem, it will not produce a nice exit status as per
-/usr/include/sysexits.h and mail will probably bounce. The same
-lack of robustness is possible when the content filtering software
-itself runs into a resource problem.
+The problem with content filters like this is that they are not
+very robust, because the software does not talk a well-defined
+protocol with Postfix. If the filter shell script aborts because
+the shell runs into some memory allocation problem, the script will
+not produce a nice exit status as per /usr/include/sysexits.h and
+mail will probably bounce. The same lack of robustness is possible
+when the content filtering software itself runs into a resource
+problem.
 
 I suggest that you play with this script for a while until you are
 satisfied with the results. Run it as root or as the filter user,
@@ -159,7 +164,7 @@ When a queue file has content filtering information, the queue
 manager will deliver the mail to the specified content filtering
 regardless of its final destination.
 
-The content filtering can be set up with the Postfix spawn service,
+The content filter can be set up with the Postfix spawn service,
 which is the Postfix equivalent of inetd. For example, to instantiate
 up to 10 content filtering processes on demand:
 
@@ -184,18 +189,18 @@ For now, it is left up to the Postfix users to come up with a
 PERL/SMTP framework for Postfix content filtering. If done well,
 it can be used with other mailers too, which is a nice spin-off.
 
-The simplest content filtering just copies SMTP commands and data
+The simplest content filter just copies SMTP commands and data
 between its inputs and outputs. If it has a problem, all it has to
 do is to reply to an input of `.' with `550 content rejected', and
 to disconnect its output side instead of sending `.'.
 
-The job of the content filtering is to either bounce mail with a
+The job of the content filter is to either bounce mail with a
 suitable diagnostic, or to feed the mail back into Postfix through
 a dedicated listener on port localhost 10026:
 
     /etc/postfix/master.cf:
         localhost:10026     inet  n      -      n      -      10      smtpd
-           -o content_filter= myhostname=localhost.domain.name
+           -o content_filter= -o myhostname=localhost.domain.name
 
 This is just another SMTP server. It is configured NOT to request
 content filtering for incoming mail, has the same process limit
index 69089100b623b91a99cefefe6a9b2accf70937e1..7a478e98397b485df0155fed3208087e0fadd126 100644 (file)
@@ -4032,3 +4032,66 @@ Apologies for any names omitted.
        Renamed "content inspection" etc. to "content filtering"
        in anticipation of a new hook for content inspection that
        only inspects mail without re-injecting it into Postfix.
+
+20000601
+
+       Feature: limit the size of pipe mailer deliveries with the
+       size=nnn command-line attribute. Patch by Andrew McNamara.
+
+20000603
+
+       Bugfix: don't try to do SASL authentication when running
+       in stand-alone (sendmail -bs) mode. Fix by Liviu Daia.
+
+       Bug: the unauthorized pipelining test fails with single
+       recipient mail when smtpd_delay_reject = yes.
+
+20000617
+
+       Bugfix: conf/sample-ldap.cf was no longer up to date with
+       reality. Patch by Lamont Jones, HP.
+
+       Bugfix: the maildir delivery routine left temporary files
+       lying around after unsuccessful delivery (problem reported
+       by Brian Laughton @ Corp.Axxent.Ca).
+
+20000619
+
+       Workaround: if append_dot_mydomain=no, turn on parent domain
+       search in the Postfix SMTP client, so that mail does not
+       bounce. Files: smtp/smtp.c, smtp/smtp_unalias.c.
+
+20000621
+
+       AIX 4.x had POSIX regular expression support all the time
+       I was working on Postfix. Beter find out late than never.
+
+20000623
+
+       Bugfix: the SMTP server did not reset the so-called junk
+       command counter after successfull delivery (Mark Hoffman
+       @ wallst.com).  File: smtpd/smtpd.c.
+
+20000625
+
+       Cleanup: remove Content-Length from incoming mail. The
+       sender has no authority over the format of mail as stored
+       by the receiving system. File: global/header_opts.h.
+
+       Feature: rewrite Mail-Followup-To: as sender. Files:
+       global/header_opts.[hc].
+
+       Cleanup: rewrite Reply-To, Errors-To, Return-Receipt-To as
+       sender, so that address masquerading works as expected.
+       Files: global/header_opts.c.
+
+       Feature: specify "test_home_directory = yes" to prevent
+       mail from being delivered to a user whose home directory
+       is not mounted. File: local/dotforward.c.
+
+       Cleanup: the pipe deliver agent no longer appends a blank
+       line when the F flag (prepend From_ line) is specified.
+       Specify the B flag if you need that blank line. The local
+       delivery agent no longer appends a blank line to mail that
+       is delivered to external command. Files:  pipe/pipe.c,
+       global/mail_copy.[hc].
diff --git a/postfix/INSPECT_README b/postfix/INSPECT_README
new file mode 100644 (file)
index 0000000..2b91d34
--- /dev/null
@@ -0,0 +1,181 @@
+This is a very first implementation of Postfix content inspection.
+A Postfix content inspector causes "bad" mail to be bounced. All
+other mail is delivered normally.  If you want content _inspection_,
+which allows you to modify mail content or destination, see the
+FILTER_README file instead.
+
+Content inspection involves an incompatible change to queue file
+formats.  Older Postfix versions will reject mail that needs to be
+content inspected, and will move the queue file to the "corrupt"
+mail queue subdirectory.
+
+This document describes two approaches to content inspection.
+
+Simple content inspection example
+=================================
+
+The example is relatively simple to set up, but is resource intensive
+because it runs a shell script for each message.
+
+With the shell script as shown you can lose a factor in Postfix
+performance for each temporary file that is created and deleted in
+the process of content inspection.  The performance impact is less
+for mail that is submitted or delivered locally, because such
+deliveries are not as fast as SMTP transit mail.
+
+The example assumes that only mail received via SMTP needs to be
+content inspected.
+
+      ..................................
+      .            Postfix             .
+   ------smtpd \                /local-----
+      .         -cleanup->queue-       .
+   -----pickup /                \smtp------
+      .                        |       .
+      .                         \pipe------>inspector
+      ..................................
+
+Create a dedicated local user account called "inspect".  The user
+will never log in, and can be given a "*" password and non-existent
+shell and home.
+
+Create a directory /var/spool/inspect that is accessible only to
+the "inspect" user. This is where the content inspection software
+will store any temporary files.
+
+Define a content inspection entry in the Postfix master file:
+
+    /etc/postfix/master.cf:
+       inspect   unix  -       n       n       -       -       pipe
+           user=inspect argv=/some/where/inspect ${sender} ${recipient}
+
+The filter program can start out as a simple shell script like this:
+
+    #!/bin/sh
+
+    # Localize this
+    INSPECT_DIR=/var/spool/inspect
+
+    # Exit codes from <sysexits.h>
+    EX_TEMPFAIL=75
+    EX_UNAVAILABLE=69
+
+    cd $INSPECT_DIR || { echo $INSPECT_DIR does not exist; exit $EX_TEMPFAIL; }
+
+    # Clean up when done or when aborting.
+    trap "rm -f in.$$; exit" 0 1 2 3 15
+
+    cat >in.$$ || { echo Cannot save mail to file; exit $EX_TEMPFAIL; }
+
+    # inspect <in.$$ || { echo Message content rejected; exit $EX_UNAVAILABLE; }
+
+    exit 0
+
+The idea is to first capture the message to file and then run the
+content through run a third-party content inspection program.  If
+the mail cannot be captured to file, mail delivery is deferred by
+terminating with exit status 75 (EX_TEMPFAIL).  If the content
+inspection program finds a problem, the mail is bounced by terminating
+the shell script with exit status 69 (EX_UNAVAILABLE). An exit
+status of zero means everything is hunky-dory and the mail can
+be delivered to its recipients.
+
+If mail is rejected, another possible action is to mail a copy to
+the local postmaster. If you do that, be sure not to enable content
+inspection for locally-posted mail or else rejected mail will loop.
+
+The problem with content inspection sotware like this is that it is
+not very robust, because the software does not talk a well-defined
+protocol with Postfix. If the shell scripts aborts because the
+shell runs into some memory allocation problem, the script will
+not produce a nice exit status as per /usr/include/sysexits.h and
+mail will probably bounce. The same lack of robustness is possible
+when the content inspection software itself runs into a resource
+problem.
+
+I suggest that you play with this script for a while until you are
+satisfied with the results. Run it as root or as the filter user,
+with a real message (headers+body) as input:
+
+    # /some/where/inspect sender recipient... <message-file
+
+Turn on content inspection for mail arriving via SMTP only, by
+appending "-o content_inspector=inspect:dummy" to the master.cf
+entry that defines the Postfix SMTP server:
+
+    /etc/postfix/master.cf:
+       smtp      inet     ...stuff...      smtpd
+           -o content_inspector=inspect:dummy
+
+The content_inspector configuration parameter accepts the same
+syntax as the right-hand side in a Postfix transport table.
+
+Advanced content inspection example
+===================================
+
+The second example is more complex, but can give better performance,
+and is less likely to bounce mail when the machine runs into a
+resource problem.  This approach uses content inspection software
+that can receive mail via SMTP, and that can run as a resident
+server.  You can expect to lose about a factor in Postfix performance
+for every temporary file created.
+
+We will set up a content inspection program listening on localhost
+port 10025 that receives mail via the SMTP protocol.
+
+      ..................................
+      .            Postfix             .
+   ------smtpd \                /local-----
+      .         -cleanup->queue-       .
+   -----pickup /            |   \smtp------
+      .                     v          .
+      .                    smtp        .
+      .                     |          .
+      ......................|...........
+                            |
+                            v
+                .................
+                .         10025 .
+                .   inspection  .
+                .               .
+                .................
+
+To enable content inspection in this manner, specify in main.cf a
+new parameter:
+
+    /etc/postfix/main.cf:
+       content_filter = smtp:localhost:10025
+
+This causes Postfix to add one extra content inspection record to
+each incoming mail message, with content smtp:localhost:10025.
+You can use the same syntax as in the right-hand side of a Postfix
+transport table.  The content inspection records are added by the
+smtpd and pickup servers.
+
+When a queue file has content inspection information, the queue
+manager will deliver the mail to the specified content inspector
+before attempting final delivery.
+
+The content filter can be set up with the Postfix spawn service,
+which is the Postfix equivalent of inetd. For example, to instantiate
+up to 10 content inspection processes on demand:
+
+    /etc/postfix/master.cf:
+       localhost:10025     inet  n      n      n      -      10     spawn
+           user=inspect argv=/some/where/inspect
+
+"inspect" is a dedicated local user account.  The user will never
+log in, and can be given a "*" password and non-existent shell and
+home.
+
+The spawn server is part of Postfix but is not installed by default.
+Edit the top-level Makefile.in file, run "make makefiles", "make",
+and "make install". The manual page isn't installed by default,
+either. See the spawn.c source file.
+
+The /some/where/inspect command is most likely a PERL script. PERL
+has modules that make talking SMTP easy.
+
+For now, it is left up to the Postfix users to come up with a
+PERL/SMTP framework for Postfix content inspection. If done well,
+it can be used with other mailers too, which is a nice spin-off.
index 514f443e8933cd56b5b9ab73f9a995468dbdec46..ff73e4d12a9fff3dd1aaa5ea9ffca0691a020fbd 100644 (file)
@@ -1,3 +1,12 @@
+Incompatible changes with snapshot-20000625
+===========================================
+
+The local delivery agent no longer appends a blank line to mail
+that is delivered to external command.
+
+The pipe delivery agent no longer appends a blank line when the F
+flag is specified. Specify the B flag if you need that blank line.
+
 Incompatible changes with snapshot-20000531
 ===========================================
 
diff --git a/postfix/base64/base64decode b/postfix/base64/base64decode
new file mode 100755 (executable)
index 0000000..67cbb9b
Binary files /dev/null and b/postfix/base64/base64decode differ
diff --git a/postfix/base64/base64encode b/postfix/base64/base64encode
new file mode 100755 (executable)
index 0000000..8f1869c
Binary files /dev/null and b/postfix/base64/base64encode differ
index 8b1da52c82158bf6067e0414e2e3c037a281ceb3..6688e4e2ce208d0ea520b1f2c66452d5fc29017b 100644 (file)
@@ -118,6 +118,8 @@ cleanup_envelope.o: ../include/tok822.h
 cleanup_envelope.o: ../include/resolve_clnt.h
 cleanup_envelope.o: ../include/mail_params.h
 cleanup_envelope.o: ../include/ext_prop.h
+cleanup_envelope.o: ../include/mail_addr.h
+cleanup_envelope.o: ../include/canon_addr.h
 cleanup_envelope.o: cleanup.h
 cleanup_envelope.o: ../include/argv.h
 cleanup_envelope.o: ../include/maps.h
index 0acb8682ec7fac268d6e99028dfe95b25c50a797..00620b31121a5250a94979632a04257206086a4a 100644 (file)
@@ -8,12 +8,62 @@
 # The ldap_lookup_timeout parameter specifies the timeout for LDAP
 # database lookups.
 #
-ldap_lookup_timeout = 10
+#ldap_timeout = 10
 
 # The ldap_search_base parameter specifies the LDAP database to search.
 #
-ldap_search_base = 
+#ldap_search_base = 
 
 # The ldap_server_host parameter specifies the LDAP server hostname.
 #
-ldap_server_host = 
+#ldap_server_host = localhost
+
+# The ldap_server_port parameter specifies the LDAP server port number.
+#
+#ldap_server_port = 389
+
+# The ldap_query_filter parameter specifies the filter used for queries.
+#
+#ldap_query_filter = (mailacceptinggeneralid=%s)
+
+# The ldap_result_attribute parameter specifies the attribute returned by
+# the search.
+#
+#ldap_result_attribute = maildrop
+
+# The ldap_scope parameter specifies the LDAP search scope: sub, base, or one.
+#
+#ldap_scope = sub
+
+# The ldap_bind parameter specifies whether or not to bind to the server.
+# LDAP v3 implementations don't require it, which saves some overhead.
+#
+#ldap_bind = yes
+
+# The ldap_bind_dn parameter specifies what distinguished name to use
+# when binding.
+#
+#ldap_bind_dn =
+
+# The ldap_bind_pw parameter specifies the password to use.
+#
+#ldap_bind_pw =
+
+# The ldap_cache parameter specifies whether or not to turn on client-side
+# caching.
+#
+#ldap_cache = no
+
+# The ldap_cache_expiry parameter specifies how many seconds to cache results
+# for (if ldap_cache=yes)
+#
+#ldap_cache_expiry = 30
+
+# The ldap_cache_size parameter specifies the cache size, in bytes.
+#
+#ldap_cache_size = 32768
+
+# The ldap_deference parameter specifies how to handle LDAP aliases.  See the
+# ldap_open(3) man page.
+#
+#ldap_dereference = 0
index 9d09490db63f8c2dbcc26edc7d8391ca24e9058f..4ae6ede78388fbd04259768254641cf00027572c 100644 (file)
@@ -87,7 +87,8 @@ static int deliver_pass_send_request(VSTREAM *stream, DELIVER_REQUEST *request,
 {
     int     stat;
 
-    mail_print(stream, "%s %s %ld %ld %s %s %s %s %ld %ld %s %s",
+    mail_print(stream, "%d %s %s %ld %ld %s %s %s %s %ld %ld %s %s",
+              request->flags,
               request->queue_name, request->queue_id,
               request->data_offset, request->data_size,
               request->nexthop, request->sender,
index ff361736eafe25b68cc8fbb0f3948a118ddc2c99..a38f0368d7eed326a02572815f27309c7cafa434 100644 (file)
@@ -9,6 +9,7 @@
 /*     typedef struct DELIVER_REQUEST {
 /* .in +5
 /*             VSTREAM *fp;
+/*             int     flags;
 /*             char    *queue_name;
 /*             char    *queue_id;
 /*             long    data_offset;
 /*     A null result means that the client sent bad information or that
 /*     it went away unexpectedly.
 /*
+/*     The \fBflags\fR structure member is the bit-wise OR of zero or more
+/*     of the following:
+/* .IP \fBDEL_REQ_FLAG_SUCCESS\fR
+/*     Delete successful recipients from the queue file.
+/* .IP \fBDEL_REQ_FLAG_BOUNCE\fR
+/*     Delete bounced recipients from the queue file. Currently,
+/*     this flag is considered to be "always on".
+/* .PP
+/*     The \fBDEL_REQ_FLAG_DEFLT\fR constant provides a convenient shorthand
+/*     for the most common case: delete successful and bounced recipients.
+/*
 /*     The \fIhop_status\fR structure member must be updated
 /*     by the caller when all delivery to the destination in
 /*     \fInexthop\fR should be deferred. The value of the
@@ -174,7 +186,8 @@ static int deliver_request_get(VSTREAM *stream, DELIVER_REQUEST *request)
      * Extract the queue file name, data offset, and sender address. Abort
      * the conversation when they send bad information.
      */
-    if (mail_scan(stream, "%s %s %ld %ld %s %s %s %s %ld",
+    if (mail_scan(stream, "%d %s %s %ld %ld %s %s %s %s %ld",
+                 &request->flags,
                  queue_name, queue_id, &request->data_offset,
                  &request->data_size, nexthop, address,
                  errors_to, return_receipt, &request->arrival_time) != 9)
index 34ab16af96dce71cd271aea02e1a376071534c98..2406085ff1eb66f3901f883d62a86af849521544 100644 (file)
@@ -27,6 +27,7 @@
   */
 typedef struct DELIVER_REQUEST {
     VSTREAM *fp;                       /* stream, shared lock */
+    int     flags;                     /* see below */
     char   *queue_name;                        /* message queue name */
     char   *queue_id;                  /* message queue id */
     long    data_offset;               /* offset to message */
@@ -40,6 +41,10 @@ typedef struct DELIVER_REQUEST {
     char   *hop_status;                        /* reason if unavailable */
 } DELIVER_REQUEST;
 
+#define DEL_REQ_FLAG_DEFLT     (DEL_REQ_FLAG_SUCCESS | DEL_REQ_FLAG_BOUNCE)
+#define DEL_REQ_FLAG_SUCCESS   (1<<0)  /* delete successful recipients */
+#define DEL_REQ_FLAG_BOUNCE    (1<<1)  /* unimplemented */
+
 typedef struct VSTREAM _deliver_vstream_;
 extern DELIVER_REQUEST *deliver_request_read(_deliver_vstream_ *);
 extern int deliver_request_done(_deliver_vstream_ *, DELIVER_REQUEST *, int);
index e14e31f3cad94e55980e45b95cabf506873ffaa5..f4d60544e60e548b53391aa2cb104b0214f74309 100644 (file)
@@ -51,13 +51,15 @@ static HEADER_OPTS header_opts[] = {
     "Apparently-To", HDR_APPARENTLY_TO, HDR_OPT_RECIP,
     "Bcc", HDR_BCC, HDR_OPT_DROP | HDR_OPT_XRECIP,
     "Cc", HDR_CC, HDR_OPT_XRECIP,
+    "Content-Length", HDR_CONTENT_LENGTH, HDR_OPT_DROP,
     "Delivered-To", HDR_DELIVERED_TO, 0,
     "Date", HDR_DATE, 0,
-    "Errors-To", HDR_ERRORS_TO, HDR_OPT_RECIP,
+    "Errors-To", HDR_ERRORS_TO, HDR_OPT_SENDER,
     "From", HDR_FROM, HDR_OPT_SENDER,
+    "Mail-Followup-To", HDR_MAIL_FOLLOWUP_TO, HDR_OPT_SENDER,
     "Message-Id", HDR_MESSAGE_ID, 0,
     "Received", HDR_RECEIVED, 0,
-    "Reply-To", HDR_REPLY_TO, HDR_OPT_RECIP,
+    "Reply-To", HDR_REPLY_TO, HDR_OPT_SENDER,
     "Resent-Bcc", HDR_RESENT_BCC, HDR_OPT_DROP | HDR_OPT_XRECIP | HDR_OPT_RR,
     "Resent-Cc", HDR_RESENT_CC, HDR_OPT_XRECIP | HDR_OPT_RR,
     "Resent-Date", HDR_RESENT_DATE, HDR_OPT_RR,
@@ -67,7 +69,7 @@ static HEADER_OPTS header_opts[] = {
     "Resent-Sender", HDR_RESENT_SENDER, HDR_OPT_SENDER | HDR_OPT_RR,
     "Resent-To", HDR_RESENT_TO, HDR_OPT_XRECIP | HDR_OPT_RR,
     "Return-Path", HDR_RETURN_PATH, HDR_OPT_DROP | HDR_OPT_SENDER,
-    "Return-Receipt-To", HDR_RETURN_RECEIPT_TO, HDR_OPT_RECIP,
+    "Return-Receipt-To", HDR_RETURN_RECEIPT_TO, HDR_OPT_SENDER,
     "Sender", HDR_SENDER, HDR_OPT_SENDER,
     "To", HDR_TO, HDR_OPT_XRECIP,
 };
index 27c44ddbe560334fa3de2c7ff30b5554a3cf3ecb..b4e0b83ddaa7da0b98318a09dc68890e3e5a278f 100644 (file)
@@ -48,6 +48,7 @@ typedef struct {
 #define HDR_RETURN_RECEIPT_TO          23
 #define HDR_SENDER                     24
 #define HDR_TO                         25
+#define HDR_MAIL_FOLLOWUP_TO           26
 
  /*
   * Header flags.
index 912f1a7eef42dd69bf2dcb1647b719e34ba29a00..c8fae4f5f7970037a097b36ab1d0ebbfdbe42c43 100644 (file)
@@ -186,7 +186,7 @@ int     mail_copy(const char *sender, const char *delivered,
            corrupt_error = mark_corrupt(src);
        if (prev_type != REC_TYPE_NORM)
            vstream_fputs(eol, dst);
-       if (flags & MAIL_COPY_FROM)
+       if (flags & MAIL_COPY_BLANK)
            vstream_fputs(eol, dst);
     }
     vstring_free(buf);
index 2c0c743bb57744e27a9387f4d377252b877d1737..2d8c6ae39f153bd8f8008697da64ac5ac49586c7 100644 (file)
@@ -29,9 +29,10 @@ extern int mail_copy(const char *, const char *, VSTREAM *, VSTREAM *,
 #define MAIL_COPY_DELIVERED    (1<<3)  /* prepend Delivered-To: */
 #define MAIL_COPY_RETURN_PATH  (1<<4)  /* prepend Return-Path: */
 #define MAIL_COPY_DOT          (1<<5)  /* escape dots - needed for bsmtp */
+#define MAIL_COPY_BLANK                (1<<6)  /* append blank line */
 #define MAIL_COPY_MBOX         (MAIL_COPY_FROM | MAIL_COPY_QUOTE | \
                                    MAIL_COPY_TOFILE | MAIL_COPY_DELIVERED | \
-                                   MAIL_COPY_RETURN_PATH)
+                                   MAIL_COPY_RETURN_PATH | MAIL_COPY_BLANK)
 #define MAIL_COPY_NONE         0       /* all turned off */
 
 /* LICENSE
index 94d0dda9f4f64a0874a34d450b861656fcde3736..64e0929267f814cf930f17f3d35d997b9336814a 100644 (file)
@@ -381,10 +381,14 @@ extern char *var_fwd_exp_filter;
 #define DEF_DELIVER_HDR                "command, file, forward"
 extern char *var_deliver_hdr;
 
-#define VAR_EXP_OWN_ALIAS              "expand_owner_alias"
-#define DEF_EXP_OWN_ALIAS              0
+#define VAR_EXP_OWN_ALIAS      "expand_owner_alias"
+#define DEF_EXP_OWN_ALIAS      0
 extern bool var_exp_own_alias;
 
+#define VAR_STAT_HOME_DIR      "test_home_directory"
+#define DEF_STAT_HOME_DIR      0
+extern bool var_stat_home_dir;
+
  /*
   * Queue manager: maximal size of the duplicate expansion filter. By
   * default, we do graceful degradation with huge mailing lists.
index 5ab30414c0fe4aa279e36e702d009635b1fb22c7..9d9f8ac887468f840afb7432af6d3b51f1bef2a3 100644 (file)
@@ -15,7 +15,7 @@
   * Version of this program.
   */
 #define VAR_MAIL_VERSION       "mail_version"
-#define DEF_MAIL_VERSION       "Snapshot-20000531"
+#define DEF_MAIL_VERSION       "Snapshot-20000625"
 extern char *var_mail_version;
 
 /* LICENSE
index c8c95e19beba10107fd73b0aa560aa5499d93111..691b64e0fa24178f951ea2df4b1d66acf2d7cc0e 100644 (file)
@@ -1020,10 +1020,9 @@ types Postfix supports, use the command <b>postconf -m</b>.
 <p>
 
 N.B. Some non-Postfix software such as <a
-href="http://www.mbnet.mb.ca/howto/dynamic.htm">DRAC</a> uses
-<b>btree</b> files instead of <b>hash</b> files.  In that case,
-you will have to adjust the above <b>check_client_access</b>
-restriction accordingly.
+href="http://mail.cc.umanitoba.ca/drac/">DRAC</a> uses <b>btree</b>
+files instead of <b>hash</b> files.  In that case, you will have
+to adjust the above <b>check_client_access</b> restriction accordingly.
 
 <p>
 
index a4c1574d34eeeb9fd6098624e7a0ef733de82127..c2d7bfea6957b46c215394bcce96bd775de805f5 100644 (file)
@@ -216,7 +216,7 @@ LOCAL(8)                                                 LOCAL(8)
        lope  header  to each message, prepends an optional <b>Deliv-</b>
        <b>ered-To:</b>  header  with  the  recipient  envelope  address,
        prepends  a  <b>Return-Path:</b>  header with the sender envelope
-       address, and appends an empty line.
+       address, and appends no empty line.
 
 <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
@@ -277,7 +277,7 @@ LOCAL(8)                                                 LOCAL(8)
        the <b>default</b><i>_</i><b>privs</b> configuration parameter.
 
 <b>STANDARDS</b>
-       RFC 822 (ARPA Internet Text Messages)
+       <a href="http://www.faqs.org/rfcs/rfc822.html">RFC 822</a> (ARPA Internet Text Messages)
 
 <b>DIAGNOSTICS</b>
        Problems  and transactions are logged to <b>syslogd</b>(8).  Cor-
@@ -352,6 +352,10 @@ LOCAL(8)                                                 LOCAL(8)
        <b>recipient</b><i>_</i><b>delimiter</b>
               Separator between username and address extension.
 
+       <b>test</b><i>_</i><b>home</b><i>_</i><b>directory</b>
+              Require that a recipient's home directory is acces-
+              sible by the recipient before attempting  delivery.
+
 <b>Mailbox</b> <b>delivery</b>
        <b>fallback</b><i>_</i><b>transport</b>
               Message transport for recipients that are not found
@@ -385,10 +389,6 @@ LOCAL(8)                                                 LOCAL(8)
               rides all other configuration parameters that  con-
               trol mailbox delivery, including <b>luser</b><i>_</i><b>relay</b>.
 
-<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-
-              sive lock on a mailbox or external file.
 
 
 
@@ -401,6 +401,11 @@ LOCAL(8)                                                 LOCAL(8)
 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-
+              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
               acquire an exclusive lock.
@@ -449,11 +454,6 @@ LOCAL(8)                                                 LOCAL(8)
               Default  rights  for  delivery  to external file or
               command.
 
-       <b>forward</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
-              What characters are  allowed  to  appear  in  $name
-              expansions  of forward_path. Illegal characters are
-              replaced by underscores.
-
 
 
 
@@ -467,6 +467,11 @@ LOCAL(8)                                                 LOCAL(8)
 LOCAL(8)                                                 LOCAL(8)
 
 
+       <b>forward</b><i>_</i><b>expansion</b><i>_</i><b>filter</b>
+              What characters are  allowed  to  appear  in  $name
+              expansions  of forward_path. Illegal characters are
+              replaced by underscores.
+
 <b>HISTORY</b>
        The <b>Delivered-To:</b> header appears in the  <b>qmail</b>  system  by
        Daniel Bernstein.
@@ -513,11 +518,6 @@ LOCAL(8)                                                 LOCAL(8)
 
 
 
-
-
-
-
-
 
 
 
index eeed535672022db6a771fcb2b35746194a8b2cf3..0b02333e5f41821cceb4c53baaf53af9a5e0cc8d 100644 (file)
@@ -30,23 +30,28 @@ PIPE(8)                                                   PIPE(8)
        file at the end of a service definition.  The syntax is as
        follows:
 
-       <b>flags=FR.</b>&gt; (optional)
+       <b>flags=BFR.</b>&gt; (optional)
               Optional message processing flags.  By  default,  a
               message is copied unchanged.
 
-              <b>F</b>      Prepend  a "<b>From</b> <i>sender</i> <i>time_stamp</i>" envelope
-                     header to  the  message  content.   This  is
+              <b>B</b>      Append  a blank line at the end of each mes-
+                     sage. This is required  by  some  mail  user
+                     agents  that  recognize  "<b>From</b>  " lines only
+                     when preceded by a blank line.
+
+              <b>F</b>      Prepend a "<b>From</b> <i>sender</i> <i>time_stamp</i>"  envelope
+                     header  to  the  message  content.   This is
                      expected by, for example, <b>UUCP</b> software. The
-                     <b>F</b> flag also  causes  an  empty  line  to  be
+                     <b>F</b>  flag  also  causes  an  empty  line to be
                      appended to the message.
 
-              <b>R</b>      Prepend  a  <b>Return-Path:</b> message header with
+              <b>R</b>      Prepend a <b>Return-Path:</b> message  header  with
                      the envelope sender address.
 
-              <b>.</b>      Prepend <b>.</b> to lines starting with  "<b>.</b>".  This
+              <b>.</b>      Prepend  <b>.</b>  to lines starting with "<b>.</b>". This
                      is needed by, for example, <b>BSMTP</b> software.
 
-              &gt;      Prepend  &gt;  to  lines starting with "<b>From</b> ".
+              &gt;      Prepend &gt; to lines starting  with  "<b>From</b>  ".
                      This is expected by, for example, <b>UUCP</b> soft-
                      ware.
 
@@ -54,11 +59,6 @@ PIPE(8)                                                   PIPE(8)
 
        <b>user</b>=<i>username</i>:<i>groupname</i>
               The external command is executed with the rights of
-              the specified <i>username</i>.  The  software  refuses  to
-              execute  commands with root privileges, or with the
-              privileges of the mail system owner.  If  <i>groupname</i>
-              is  specified,  the  corresponding group ID is used
-              instead of the group ID of <i>username</i>.
 
 
 
@@ -71,12 +71,22 @@ PIPE(8)                                                   PIPE(8)
 PIPE(8)                                                   PIPE(8)
 
 
+              the  specified  <i>username</i>.   The software refuses to
+              execute commands with root privileges, or with  the
+              privileges  of  the mail system owner. If <i>groupname</i>
+              is specified, the corresponding group  ID  is  used
+              instead of the group ID of <i>username</i>.
+
        <b>eol=string</b> (default: <b>\n</b>)
-              The output record delimiter.  Typically  one  would
-              use  either <b>\r\n</b> or <b>\n</b>. The usual C-style backslash
-              escape sequences are recognized: <b>\a</b> <b>\b</b> <b>\f</b> <b>\n</b> <b>\r</b>  <b>\t</b>
+              The  output  record  delimiter. Typically one would
+              use either <b>\r\n</b> or <b>\n</b>. The usual C-style  backslash
+              escape  sequences are recognized: <b>\a</b> <b>\b</b> <b>\f</b> <b>\n</b> <b>\r</b> <b>\t</b>
               <b>\v</b> <b>\</b><i>octal</i> and <b>\\</b>.
 
+       <b>size</b>=<i>size_limit</i> (optional)
+              Messages greater in size than this limit (in bytes)
+              will be bounced back to the sender.
+
        <b>argv</b>=<i>command</i>... (required)
               The  command to be executed. This must be specified
               as the last command attribute.  The command is exe-
@@ -115,16 +125,6 @@ PIPE(8)                                                   PIPE(8)
                      tains <b>${recipient</b>} expands into as many com-
                      mand-line arguments as there are recipients.
 
-              <b>${sender</b>}
-                     This macro expands to  the  envelope  sender
-                     address.
-
-              <b>${user</b>}
-                     This macro expands to the username part of a
-                     recipient address.   For  example,  with  an
-                     address <i>user+foo@domain</i> the username part is
-                     <i>user</i>.  A command-line argument that contains
-                     <b>${user</b>}  expands  into  as many command-line
 
 
 
@@ -137,6 +137,16 @@ PIPE(8)                                                   PIPE(8)
 PIPE(8)                                                   PIPE(8)
 
 
+              <b>${sender</b>}
+                     This macro expands to  the  envelope  sender
+                     address.
+
+              <b>${user</b>}
+                     This macro expands to the username part of a
+                     recipient address.   For  example,  with  an
+                     address <i>user+foo@domain</i> the username part is
+                     <i>user</i>.  A command-line argument that contains
+                     <b>${user</b>}  expands  into  as many command-line
                      arguments as there are recipients.
 
        In addition to the  form  ${<i>name</i>},  the  forms  $<i>name</i>  and
@@ -180,17 +190,7 @@ PIPE(8)                                                   PIPE(8)
               enforced by the Postfix queue manager.
 
        <i>transport_</i><b>destination</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>
-              Limit the number of recipients per  message  deliv-
-              ery,  for  delivery  via  the  named <i>transport</i>. The
-              default limit is taken  from  the  <b>default</b><i>_</i><b>destina-</b>
-              <b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>   parameter.    The  limit  is
-              enforced by the Postfix queue manager.
-
-       <i>transport_</i><b>time</b><i>_</i><b>limit</b>
-              Limit the time for delivery  to  external  command,
-              for  delivery  via the named <b>transport</b>. The default
-              limit is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b>  parame-
-              ter.   The  limit  is enforced by the Postfix queue
+              Limit  the  number  of   recipients   per   message
 
 
 
@@ -203,6 +203,16 @@ PIPE(8)                                                   PIPE(8)
 PIPE(8)                                                   PIPE(8)
 
 
+              delivery, for delivery via the named <i>transport</i>. The
+              default limit is taken  from  the  <b>default</b><i>_</i><b>destina-</b>
+              <b>tion</b><i>_</i><b>recipient</b><i>_</i><b>limit</b>   parameter.    The  limit  is
+              enforced by the Postfix queue manager.
+
+       <i>transport_</i><b>time</b><i>_</i><b>limit</b>
+              Limit the time for delivery  to  external  command,
+              for  delivery  via the named <b>transport</b>. The default
+              limit is taken from the <b>command</b><i>_</i><b>time</b><i>_</i><b>limit</b>  parame-
+              ter.   The  limit  is enforced by the Postfix queue
               manager.
 
 <b>SEE</b> <b>ALSO</b>
@@ -239,16 +249,6 @@ PIPE(8)                                                   PIPE(8)
 
 
 
-
-
-
-
-
-
-
-
-
-
 
 
 
index 05e2d06e6131e7f84c10e9e12446630d3cedc172..1529182fb7ab49eefbfe92c73d5009aac1041b2c 100644 (file)
@@ -75,6 +75,9 @@ SMTP(8)                                                   SMTP(8)
        command after a configuration change.
 
 <b>Miscellaneous</b>
+       <b>append</b><i>_</i><b>dot</b><i>_</i><b>mydomain</b>
+              Rewrite <i>user</i>@<i>host</i> to <i>user</i>@<i>host</i>.$<b>mydomain</b>.
+
        <b>best</b><i>_</i><b>mx</b><i>_</i><b>transport</b>
               Name  of  the  delivery  transport  to use when the
               local machine is the most-preferred mail  exchanger
@@ -123,9 +126,6 @@ SMTP(8)                                                   SMTP(8)
        <b>smtp</b><i>_</i><b>always</b><i>_</i><b>send</b><i>_</i><b>ehlo</b>
               Always send EHLO at the start of a connection.
 
-       <b>smtp</b><i>_</i><b>skip</b><i>_</i><b>4xx</b><i>_</i><b>greeting</b>
-              Skip  servers that greet us with a 4xx status code.
-
 
 
                                                                 2
@@ -137,6 +137,9 @@ SMTP(8)                                                   SMTP(8)
 SMTP(8)                                                   SMTP(8)
 
 
+       <b>smtp</b><i>_</i><b>skip</b><i>_</i><b>4xx</b><i>_</i><b>greeting</b>
+              Skip  servers that greet us with a 4xx status code.
+
        <b>smtp</b><i>_</i><b>skip</b><i>_</i><b>5xx</b><i>_</i><b>greeting</b>
               Skip servers that greet us with a 5xx status  code.
 
@@ -188,9 +191,6 @@ SMTP(8)                                                   SMTP(8)
               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>Timeout</b> <b>controls</b>
-       <b>smtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
-              Timeout in seconds for completing a TCP connection.
 
 
 
@@ -203,6 +203,9 @@ SMTP(8)                                                   SMTP(8)
 SMTP(8)                                                   SMTP(8)
 
 
+<b>Timeout</b> <b>controls</b>
+       <b>smtp</b><i>_</i><b>connect</b><i>_</i><b>timeout</b>
+              Timeout in seconds for completing a TCP connection.
               When no connection can be made within the deadline,
               the  SMTP client tries the next address on the mail
               exchanger list.
@@ -254,9 +257,6 @@ SMTP(8)                                                   SMTP(8)
        The Secure Mailer license must be  distributed  with  this
        software.
 
-<b>AUTHOR(S)</b>
-       Wietse Venema
-       IBM T.J. Watson Research
 
 
 
@@ -269,6 +269,9 @@ SMTP(8)                                                   SMTP(8)
 SMTP(8)                                                   SMTP(8)
 
 
+<b>AUTHOR(S)</b>
+       Wietse Venema
+       IBM T.J. Watson Research
        P.O. Box 704
        Yorktown Heights, NY 10598, USA
 
@@ -319,9 +322,6 @@ SMTP(8)                                                   SMTP(8)
 
 
 
-
-
-
 
 
 
index 440d521d45599754f1ecace70c9cc8d40d0f27bc..ae16b03855dbe138d5d98ad89f4f0321ae91e0b0 100644 (file)
@@ -531,7 +531,8 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
                                sent(request->queue_id, rcpt->address,
                                     session->namaddr, request->arrival_time,
                                     "%s", resp->str);
-                               deliver_completed(state->src, rcpt->offset);
+                               if (request->flags & DEL_REQ_FLAG_SUCCESS)
+                                   deliver_completed(state->src, rcpt->offset);
                                rcpt->offset = 0;
                            }
                        } else {
index e3131d3f800e3e3b9b6e85c4595dba13da9cb202..12ae1241d27d4e1f46c874e65cca52ba8fd6685e 100644 (file)
@@ -64,6 +64,7 @@
 #include <vstream.h>
 #include <htable.h>
 #include <open_as.h>
+#include <stat_as.h>
 #include <lstat_as.h>
 #include <iostuff.h>
 #include <stringops.h>
@@ -78,6 +79,7 @@
 #include <mail_params.h>
 #include <mail_conf.h>
 #include <ext_prop.h>
+#include <defer.h>
 
 /* Application-specific. */
 
@@ -113,18 +115,36 @@ int     deliver_dotforward(LOCAL_STATE state, USER_ATTR usr_attr, int *statusp)
        MSG_LOG_STATE(myname, state);
 
     /*
-     * Skip this module if per-user forwarding is disabled.
+     * Skip non-existing users. The mailbox delivery routine will catch the
+     * error.
+     * 
+     * Defer delivery to recipients whose home directory is not accessible.
+     * 
+     * XXX This code should be one level up. The caller should pass the
+     * recipient's password file info along with the call.
+     * 
+     * XXX This code should also be executed for \user deliveries that bypass
+     * aliasing and .forward processing. Said code is currently broken after
+     * a revision of the RFC822 address parser.
      */
-    if (*var_forward_path == 0)
+    if ((mypwd = mypwnam(state.msg_attr.user)) == 0)
        return (NO);
+    if (var_stat_home_dir
+       && stat_as(mypwd->pw_dir, &st, mypwd->pw_uid, mypwd->pw_gid) < 0) {
+       *statusp = defer_append(BOUNCE_FLAG_KEEP,
+                               BOUNCE_ATTR(state.msg_attr),
+                               "cannot access %s home directory %s: %m",
+                               mypwd->pw_name, mypwd->pw_dir);
+       return (YES);
+    }
 
     /*
-     * Skip non-existing users. The mailbox delivery routine will catch the
-     * error.
+     * Skip this module if per-user forwarding is disabled.
      */
-    if ((mypwd = mypwnam(state.msg_attr.user)) == 0)
+    if (*var_forward_path == 0)
        return (NO);
 
+
     /*
      * From here on no early returns or we have a memory leak.
      */
index 94bcb97994ba4cd60587b43b276861e60961d7cc..fd25801947939dcf55031d78006fab43e18eafc9 100644 (file)
 /*     optional \fBDelivered-To:\fR
 /*     header with the recipient envelope address, prepends a
 /*     \fBReturn-Path:\fR header with the sender envelope address,
-/*     and appends an empty line.
+/*     and appends no empty line.
 /* EXTERNAL FILE DELIVERY
 /* .ad
 /* .fi
 /*     forwarding mail is not recommended.
 /* .IP \fBrecipient_delimiter\fR
 /*     Separator between username and address extension.
+/* .IP \fBtest_home_directory\fR
+/*     Require that a recipient's home directory is accessible by the 
+/*     recipient before attempting delivery.
 /* .SH Mailbox delivery
 /* .ad
 /* .fi
@@ -439,6 +442,7 @@ char   *var_fwd_exp_filter;
 char   *var_prop_extension;
 int     var_exp_own_alias;
 char   *var_deliver_hdr;
+int     var_stat_home_dir;
 
 int     local_cmd_deliver_mask;
 int     local_file_deliver_mask;
@@ -500,7 +504,7 @@ static int local_deliver(DELIVER_REQUEST *rqst, char *service)
        state.msg_attr.recipient = rcpt->address;
        rcpt_stat = deliver_recipient(state, usr_attr);
        rcpt_stat |= forward_finish(state.msg_attr, rcpt_stat);
-       if (rcpt_stat == 0)
+       if (rcpt_stat == 0 && (rqst->flags & DEL_REQ_FLAG_SUCCESS))
            deliver_completed(state.msg_attr.fp, rcpt->offset);
        been_here_free(state.dup_filter);
        msg_stat |= rcpt_stat;
@@ -618,6 +622,7 @@ int     main(int argc, char **argv)
     static CONFIG_BOOL_TABLE bool_table[] = {
        VAR_BIFF, DEF_BIFF, &var_biff,
        VAR_EXP_OWN_ALIAS, DEF_EXP_OWN_ALIAS, &var_exp_own_alias,
+       VAR_STAT_HOME_DIR, DEF_STAT_HOME_DIR, &var_stat_home_dir,
        0,
     };
 
index 24f2ff8f4b5ba80c79b9bb07d5e0a46b4df07b5e..01adc5b1541eeb7a4bfb801a80671b0b15be389b 100644 (file)
@@ -143,11 +143,11 @@ int     deliver_maildir(LOCAL_STATE state, USER_ATTR usr_attr, char *path)
                    || sane_link(tmpfile, newfile) < 0)) {
                vstring_sprintf(why, "link to %s: %m", newfile);
            } else {
-               if (unlink(tmpfile) < 0)
-                   msg_warn("remove %s: %m", tmpfile);
                status = 0;
            }
        }
+       if (unlink(tmpfile) < 0)
+           msg_warn("remove %s: %m", tmpfile);
     }
     set_eugid(var_owner_uid, var_owner_gid);
 
index 3a6a2991f761477e8f360e935b20b68c83e97c74..4db8441739aae2d426a99e5c7e999c7250d4c96b 100644 (file)
@@ -104,6 +104,10 @@ static int deliver_switch(LOCAL_STATE state, USER_ATTR usr_attr)
 
     /*
      * \user is special: it means don't do any alias or forward expansion.
+     * 
+     * XXX This code currently does not work due to revision of the RFC822
+     * address parser. \user should be permitted only in locally specified
+     * aliases, includes or forward files.
      */
     if (state.msg_attr.recipient[0] == '\\') {
        state.msg_attr.recipient++, state.msg_attr.local++, state.msg_attr.user++;
index 6a95037068ac685b48889089a60ba402356a16e4..fe25dde9ba83c6b21fac08b85211d1366d5be7ae 100644 (file)
@@ -147,7 +147,7 @@ case "$SYSTEM.$RELEASE" in
                        case "$CC" in
                        cc|*/cc|xlc|*/xlc) OPT=; CCARGS="$CCARGS -w -blibpath:/usr/lib:/lib:/usr/local/lib";;
                        esac
-                       CCARGS="$CCARGS -D_ALL_SOURCE"
+                       CCARGS="$CCARGS -D_ALL_SOURCE -DHAS_POSIX_REGEXP"
                        ;;
                3)      SYSTYPE=AIX3
                        # How embarrassing...
index da7665d53ba7e8887b39412d575238cd1313d657..b7489f5f80b41e6f91e6a718a96b080be27ed325 100644 (file)
@@ -187,7 +187,7 @@ envelope header to each message, prepends an
 optional \fBDelivered-To:\fR
 header with the recipient envelope address, prepends a
 \fBReturn-Path:\fR header with the sender envelope address,
-and appends an empty line.
+and appends no empty line.
 .SH EXTERNAL FILE DELIVERY
 .na
 .nf
@@ -306,6 +306,9 @@ forwarding, delivery to command or file. Specify zero or more of:
 forwarding mail is not recommended.
 .IP \fBrecipient_delimiter\fR
 Separator between username and address extension.
+.IP \fBtest_home_directory\fR
+Require that a recipient's home directory is accessible by the
+recipient before attempting delivery.
 .SH Mailbox delivery
 .ad
 .fi
index 9676e8210fbb669fb0928c66d1cadab788615842..59b3cd02879e2e6261cd2a214a39dd4226298aa8 100644 (file)
@@ -30,10 +30,14 @@ to the \fBbounce\fR(8) or \fBdefer\fR(8) daemon as appropriate.
 .fi
 The external command attributes are given in the \fBmaster.cf\fR
 file at the end of a service definition.  The syntax is as follows:
-.IP "\fBflags=FR.>\fR (optional)"
+.IP "\fBflags=BFR.>\fR (optional)"
 Optional message processing flags. By default, a message is
 copied unchanged.
 .RS
+.IP \fBB\fR
+Append a blank line at the end of each message. This is required
+by some mail user agents that recognize "\fBFrom \fR" lines only
+when preceded by a blank line.
 .IP \fBF\fR
 Prepend a "\fBFrom \fIsender time_stamp\fR" envelope header to
 the message content.
@@ -62,6 +66,9 @@ The output record delimiter. Typically one would use either
 \fB\er\en\fR or \fB\en\fR. The usual C-style backslash escape
 sequences are recognized: \fB\ea \eb \ef \en \er \et \ev
 \e\fIoctal\fR and \fB\e\e\fR.
+.IP "\fBsize\fR=\fIsize_limit\fR (optional)"
+Messages greater in size than this limit (in bytes) will be bounced
+back to the sender.
 .IP "\fBargv\fR=\fIcommand\fR... (required)"
 The command to be executed. This must be specified as the
 last command attribute.
index bcf367a204424793eb0a4302799a9f337f3d628a..2942eb9ff6dfb2611accce945ba41894774303a0 100644 (file)
@@ -72,6 +72,8 @@ a configuration change.
 .SH Miscellaneous
 .ad
 .fi
+.IP \fBappend_dot_mydomain\fR
+Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.$\fBmydomain\fR.
 .IP \fBbest_mx_transport\fR
 Name of the delivery transport to use when the local machine
 is the most-preferred mail exchanger (by default, a mailer
index 9102d4275b269e96a29a129986dc43e939e403eb..78c11a200e9aa815c5507f5e4afd75b050bc1734 100644 (file)
 /* .fi
 /*     The external command attributes are given in the \fBmaster.cf\fR
 /*     file at the end of a service definition.  The syntax is as follows:
-/* .IP "\fBflags=FR.>\fR (optional)"
+/* .IP "\fBflags=BFR.>\fR (optional)"
 /*     Optional message processing flags. By default, a message is
 /*     copied unchanged.
 /* .RS
+/* .IP \fBB\fR
+/*     Append a blank line at the end of each message. This is required
+/*     by some mail user agents that recognize "\fBFrom \fR" lines only
+/*     when preceded by a blank line.
 /* .IP \fBF\fR
 /*     Prepend a "\fBFrom \fIsender time_stamp\fR" envelope header to
 /*     the message content.
@@ -54,6 +58,9 @@
 /*     \fB\er\en\fR or \fB\en\fR. The usual C-style backslash escape
 /*     sequences are recognized: \fB\ea \eb \ef \en \er \et \ev
 /*     \e\fIoctal\fR and \fB\e\e\fR.
+/* .IP "\fBsize\fR=\fIsize_limit\fR (optional)"
+/*     Messages greater in size than this limit (in bytes) will be bounced
+/*     back to the sender.
 /* .IP "\fBargv\fR=\fIcommand\fR... (required)"
 /*     The command to be executed. This must be specified as the
 /*     last command attribute.
 #include <mail_addr.h>
 #include <canon_addr.h>
 #include <split_addr.h>
+#include <off_cvt.h>
 
 /* Single server skeleton. */
 
@@ -255,6 +263,7 @@ typedef struct {
     gid_t   gid;                       /* command privileges */
     int     flags;                     /* mail_copy() flags */
     VSTRING *eol;                      /* output record delimiter */
+    off_t   size_limit;                        /* max size in bytes we will accept */
 } PIPE_ATTR;
 
 /* parse_callback - callback for mac_parse() */
@@ -415,6 +424,7 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv)
     struct group *grp;
     char   *user;                      /* user name */
     char   *group;                     /* group name */
+    char   *size;                      /* max message size */
     char   *cp;
 
     /*
@@ -425,6 +435,7 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv)
     attr->command = 0;
     attr->flags = 0;
     attr->eol = vstring_strcpy(vstring_alloc(1), "\n");
+    attr->size_limit = 0;
 
     /*
      * Iterate over the command-line attribute list.
@@ -437,6 +448,9 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv)
        if (strncasecmp("flags=", *argv, sizeof("flags=") - 1) == 0) {
            for (cp = *argv + sizeof("flags=") - 1; *cp; cp++) {
                switch (*cp) {
+               case 'B':
+                   attr->flags |= MAIL_COPY_BLANK;
+                   break;
                case 'F':
                    attr->flags |= MAIL_COPY_FROM;
                    break;
@@ -483,6 +497,15 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv)
            unescape(attr->eol, *argv + sizeof("eol=") - 1);
        }
 
+       /*
+        * size=max_message_size (in bytes)
+        */
+       else if (strncasecmp("size=", *argv, sizeof("size=") - 1) == 0) {
+           size = *argv + sizeof("size=") - 1;
+           if ((attr->size_limit = off_cvt_string(size)) < 0)
+               msg_fatal("%s: bad size= value: %s", myname, size);
+       }
+
        /*
         * argv=command...
         */
@@ -519,8 +542,9 @@ static void get_service_attr(PIPE_ATTR *attr, char **argv)
      * Give the poor tester a clue of what is going on.
      */
     if (msg_verbose)
-       msg_info("%s: uid %d, gid %d. flags %d",
-                myname, attr->uid, attr->gid, attr->flags);
+       msg_info("%s: uid %d, gid %d, flags %d, size %ld",
+                myname, attr->uid, attr->gid, attr->flags,
+                (long) attr->size_limit);
 }
 
 /* eval_command_status - do something with command completion status */
@@ -544,7 +568,8 @@ static int eval_command_status(int command_status, char *service,
            rcpt = request->rcpt_list.info + n;
            sent(request->queue_id, rcpt->address, service,
                 request->arrival_time, "%s", request->nexthop);
-           deliver_completed(src, rcpt->offset);
+           if (request->flags & DEL_REQ_FLAG_SUCCESS)
+               deliver_completed(src, rcpt->offset);
        }
        break;
     case PIPE_STAT_BOUNCE:
@@ -621,6 +646,19 @@ static int deliver_message(DELIVER_REQUEST *request, char *service, char **argv)
        get_service_attr(&attr, argv);
     }
 
+    /*
+     * Check that this agent accepts messages this large.
+     */
+    if (attr.size_limit != 0 && request->data_size > attr.size_limit) {
+       if (msg_verbose)
+           msg_info("%s: too big: size_limit = %ld, request->data_size = %ld",
+                    myname, (long) attr.size_limit, request->data_size);
+
+       deliver_status = eval_command_status(PIPE_STAT_BOUNCE, service,
+                                request, request->fp, "message too large");
+       return (deliver_status);
+    }
+
     /*
      * Deliver. Set the nexthop and sender variables, and expand the command
      * argument vector. Recipients will be expanded on the fly. XXX Rewrite
index 99ce9e6eff584234870545a3ab903af3318d83d7..a078dcaee8812d037afc8387e8065647953904e6 100644 (file)
@@ -134,6 +134,7 @@ qmgr_deliver.o: ../include/mail_queue.h
 qmgr_deliver.o: ../include/mail_proto.h
 qmgr_deliver.o: ../include/recipient_list.h
 qmgr_deliver.o: ../include/mail_params.h
+qmgr_deliver.o: ../include/deliver_request.h
 qmgr_deliver.o: qmgr.h
 qmgr_deliver.o: ../include/scan_dir.h
 qmgr_deliver.o: ../include/maps.h
index 004fd1d91ec750bb5165e271d14ff4a31636e206..44e6b4fb38fad4abff79a66f8c3acde9ebeaf6d5 100644 (file)
@@ -229,7 +229,8 @@ struct QMGR_MESSAGE {
     char   *sender;                    /* complete address */
     char   *errors_to;                 /* error report address */
     char   *return_receipt;            /* confirm receipt address */
-    char   *filter_xport;              /* inspection transport */
+    char   *filter_xport;              /* filtering transport */
+    char   *inspect_xport;             /* inspecting transport */
     long    data_size;                 /* message content size */
     long    rcpt_offset;               /* more recipients here */
     QMGR_RCPT_LIST rcpt_list;          /* complete addresses */
index 1ff2f350e1f372382afca72c6d7c80e451ccbe9c..466d5360d14b5c3c687342ba3a65e5f02b6cc0e9 100644 (file)
@@ -61,6 +61,7 @@
 #include <mail_proto.h>
 #include <recipient_list.h>
 #include <mail_params.h>
+#include <deliver_request.h>
 
 /* Application-specific. */
 
@@ -117,7 +118,8 @@ static int qmgr_deliver_send_request(QMGR_ENTRY *entry, VSTREAM *stream)
     QMGR_RCPT *recipient;
     QMGR_MESSAGE *message = entry->message;
 
-    mail_print(stream, "%s %s %ld %ld %s %s %s %s %ld",
+    mail_print(stream, "%d %s %s %ld %ld %s %s %s %s %ld",
+              message->inspect_xport ? DEL_REQ_FLAG_BOUNCE : DEL_REQ_FLAG_DEFLT,
               message->queue_name, message->queue_id,
               message->data_offset, message->data_size,
               entry->queue->name, message->sender,
index feb247806c7096d40eaec1409c2a405ea3ced172..7008cc7f35a74d345a7058bbd70eba09d75f77a1 100644 (file)
@@ -145,6 +145,7 @@ static QMGR_MESSAGE *qmgr_message_create(const char *queue_name,
     message->errors_to = 0;
     message->return_receipt = 0;
     message->filter_xport = 0;
+    message->inspect_xport = 0;
     message->data_size = 0;
     message->warn_offset = 0;
     message->warn_time = 0;
@@ -250,6 +251,9 @@ static int qmgr_message_read(QMGR_MESSAGE *message)
        } else if (rec_type == REC_TYPE_FILT) {
            if (message->filter_xport == 0)
                message->filter_xport = mystrdup(start);
+       } else if (rec_type == REC_TYPE_INSP) {
+           if (message->inspect_xport == 0)
+               message->inspect_xport = mystrdup(start);
        } else if (rec_type == REC_TYPE_FROM) {
            if (message->sender == 0) {
                message->sender = mystrdup(start);
@@ -706,6 +710,8 @@ void    qmgr_message_free(QMGR_MESSAGE *message)
        myfree(message->return_receipt);
     if (message->filter_xport)
        myfree(message->filter_xport);
+    if (message->inspect_xport)
+       myfree(message->inspect_xport);
     qmgr_rcpt_list_free(&message->rcpt_list);
     qmgr_message_count--;
     myfree((char *) message);
index d9d54357e852b83a56273251fc4b6ef0fde5f915..5a5b30b20dc0d8d2f80b201da22b42eeabe148fa 100644 (file)
@@ -56,6 +56,8 @@
 /* .SH Miscellaneous
 /* .ad
 /* .fi
+/* .IP \fBappend_dot_mydomain\fR
+/*     Rewrite \fIuser\fR@\fIhost\fR to \fIuser\fR@\fIhost\fR.$\fBmydomain\fR.
 /* .IP \fBbest_mx_transport\fR
 /*     Name of the delivery transport to use when the local machine
 /*     is the most-preferred mail exchanger (by default, a mailer
@@ -239,6 +241,7 @@ char   *var_smtp_sasl_opts;
 char   *var_smtp_sasl_passwd;
 bool    var_smtp_sasl_enable;
 char   *var_smtp_bind_addr;
+bool    var_append_dot_mydomain;
 
  /*
   * Global variables. smtp_errno is set by the address lookup routines and by
@@ -408,6 +411,7 @@ int     main(int argc, char **argv)
        VAR_SKIP_QUIT_RESP, DEF_SKIP_QUIT_RESP, &var_skip_quit_resp,
        VAR_SMTP_ALWAYS_EHLO, DEF_SMTP_ALWAYS_EHLO, &var_smtp_always_ehlo,
        VAR_SMTP_SASL_ENABLE, DEF_SMTP_SASL_ENABLE, &var_smtp_sasl_enable,
+       VAR_APP_DOT_MYDOMAIN, DEF_APP_DOT_MYDOMAIN, &var_append_dot_mydomain,
        0,
     };
 
index 0d7b4f97b57ccd3e4665378af560bc59d0e017fd..5d562ccdba3d7ce10a460c09dce055893b99b965 100644 (file)
@@ -533,7 +533,8 @@ int     smtp_xfer(SMTP_STATE *state)
                                         session->namaddr,
                                         request->arrival_time, "%s",
                                         resp->str);
-                                   deliver_completed(state->src, rcpt->offset);
+                                   if (request->flags & DEL_REQ_FLAG_SUCCESS)
+                                       deliver_completed(state->src, rcpt->offset);
                                    rcpt->offset = 0;
                                }
                            }
index 91cf6f9897ffb8162a2402b950fd80add65698c8..f92fb24771a8e5fe9c76b96c5d36a1c16b46a67b 100644 (file)
 #include <vstring.h>
 #include <msg.h>
 
+/* Global library. */
+
+#include <mail_params.h>
+
 /* DNS library. */
 
 #include <dns.h>
@@ -73,8 +77,11 @@ const char *smtp_unalias_name(const char *name)
      * after servicing a limited number of requests, so there is no need to
      * prevent the cache from growing too large, or to expire old entries.
      */
-    if (cache == 0)
+    if (cache == 0) {
        cache = htable_create(10);
+       if (var_append_dot_mydomain == 0)
+           smtp_unalias_flags |= RES_DNSRCH;
+    }
 
     /*
      * Look up the fqdn. If none is found use the query name instead, so that
index e7fe2d31d42ec566daea3a9d168410a0c1964a17..4d8701e4ff2fc484755234309278859499c7f385 100644 (file)
@@ -431,7 +431,7 @@ static int ehlo_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
        smtpd_chat_reply(state, "250-SIZE");
     smtpd_chat_reply(state, "250-ETRN");
 #ifdef USE_SASL_AUTH
-    if (SMTPD_STAND_ALONE(state) == 0 && var_smtpd_sasl_enable)
+    if (var_smtpd_sasl_enable)
        smtpd_chat_reply(state, "250-AUTH %s", state->sasl_mechanism_list);
 #endif
     smtpd_chat_reply(state, "250 8BITMIME");
@@ -624,9 +624,7 @@ static int mail_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *argv)
            if ((state->msg_size = off_cvt_string(arg + 5)) < 0)
                state->msg_size = 0;
 #ifdef USE_SASL_AUTH
-       } else if (SMTPD_STAND_ALONE(state) == 0
-                  && var_smtpd_sasl_enable
-                  && strncasecmp(arg, "AUTH=", 5) == 0) {
+       } else if (var_smtpd_sasl_enable && strncasecmp(arg, "AUTH=", 5) == 0) {
            if ((err = smtpd_sasl_mail_opt(state, arg + 5)) != 0) {
                smtpd_chat_reply(state, "%s", err);
                return (-1);
@@ -913,6 +911,7 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
     if (state->err == CLEANUP_STAT_OK) {
        state->error_count = 0;
        state->error_mask = 0;
+       state->junk_cmds = 0;
        smtpd_chat_reply(state, "250 Ok: queued as %s", state->queue_id);
     } else if ((state->err & CLEANUP_STAT_BAD) != 0) {
        state->error_mask |= MAIL_ERROR_SOFTWARE;
index 09b7b82efc8edb7624dddfec1f528695fc061bd2..4e98a8f282e429115f774be6e3fc36ae5e3891cb 100644 (file)
@@ -92,6 +92,8 @@ void    smtpd_state_init(SMTPD_STATE *state, VSTREAM *stream)
     state->junk_cmds = 0;
 
 #ifdef USE_SASL_AUTH
+    if (SMTPD_STAND_ALONE(state))
+       var_smtpd_sasl_enable = 0;
     if (var_smtpd_sasl_enable)
        smtpd_sasl_connect(state);
 #endif
index ddaf39bdded34042dc4d8659c7771ce3f3170df8..94d6fc67fe7003161ba11a73ba7cff4f69de13d2 100644 (file)
@@ -13,8 +13,6 @@
 /* DESCRIPTION
 /*     dict_pcre_open() opens the named file and compiles the contained
 /*     regular expressions.
-/*
-/*      The lookup interface will match only user@domain form addresses.
 /* SEE ALSO
 /*     dict(3) generic dictionary manager
 /* AUTHOR(S)
index 85ae9a49c5ee09e1b5b00c2e9bcf505069679c93..7f86f083dba34c7f363ce495ea180ab670e2b8ff 100644 (file)
@@ -13,8 +13,6 @@
 /* DESCRIPTION
 /*     dict_regexp_open() opens the named file and compiles the contained
 /*     regular expressions.
-/*
-/*      The lookup interface will match only user@domain form addresses.
 /* SEE ALSO
 /*     dict(3) generic dictionary manager
 /* AUTHOR(S)
index 1f582a45845ae100fd77841eddba6ccadceb38bf..e2ec94ddcf70437e4db62620349becc4f1a14ca0 100644 (file)
 /*     value arguments.
 /* .IP "VSTREAM_CTL_READ_FN (int (*)(int, void *, unsigned, int, void *))"
 /*     The argument specifies an alternative for the timed_read(3) function,
-/*     for example, a read function that performs encryption.
+/*     for example, a read function that performs decryption.
 /* .IP "VSTREAM_CTL_WRITE_FN (int (*)(int, void *, unsigned, int, void *))"
 /*     The argument specifies an alternative for the timed_write(3) function,
 /*     for example, a write function that performs encryption.