]> git.ipfire.org Git - thirdparty/postfix.git/commitdiff
postfix-2.0.9-20030519
authorWietse Venema <wietse@porcupine.org>
Mon, 19 May 2003 05:00:00 +0000 (00:00 -0500)
committerViktor Dukhovni <viktor@dukhovni.org>
Tue, 5 Feb 2013 06:28:52 +0000 (06:28 +0000)
30 files changed:
postfix/HISTORY
postfix/README_FILES/ADDRESS_CLASS_README
postfix/README_FILES/FILTER_README
postfix/README_FILES/SCHEDULER_README
postfix/README_FILES/VIRTUAL_README
postfix/conf/master.cf
postfix/conf/pcre_table
postfix/conf/sample-mime.cf
postfix/conf/sample-pcre-access.cf
postfix/conf/sample-regexp-access.cf
postfix/html/pcre_table.5.html
postfix/man/man5/pcre_table.5
postfix/man/man8/cleanup.8
postfix/proto/pcre_table
postfix/src/cleanup/cleanup.c
postfix/src/cleanup/cleanup_envelope.c
postfix/src/cleanup/cleanup_message.c
postfix/src/global/cleanup_strerror.c
postfix/src/global/cleanup_user.h
postfix/src/global/mail_params.h
postfix/src/global/mail_version.h
postfix/src/lmtp/lmtp_proto.c
postfix/src/lmtp/lmtp_sasl_glue.c
postfix/src/local/token.c
postfix/src/proxymap/proxymap.c
postfix/src/qmqpd/qmqpd.c
postfix/src/smtpd/smtpd.c
postfix/src/smtpd/smtpd_check.c
postfix/src/util/sys_defs.h
postfix/src/util/vstream.c

index 68140df75b027062f579e42075f7b874f3f804bf..4d4512d4ebde35f8d01ae47b65a941d4defe8a80 100644 (file)
@@ -8047,6 +8047,43 @@ Apologies for any names omitted.
        Patrik Rak's clever queue manager scheduler (nqmgr). Files:
        conf/sample-scheduler.cf, README_FILES/SCHEDULER_README.
 
+20030429
+
+       Bugfix: while verifying an address, the LMTP client entered
+       a forbidden "next" sender state after the last recipient.
+       Fix by Vladimir Davydoff. File: lmtp/lmtp_proto.c.
+
+       Bugfix: proxymap server did not parse "," as space.
+       Leandro Santi. File: proxymap/proxymap.c.
+
+20030502
+
+       Bugfix: defer delivery after .forward etc. file read error.
+       File: local/token.c.
+
+20030503
+
+       Bugfix: the Postfix LMTP client used the wrong service
+       name, causing trouble with SASL 2.1.13.  Daniel Schales,
+       Louisiana Tech. File: lmtp/lmtp_sasl_glue.c.
+
+20030518
+
+       Workaround: IRIX select() reports that a non-blocking file
+       descriptor is writable while write() transfers zero bytes.
+       File:  util/vstream.c.
+
+20030519
+
+       Feature: new require_{date,from,message_id,received}_header
+       restriction to reject SMTP mail when some message header
+       is missing.  Only the From: and Date: headers are actually
+       required by Internet mail standards; the Received:  and
+       Message-ID: headers are optional, but these are often
+       missing from SPAM email.  Files: global/cleanup_user.h,
+       global/cleanup_strerror.c, smtpd/smtpd_check.c,
+       cleanup/cleanup_message.c.
+
 Open problems:
 
        Low: smtp-source may block when sending large test messages.
index 8a77dae12101b928b32bf19c49923cc9d498e4e9..07658ccbaea823bdbf5d4b0f67aca4e7d17e8861 100644 (file)
@@ -28,43 +28,43 @@ Initially the list of address classes is hard coded, but this is
 meant to become extensible:
 
 -------------------------------------------------------------------
-Class  Description
+Class   Description
 -------------------------------------------------------------------
-local  For UNIX accounts and for traditional /etc/aliases
-       Domain names are listed in $mydestination (or match the IP
-           address listed with $inet_interfaces)
-       Known recipients are listed in $local_recipient_maps (this
-           information is currently used by the Postfix SMTP server
-           only; if $local_recipient_maps is empty, the Postfix
-           SMTP server accepts all recipients)
-       Default delivery agent: local
+local   For UNIX accounts and for traditional /etc/aliases
+        Domain names are listed in $mydestination (or match the IP
+            address listed with $inet_interfaces)
+        Known recipients are listed in $local_recipient_maps (this
+            information is currently used by the Postfix SMTP server
+            only; if $local_recipient_maps is empty, the Postfix
+            SMTP server accepts all recipients)
+        Default delivery agent: local
 
 virtual For hosted domains that are aliased to mailboxes in other
-alias      domains
-       Known recipients are listed in $virtual_alias_maps (default
-           is $virtual_maps for Postfix 1.1 compatibility)
-       Domain names are listed in $virtual_alias_domains (default
-           is $virtual_alias_maps for Postfix 1.1 compatibility)
-
-virtual        For hosted domains with their own mailboxes
-mailbox        Known recipients are listed in $virtual_mailbox_maps (if
-           this parameter is empty, the Postfix SMTP server accepts
-           all recipients for domains listed in $virtual_mailbox_domains)
-       Domain names are listed in $virtual_mailbox_domains (default
-           is $virtual_mailbox_maps for Postfix 1.1 compatibility)
-       Default delivery agent: virtual
-
-relay  For remote destinations that list your system as MX host
-       Domain names are listed in $relay_domains
-       Known recipients are listed in $relay_recipient_maps (if
-           this parameter is empty, the Postfix SMTP server accepts
-           all recipients for domains listed in $relay_domains)
-       Default delivery agent: relay (clone of default smtp agent)
-
-other  Restricted to mail from authorized clients
-       Default delivery agent: smtp
-       No domain table
-       No recipient table
+alias       domains
+        Known recipients are listed in $virtual_alias_maps (default
+            is $virtual_maps for Postfix 1.1 compatibility)
+        Domain names are listed in $virtual_alias_domains (default
+            is $virtual_alias_maps for Postfix 1.1 compatibility)
+
+virtual For hosted domains with their own mailboxes
+mailbox Known recipients are listed in $virtual_mailbox_maps (if
+            this parameter is empty, the Postfix SMTP server accepts
+            all recipients for domains listed in $virtual_mailbox_domains)
+        Domain names are listed in $virtual_mailbox_domains (default
+            is $virtual_mailbox_maps for Postfix 1.1 compatibility)
+        Default delivery agent: virtual
+
+relay   For remote destinations that list your system as MX host
+        Domain names are listed in $relay_domains
+        Known recipients are listed in $relay_recipient_maps (if
+            this parameter is empty, the Postfix SMTP server accepts
+            all recipients for domains listed in $relay_domains)
+        Default delivery agent: relay (clone of default smtp agent)
+
+other   Restricted to mail from authorized clients
+        Default delivery agent: smtp
+        No domain table
+        No recipient table
 -------------------------------------------------------------------
 
 Incompatibilities with Postfix 1.1
@@ -92,8 +92,7 @@ Incompatibilities with Postfix 1.1
 
 - The local_recipient_maps feature is now turned on by default, so
   that the Postfix SMTP server rejects mail for unknown local
-  recipients. This is enabled by default. See the LOCAL_RECIPIENT_README
-  file hints and tips.
+  recipients. See the LOCAL_RECIPIENT_README file hints and tips.
 
 - Introduction of relay delivery transport in master.cf. This helps
   to avoid mail delivery scheduling problems on inbound mail relays,
index e59ccfa510d41e82214acc752b2e53a242b2e52f..ecdf61d717b55de1bc418717362f69c8b548e434 100644 (file)
@@ -236,8 +236,9 @@ program.
 
 Note: the localhost port 10025 SMTP server filter should announce
 itself as "220 localhost...".  Postfix aborts delivery when it
-connects to an SMTP server that uses the same hostname, because
-that normally means you have a mail delivery loop problem.
+connects to an SMTP server that uses the same hostname as Postfix
+("host <servername> greeted me with my own hostname"), because that
+normally means you have a mail delivery loop problem.
 
 The example here assumes that the /some/where/filter command is a
 PERL script. PERL has modules that make talking SMTP easy. The
@@ -280,9 +281,9 @@ mail.
 The "-o local_recipient_maps=" and "-o relay_recipient_maps=" avoid
 unnecessary table lookups.
 
-The "-o myhostname=localhost.domain.tld" avoids a possible problem
-if your content filter is based on a proxy that simply relays SMTP
-commands.
+The "-o myhostname=localhost.domain.tld" avoids false alarms ("host
+<servername> greeted me with my own hostname") if your content
+filter is based on a proxy that simply relays SMTP commands.
 
 The "-o smtpd_xxx_restrictions" and "-o mynetworks=127.0.0.0/8"
 turn off UCE controls that would only waste time here.
index 457ea9ebee528c7df9c6a49883fdcf35bce7acab..ebfff51e682f9a53f0b9d7f037116b20eadb6655 100644 (file)
@@ -13,10 +13,11 @@ The old Postfix scheduler had several limitations due to unfortunate
 choices in its design.
 
 1 - Round-robin selection by destination for mail that is delivered
-    via the same message delivery transport.  That strategy broke
-    down when one single destination (say, inbound mail) had to
-    compete with multiple other destinations (say, outbound mail).
-    The poor suffering destination would be selected only
+    via the same message delivery transport. The round-robin strategy
+    was chosen with the intention to prevent a single (destination)
+    site from using up too many mail delivery resources.  However,
+    that strategy penalized inbound mail on bi-directional gateways.
+    The poor suffering inbound destination would be selected only
     1/number-of-destinations of the time, even when it had more
     mail than other destinations, and thus mail could be delayed.
 
@@ -62,7 +63,7 @@ However, even from programmer's point of view, there is nothing
 more to add to the message scheduling idea itself.  There are few
 things which make it look more complicated than it is, but the
 algorithm is the same as the user percieves it. The summary of the
-changes from the user's view:
+differences of the programmer's view from the user's view are:
 
 1) Simplification of terms for users: The user knows about messages
 and recipients. The program itself works with jobs (one message is
index d4c9ab19cdcf0e64d9c23cabf087cfeb7acdcac8..5c9df76137f60ee0644194f185ea345cda4c23a3 100644 (file)
@@ -68,7 +68,7 @@ virtual_mailbox_domains
 
     Specifies the list of domains that should be delivered to the
     $virtual_transport delivery agent (default: virtual). As of
-    version 1.2, Postfix is smart enough that you don't have to
+    version 2.0, Postfix is smart enough that you don't have to
     list every virtual domain in a Postfix transport map.
 
 virtual_mailbox_maps
index a8f9737215f0fc53646ae1c4f8b9ecfc2b7bf275..1418667605b9a3260cf20d1c6c9901de397b33d3 100644 (file)
@@ -1,8 +1,14 @@
 #
-# Postfix master process configuration file.  Each line describes how
-# a mailer component program should be run. The fields that make up
-# each line are described below. A "-" field value requests that a
-# default value be used for that field.
+# Postfix master process configuration file.  Each logical line 
+# describes how a Postfix daemon program should be run. 
+#
+# A logical line starts with non-whitespace, non-comment text.
+# Empty lines and whitespace-only lines are ignored, as are comment 
+# lines whose first non-whitespace character is a `#'.  
+# A line that starts with whitespace continues a logical line.
+#
+# The fields that make up each line are described below. A "-" field
+# value requests that a default value be used for that field.
 #
 # Service: any name that is valid for the specified transport type
 # (the next field).  With INET transports, a service is specified as
 # SPECIFY ONLY PROGRAMS THAT ARE WRITTEN TO RUN AS POSTFIX DAEMONS.
 # ALL DAEMONS SPECIFIED HERE MUST SPEAK A POSTFIX-INTERNAL PROTOCOL.
 #
-# DO NOT CHANGE THE ZERO PROCESS LIMIT FOR CLEANUP/BOUNCE/DEFER OR
-# POSTFIX WILL BECOME STUCK UP UNDER HEAVY LOAD
-#
-# DO NOT CHANGE THE ONE PROCESS LIMIT FOR PICKUP/QMGR OR POSTFIX WILL
-# DELIVER MAIL MULTIPLE TIMES.
-#
 # DO NOT SHARE THE POSTFIX QUEUE BETWEEN MULTIPLE POSTFIX INSTANCES.
 #
 # ==========================================================================
index c8db65bac1a2060b474dc854a3a8f9365d04ed62..ad5bd0bc9d662476e4d57b74cdae9e02e5ceaafb 100644 (file)
 # 
 # EXAMPLE SMTPD ACCESS MAP
 #        # Protect your outgoing majordomo exploders
-#        /^(?!owner-)(.*)-outgoing@/     550 Use ${1}@${2} instead
+#        /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
 # 
 #        # Bounce friend@whatever, except when whatever is our domain (you would
 #        # be better just bouncing all friend@ mail - this is just an example).
index 67aa228003a084273a793a0f742372defd521c05..ac4d9f2417582a09dc21415a2a70e37225d3105c 100644 (file)
@@ -66,4 +66,4 @@ strict_8bitmime = no
 # 
 # This blocks mail from poorly written mail software.
 # 
-strict_mime_domain_encoding = no
+strict_mime_encoding_domain = no
index c9735698f8a932e5453d7f6b4356a3609f07a8ca..03aa27a8c82d406ab31acec0a7e87b7de27ef47c 100644 (file)
@@ -45,7 +45,7 @@
 
 # Protect your outgoing majordomo exploders
 #
-/^(?!owner-)(.*)-outgoing@/            550 Use ${1}@${2} instead
+/^(?!owner-)(.*)-outgoing@(.*)/                550 Use ${1}@${2} instead
 
 
 # Bounce friend@whatever, except when whatever is our domain (you would
index 6d6d1c27ec3fdf8badc8d43cd61db406de784e6d..10df2529d1cda1fd51999754fd5f85fb95ca6f1f 100644 (file)
@@ -30,4 +30,6 @@
 /^postmaster@/                         OK
 
 # Protect your outgoing majordomo exploders
-/^(.*)-outgoing@(.*)$/!/^owner-.*/     550 Use ${1}@${2} instead
+if !/^owner-.*/
+/^(.*)-outgoing@(.*)$/                 550 Use ${1}@${2} instead
+endif
index 31da45f43a9e97daf6f6735fcd3c7618fa31f0e9..6be1fd8c71f76fb70e804f6f859b38593416b0ba 100644 (file)
@@ -136,7 +136,7 @@ PCRE_TABLE(5)                                       PCRE_TABLE(5)
 
 <b>EXAMPLE</b> <b>SMTPD</b> <b>ACCESS</b> <b>MAP</b>
        # Protect your outgoing majordomo exploders
-       /^(?!owner-)(.*)-outgoing@/     550 Use ${1}@${2} instead
+       /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
 
        # Bounce friend@whatever, except when whatever is our domain (you would
        # be better just bouncing all friend@ mail - this is just an example).
index 6293ed4a8c413b558913034865041948f1da9841..7fcedcb888dff91b08e73c4c1621fcf7ef4641cd 100644 (file)
@@ -119,7 +119,7 @@ or $(n) if they aren't followed by whitespace.
 .na
 .nf
 # Protect your outgoing majordomo exploders
-/^(?!owner-)(.*)-outgoing@/     550 Use ${1}@${2} instead
+/^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
 
 # Bounce friend@whatever, except when whatever is our domain (you would
 # be better just bouncing all friend@ mail - this is just an example).
index fdadfa4a80a36291a540917f849b0daca2a33856..67420bea375ee85a31dd1c58580a99d1eef2906a 100644 (file)
@@ -121,7 +121,7 @@ this also breaks majordomo approval requests when the included
 request contains valid 8-bit MIME mail, and it breaks bounces from
 mailers that do not properly encapsulate 8-bit content (for example,
 bounces from qmail or from old versions of Postfix).
-.IP \fBstrict_mime_domain_encoding\fR
+.IP \fBstrict_mime_encoding_domain\fR
 Reject mail with invalid \fBContent-Transfer-Encoding:\fR
 information for message/* or multipart/*. This blocks mail
 from poorly written software.
index c8512c70c87100c1b526287765cc78fda09b3d8e..eab2ebbee5ce2db300389b008cc0e4ee19f78d07 100644 (file)
 #      or $(n) if they aren't followed by whitespace.
 # EXAMPLE SMTPD ACCESS MAP
 #      # Protect your outgoing majordomo exploders
-#      /^(?!owner-)(.*)-outgoing@/     550 Use ${1}@${2} instead
+#      /^(?!owner-)(.*)-outgoing@(.*)/ 550 Use ${1}@${2} instead
 #
 #      # Bounce friend@whatever, except when whatever is our domain (you would
 #      # be better just bouncing all friend@ mail - this is just an example).
index 2b19a902e566764801e583aac28158d4a4571b14..1e988f22e9bf29601cdfc58ae15009ca0475266e 100644 (file)
@@ -277,9 +277,6 @@ static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
      * our status report.
      */
     if (CLEANUP_OUT_OK(state) == 0 && type > 0) {
-       if ((state->errs & CLEANUP_STAT_CONT) == 0
-           && (state->flags & CLEANUP_FLAG_DISCARD) == 0)
-           msg_warn("%s: skipping further client input", state->queue_id);
        while (type != REC_TYPE_END
               && (type = rec_get(src, buf, 0)) > 0)
             /* void */ ;
index 226a673d658e90ff2b35543f69d33dcb46e214a0..b26ccc7ed0108007e141a8aabb8bfbc9bd8ad7e4 100644 (file)
@@ -132,6 +132,8 @@ static void cleanup_envelope_process(CLEANUP_STATE *state, int type,
        return;
     }
     if (type == REC_TYPE_FLGS) {
+       if (msg_verbose)
+           msg_info("envelope %c %.*s", type, len, buf);
        extra_flags = atol(buf);
        if (extra_flags & ~CLEANUP_FLAG_MASK_EXTRA)
            msg_warn("%s: bad extra flags: 0x%x", state->queue_id, extra_flags);
index 72a562703c53a238c89e3dac261a7770b9b8ae19..f778015656c5f26d99108b25fcd521fa7840ec52 100644 (file)
@@ -493,6 +493,29 @@ static void cleanup_header_callback(void *context, int header_class,
     }
 }
 
+/* cleanup_missing - handle missing message header */
+
+static void cleanup_missing(CLEANUP_STATE *state, const char *resent,
+                                   const char *header)
+{
+    const char *attr;
+
+    if ((attr = nvtable_find(state->attr, MAIL_ATTR_ORIGIN)) == 0)
+       attr = "unknown";
+    vstring_sprintf(state->temp1, "%s: reject: missing %s%s header from %s;",
+                   state->queue_id, resent, header, attr);
+    if (state->sender)
+       vstring_sprintf_append(state->temp1, " from=<%s>", state->sender);
+    if (state->recip)
+       vstring_sprintf_append(state->temp1, " to=<%s>", state->recip);
+    if ((attr = nvtable_find(state->attr, MAIL_ATTR_PROTO_NAME)) != 0)
+       vstring_sprintf_append(state->temp1, " proto=%s", attr);
+    if ((attr = nvtable_find(state->attr, MAIL_ATTR_HELO_NAME)) != 0)
+       vstring_sprintf_append(state->temp1, " helo=<%s>", attr);
+    msg_info("%s", vstring_str(state->temp1));
+    state->errs |= CLEANUP_STAT_MISS_HDR;
+}
+
 /* cleanup_header_done_callback - insert missing message headers */
 
 static void cleanup_header_done_callback(void *context)
@@ -502,6 +525,15 @@ static void cleanup_header_done_callback(void *context)
     struct tm *tp;
     TOK822 *token;
 
+    /*
+     * Postfix prepends a Received: message header, so we should see two when
+     * one is required.
+     */
+    if ((state->flags & CLEANUP_FLAG_NEED_RCVD) && state->hop_count < 2) {
+       cleanup_missing(state, "", "Received");
+       return;
+    }
+
     /*
      * Add a missing (Resent-)Message-Id: header. The message ID gives the
      * time in GMT units, plus the local queue ID.
@@ -513,6 +545,10 @@ static void cleanup_header_done_callback(void *context)
      */
     if ((state->headers_seen & (1 << (state->resent[0] ?
                           HDR_RESENT_MESSAGE_ID : HDR_MESSAGE_ID))) == 0) {
+       if (state->flags & CLEANUP_FLAG_NEED_MSGID) {
+           cleanup_missing(state, state->resent, "Message-Id");
+           return;
+       }
        tp = gmtime(&state->time);
        strftime(time_stamp, sizeof(time_stamp), "%Y%m%d%H%M%S", tp);
        cleanup_out_format(state, REC_TYPE_NORM, "%sMessage-Id: <%s.%s@%s>",
@@ -528,6 +564,10 @@ static void cleanup_header_done_callback(void *context)
      */
     if ((state->headers_seen & (1 << (state->resent[0] ?
                                      HDR_RESENT_DATE : HDR_DATE))) == 0) {
+       if (state->flags & CLEANUP_FLAG_NEED_DATE) {
+           cleanup_missing(state, state->resent, "Date");
+           return;
+       }
        cleanup_out_format(state, REC_TYPE_NORM, "%sDate: %s",
                           state->resent, mail_date(state->time));
     }
@@ -537,6 +577,10 @@ static void cleanup_header_done_callback(void *context)
      */
     if ((state->headers_seen & (1 << (state->resent[0] ?
                                      HDR_RESENT_FROM : HDR_FROM))) == 0) {
+       if (state->flags & CLEANUP_FLAG_NEED_FROM) {
+           cleanup_missing(state, state->resent, "From");
+           return;
+       }
        quote_822_local(state->temp1, *state->sender ?
                        state->sender : MAIL_ADDR_MAIL_DAEMON);
        vstring_sprintf(state->temp2, "%sFrom: %s",
index 489093ed94e2e9cb367d099e611be3d980c5703e..e763ce950f9c528dbdd6b08f255dafcdcafab8fd 100644 (file)
@@ -51,6 +51,7 @@ static struct cleanup_stat_map cleanup_stat_map[] = {
     CLEANUP_STAT_BAD, "Internal protocol error",
     CLEANUP_STAT_RCPT, "No recipients specified",
     CLEANUP_STAT_HOPS, "Too many hops",
+    CLEANUP_STAT_MISS_HDR, "Missing message header",
     CLEANUP_STAT_SIZE, "Message file too big",
     CLEANUP_STAT_CONT, "Message content rejected",
     CLEANUP_STAT_WRITE, "Error writing message file",
index ce4af58514d7b83c39477416346281d61b347cd5..8c988251b9b5d7e6a51b648a0dbcfda89a136894 100644 (file)
 #define CLEANUP_FLAG_HOLD      (1<<2)  /* Place message on hold */
 #define CLEANUP_FLAG_DISCARD   (1<<3)  /* Discard message silently */
 #define CLEANUP_FLAG_BCC_OK    (1<<4)  /* Ok to add auto-BCC addresses */
+#define CLEANUP_FLAG_NEED_DATE (1<<5)  /* Require (Resent:-)Date: */
+#define CLEANUP_FLAG_NEED_FROM (1<<6)  /* Require (Resent:-)From: */
+#define CLEANUP_FLAG_NEED_MSGID        (1<<7)  /* Require (Resent:-)Message-Id: */
+#define CLEANUP_FLAG_NEED_RCVD (1<<8)  /* Require two Received: headers */
 
  /*
   * These are set on the fly while processing SMTP envelopes or message
   * content.
   */
 #define CLEANUP_FLAG_MASK_EXTRA \
-       (CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD)
+       (CLEANUP_FLAG_HOLD | CLEANUP_FLAG_DISCARD | CLEANUP_FLAG_NEED_DATE | \
+           CLEANUP_FLAG_NEED_FROM | CLEANUP_FLAG_NEED_MSGID | \
+           CLEANUP_FLAG_NEED_RCVD)
 
  /*
   * Diagnostics.
@@ -39,6 +45,7 @@
 #define CLEANUP_STAT_SIZE      (1<<2)  /* Message file too big */
 #define CLEANUP_STAT_CONT      (1<<3)  /* Message content rejected */
 #define CLEANUP_STAT_HOPS      (1<<4)  /* Too many hops */
+#define CLEANUP_STAT_MISS_HDR  (1<<5)  /* Some missing header */
 #define CLEANUP_STAT_RCPT      (1<<6)  /* No recipients found */
 
  /*
index 3c8021d5d8f9092bcc13342ccf4a9ef0695956db..4b968416c5e9738cd804967b2710228764631a4c 100644 (file)
@@ -1337,6 +1337,11 @@ ABCDEFGHIJKLMNOPQRSTUVWXYZ[\\\\]^_`\
 abcdefghijklmnopqrstuvwxyz{|}~"
 extern char *var_smtpd_exp_filter;
 
+#define REQUIRE_DATE_HDR       "require_date_header"
+#define REQUIRE_FROM_HDR       "require_from_header"
+#define REQUIRE_MSGID_HDR      "require_message_id_header"
+#define REQUIRE_RCVD_HDR       "require_received_header"
+
  /*
   * Heuristic to reject unknown local recipients at the SMTP port.
   */
index 302e68189f9c0bf15cafff8b8fe59a9fb83da306..744414eff0baf78c08ba0e9c57b7b14d2fc4d0d3 100644 (file)
@@ -20,7 +20,7 @@
   * Patches change the patchlevel and the release date. Snapshots change the
   * release date only, unless they include the same bugfix as a patch release.
   */
-#define MAIL_RELEASE_DATE      "20030424"
+#define MAIL_RELEASE_DATE      "20030519"
 
 #define VAR_MAIL_VERSION       "mail_version"
 #define DEF_MAIL_VERSION       "2.0.9-" MAIL_RELEASE_DATE
index b4afc37d0350266ce86d49fc4f2a2bd2f5d3556b..e17d7b0aa4e35504533e4f6b60f4754f941631c2 100644 (file)
@@ -396,7 +396,7 @@ static int lmtp_loop(LMTP_STATE *state, int send_state, int recv_state)
                            vstring_str(state->scratch));
            if ((next_rcpt = send_rcpt + 1) == request->rcpt_list.len)
                next_state = DEL_REQ_TRACE_ONLY(request->flags) ?
-                   LMTP_STATE_ABORT : LMTP_STATE_DATA;
+                   LMTP_STATE_RSET : LMTP_STATE_DATA;
            break;
 
            /*
index a53c19f9a6dc271e00697db1f97b742b5655fe5d..60e622fcabddc69557f23cd1116cc2a51cad49c7 100644 (file)
@@ -369,7 +369,7 @@ void    lmtp_sasl_start(LMTP_STATE *state)
 #define NULL_SERVER_ADDR       ((char *) 0)
 #define NULL_CLIENT_ADDR       ((char *) 0)
 
-    if (SASL_CLIENT_NEW("smtp", state->session->host,
+    if (SASL_CLIENT_NEW("lmtp", state->session->host,
                        NULL_CLIENT_ADDR, NULL_SERVER_ADDR,
                        state->sasl_callbacks, NULL_SECFLAGS,
                        (sasl_conn_t **) &state->sasl_conn) != SASL_OK)
index 1da680c0118717fdb6941c0eba62ec53f1eb75b0..7954c39ac3d8542d6a1785bc99760f053f1334bd 100644 (file)
@@ -98,6 +98,7 @@
 #include <tok822.h>
 #include <mail_params.h>
 #include <bounce.h>
+#include <defer.h>
 
 /* Application-specific. */
 
@@ -207,6 +208,10 @@ int     deliver_token_stream(LOCAL_STATE state, USER_ATTR usr_attr,
                break;
        }
     }
+    if (vstream_ferror(fp))
+       status = defer_append(BOUNCE_FLAGS(state.request),
+                             BOUNCE_ATTR(state.msg_attr),
+                             "error reading .forward file: %m");
     vstring_free(buf);
     return (status);
 }
index 22d070f3aed7a25a89ead3cbfdab7c16c0b9d514..83279127c9a825875260468e4c839d1edf24e04b 100644 (file)
@@ -350,7 +350,7 @@ DICT   *dict_proxy_open(const char *map, int open_flags, int dict_flags)
 
 static void post_jail_init(char *unused_name, char **unused_argv)
 {
-    const char *sep = " \t\r\n";
+    const char *sep = ", \t\r\n";
     char   *saved_filter;
     char   *bp;
     char   *type_name;
index 28cbbcd68947dfa8ca6bdd31ba38d6663c4cf17e..2e676001e6159cf9573662fe7284b68b5273c6a7 100644 (file)
@@ -482,6 +482,9 @@ static void qmqpd_send_status(QMQPD_STATE *state)
     } else if ((state->err & CLEANUP_STAT_RCPT) != 0) {
        qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD,
                    "Error: no recipients specified");
+    } else if ((state->err & CLEANUP_STAT_MISS_HDR) != 0) {
+       qmqpd_reply(state, DO_LOG, QMQPD_STAT_HARD,
+                   "Error: missing message header");
     } else {
        qmqpd_reply(state, DO_LOG, QMQPD_STAT_RETRY,
                    "Error: internal error %d", state->err);
index 96147559d6356699b7b70bcdeb5f79dc5eaec496..9c93fd0e31d5a05e9f44f8d5bc25a39c1425c58e 100644 (file)
@@ -1141,6 +1141,9 @@ static int data_cmd(SMTPD_STATE *state, int argc, SMTPD_TOKEN *unused_argv)
     } else if ((state->err & CLEANUP_STAT_WRITE) != 0) {
        state->error_mask |= MAIL_ERROR_RESOURCE;
        smtpd_chat_reply(state, "451 Error: queue file write error");
+    } else if ((state->err & CLEANUP_STAT_MISS_HDR) != 0) {
+       state->error_mask |= MAIL_ERROR_POLICY;
+       smtpd_chat_reply(state, "550 Error: missing message header");
     } else {
        state->error_mask |= MAIL_ERROR_SOFTWARE;
        smtpd_chat_reply(state, "451 Error: internal error %d", state->err);
index f3ef3fe4f1cb4003c50f8c5641adf3335d1619d1..ee56be5236cafc313de3b86308075bf27808e90a 100644 (file)
 /*     Reject, defer or permit the request unconditionally. This is to be used
 /*     at the end of a restriction list in order to make the default
 /*     action explicit.
+/* .IP require_date_header
+/* .IP require_from_header
+/* .IP require_message_id_header
+/* .IP require_received_header
+/*     Reject the message when it does not contain a Date: etc. 
+/*     message header. Only the Date: header is required by mail
+/*     standards. The other headers are usually added by MTAs.
 /* .IP reject_unknown_client
 /*     Reject the request when the client hostname could not be found.
 /*     The \fIunknown_client_reject_code\fR configuration parameter
@@ -2750,6 +2757,26 @@ static int generic_checks(SMTPD_STATE *state, ARGV *restrictions,
            DEFER_IF_REJECT2(state, MAIL_ERROR_POLICY,
                         "450 <%s>: %s rejected: defer_if_reject requested",
                             reply_name, reply_class);
+       } else if (strcasecmp(name, REQUIRE_DATE_HDR) == 0) {
+#ifndef TEST
+           rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
+                       CLEANUP_FLAG_NEED_DATE);
+#endif
+       } else if (strcasecmp(name, REQUIRE_FROM_HDR) == 0) {
+#ifndef TEST
+           rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
+                       CLEANUP_FLAG_NEED_FROM);
+#endif
+       } else if (strcasecmp(name, REQUIRE_MSGID_HDR) == 0) {
+#ifndef TEST
+           rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
+                       CLEANUP_FLAG_NEED_MSGID);
+#endif
+       } else if (strcasecmp(name, REQUIRE_RCVD_HDR) == 0) {
+#ifndef TEST
+           rec_fprintf(state->dest->stream, REC_TYPE_FLGS, "%d",
+                       CLEANUP_FLAG_NEED_RCVD);
+#endif
        }
 
        /*
index e084d5cfb2275188eebbfb09f4d890b5b74fe482..17120a0c93df45134811ce20ed9ce06bf8a09323 100644 (file)
@@ -470,6 +470,7 @@ extern int initgroups(const char *, int);
 #define DBM_NO_TRAILING_NULL           /* XXX check */
 #define USE_STATVFS
 #define STATVFS_IN_SYS_STATVFS_H
+#define BROKEN_NON_BLOCKING_WRITE_SELECT
 #endif
 
 #if defined(IRIX5)
index 5cff4514075005c507d0397395195f53e0d7cb62..b0176b13a97c3a735504cdf75141e465f5526f52 100644 (file)
@@ -535,11 +535,23 @@ static int vstream_fflush_some(VSTREAM *stream, int to_flush)
      * When flushing a buffer, allow for partial writes. These can happen
      * while talking to a network. Update the cached file seek position, if
      * any.
+     * 
+     * XXX Workaround for IRIX brain damage: select() indicates that a pipe is
+     * writable, but write() transfers zero bytes on non-blocking pipes. This
+     * means that there is no reasonable way to enforce write timeouts.
      */
     for (data = (char *) bp->data, len = to_flush; len > 0; len -= n, data += n) {
        if (stream->timeout)
            stream->iotime = time((time_t *) 0);
        if ((n = stream->write_fn(stream->fd, data, len, stream->timeout, stream->context)) <= 0) {
+#ifdef BROKEN_NON_BLOCKING_WRITE_SELECT
+           if (n == 0) {
+               msg_warn("%s: write() transfers 0 bytes on a writable descriptor!",
+                        myname);
+               sleep(1);
+               continue;
+           }
+#endif
            bp->flags |= VSTREAM_FLAG_ERR;
            if (errno == ETIMEDOUT)
                bp->flags |= VSTREAM_FLAG_TIMEOUT;