Add control=suppress_local_fixups to complete the quartet.
authorPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 12 Sep 2005 10:08:53 +0000 (10:08 +0000)
committerPhilip Hazel <ph10@hermes.cam.ac.uk>
Mon, 12 Sep 2005 10:08:53 +0000 (10:08 +0000)
doc/doc-txt/ChangeLog
doc/doc-txt/NewStuff
src/src/acl.c
src/src/exim.c
src/src/globals.c
src/src/globals.h
src/src/receive.c
src/src/smtp_in.c

index aae31b2..c09c42f 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.217 2005/09/07 10:15:33 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/ChangeLog,v 1.218 2005/09/12 10:08:53 ph10 Exp $
 
 Change log file for Exim from version 4.21
 -------------------------------------------
@@ -152,6 +152,8 @@ PH/36 When a locally submitted message by a trusted user did not contain a
       messages from external hosts without From: headers in a similar way,
       which is clearly wrong.
 
+PH/37 Added control=suppress_local_fixups.
+
 
 Exim version 4.52
 -----------------
index 151960e..15cf0b4 100644 (file)
@@ -1,4 +1,4 @@
-$Cambridge: exim/doc/doc-txt/NewStuff,v 1.66 2005/09/06 13:17:36 ph10 Exp $
+$Cambridge: exim/doc/doc-txt/NewStuff,v 1.67 2005/09/12 10:08:53 ph10 Exp $
 
 New Features in Exim
 --------------------
@@ -120,6 +120,28 @@ PH/09 There is a new ACL condition "verify = not_blind". It checks that there
       (bcc) recipients. This check should not be used on its own for blocking
       messages.
 
+PH/10 There is a new ACL control called "suppress_local_fixups". This applies
+      to locally submitted (non TCP/IP) messages, and is the complement of
+      "control = submission". It disables the fixups that are normally applied
+      to locally-submitted messages. Specifically:
+
+      (a) Any Sender: header line is left alone (in this respect, it's a
+          dynamic version of local_sender_retain).
+
+      (b) No Message-ID:, From:, or Date: headers are added.
+
+      (c) There is no check that From: corresponds to the actual sender.
+
+      This feature may be useful when a remotely-originated message is
+      accepted, passed to some scanning program, and then re-submitted for
+      delivery. It means that all four possibilities can now be specified:
+
+      (1) Locally submitted, fixups applies: the default.
+      (2) Locally submitted, no fixups applied: use control =
+          suppress_local_fixups.
+      (3) Remotely submitted, no fixups applied: the default.
+      (4) Remotely submitted, fixups applied: use control = submission.
+
 
 Exim version 4.52
 -----------------
index 5d1e7cf..06fa6e8 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/acl.c,v 1.46 2005/09/07 10:15:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/acl.c,v 1.47 2005/09/12 10:08:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -140,13 +140,16 @@ enum {
 #endif
   CONTROL_ERROR, CONTROL_CASEFUL_LOCAL_PART, CONTROL_CASELOWER_LOCAL_PART,
   CONTROL_ENFORCE_SYNC, CONTROL_NO_ENFORCE_SYNC, CONTROL_FREEZE,
-  CONTROL_QUEUE_ONLY, CONTROL_SUBMISSION,
+  CONTROL_QUEUE_ONLY, CONTROL_SUBMISSION, CONTROL_SUPPRESS_LOCAL_FIXUPS,
 #ifdef WITH_CONTENT_SCAN
   CONTROL_NO_MBOX_UNSPOOL,
 #endif
   CONTROL_FAKEDEFER, CONTROL_FAKEREJECT, CONTROL_NO_MULTILINE };
 
-/* ACL control names; keep in step with the table above! */
+/* ACL control names; keep in step with the table above! This list is used for
+turning ids into names. The actual list of recognized names is in the variable
+control_def controls_list[] below. The fact that there are two lists is a mess
+and should be tidied up. */
 
 static uschar *controls[] = {
   #ifdef EXPERIMENTAL_BRIGHTMAIL
@@ -157,10 +160,11 @@ static uschar *controls[] = {
   #endif
   US"error", US"caseful_local_part",
   US"caselower_local_part", US"enforce_sync", US"no_enforce_sync", US"freeze",
-  US"queue_only", US"submission",
+  US"queue_only", US"submission", US"suppress_local_fixups",
   #ifdef WITH_CONTENT_SCAN
   US"no_mbox_unspool",
   #endif
+
   US"no_multiline"};
 
 /* Flags to indicate for which conditions /modifiers a string expansion is done
@@ -482,6 +486,10 @@ static unsigned int control_forbids[] = {
   ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* submission */
     (1<<ACL_WHERE_PREDATA)),
 
+  (unsigned int)
+  ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* suppress_local_fixups */
+    (1<<ACL_WHERE_NOTSMTP)|(1<<ACL_WHERE_PREDATA)),
+
 #ifdef WITH_CONTENT_SCAN
   (unsigned int)
   ~((1<<ACL_WHERE_MAIL)|(1<<ACL_WHERE_RCPT)|       /* no_mbox_unspool */
@@ -512,24 +520,25 @@ typedef struct control_def {
 
 static control_def controls_list[] = {
 #ifdef EXPERIMENTAL_BRIGHTMAIL
-  { US"bmi_run",                CONTROL_BMI_RUN, FALSE},
+  { US"bmi_run",                CONTROL_BMI_RUN, FALSE },
 #endif
 #ifdef EXPERIMENTAL_DOMAINKEYS
-  { US"dk_verify",              CONTROL_DK_VERIFY, FALSE},
-#endif
-  { US"caseful_local_part",     CONTROL_CASEFUL_LOCAL_PART, FALSE},
-  { US"caselower_local_part",   CONTROL_CASELOWER_LOCAL_PART, FALSE},
-  { US"enforce_sync",           CONTROL_ENFORCE_SYNC, FALSE},
-  { US"freeze",                 CONTROL_FREEZE, FALSE},
-  { US"no_enforce_sync",        CONTROL_NO_ENFORCE_SYNC, FALSE},
-  { US"no_multiline_responses", CONTROL_NO_MULTILINE, FALSE},
-  { US"queue_only",             CONTROL_QUEUE_ONLY, FALSE},
+  { US"dk_verify",              CONTROL_DK_VERIFY, FALSE },
+#endif
+  { US"caseful_local_part",     CONTROL_CASEFUL_LOCAL_PART, FALSE },
+  { US"caselower_local_part",   CONTROL_CASELOWER_LOCAL_PART, FALSE },
+  { US"enforce_sync",           CONTROL_ENFORCE_SYNC, FALSE },
+  { US"freeze",                 CONTROL_FREEZE, FALSE },
+  { US"no_enforce_sync",        CONTROL_NO_ENFORCE_SYNC, FALSE },
+  { US"no_multiline_responses", CONTROL_NO_MULTILINE, FALSE },
+  { US"queue_only",             CONTROL_QUEUE_ONLY, FALSE },
 #ifdef WITH_CONTENT_SCAN
-  { US"no_mbox_unspool",        CONTROL_NO_MBOX_UNSPOOL, FALSE},
+  { US"no_mbox_unspool",        CONTROL_NO_MBOX_UNSPOOL, FALSE },
 #endif
-  { US"fakedefer",              CONTROL_FAKEDEFER, TRUE},
-  { US"fakereject",             CONTROL_FAKEREJECT, TRUE},
-  { US"submission",             CONTROL_SUBMISSION, TRUE}
+  { US"fakedefer",              CONTROL_FAKEDEFER, TRUE },
+  { US"fakereject",             CONTROL_FAKEREJECT, TRUE },
+  { US"submission",             CONTROL_SUBMISSION, TRUE },
+  { US"suppress_local_fixups",  CONTROL_SUPPRESS_LOCAL_FIXUPS, FALSE }
   };
 
 /* Support data structures for Client SMTP Authorization. acl_verify_csa()
@@ -2506,6 +2515,10 @@ for (; cb != NULL; cb = cb->next)
         return ERROR;
         }
       break;
+
+      case CONTROL_SUPPRESS_LOCAL_FIXUPS:
+      suppress_local_fixups = TRUE;
+      break;
       }
     break;
 
index d232339..f3f303d 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/exim.c,v 1.27 2005/09/07 10:15:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/exim.c,v 1.28 2005/09/12 10:08:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -3913,7 +3913,7 @@ for (i = 0;;)
 
 /* If we cannot get a user login, log the incident and give up, unless the
 configuration specifies something to use. When running in the test harness,
-any setting of unknown_login overrides the actual login name. */
+any setting of unknown_login overrides the actual name. */
 
 if (originator_login == NULL || running_in_test_harness)
   {
index b00b70d..a4e37fb 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.c,v 1.35 2005/09/07 10:15:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.c,v 1.36 2005/09/12 10:08:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1083,6 +1083,7 @@ BOOL    strip_trailing_dot     = FALSE;
 uschar *submission_domain      = NULL;
 BOOL    submission_mode        = FALSE;
 uschar *submission_name        = NULL;
+BOOL    suppress_local_fixups  = FALSE;
 BOOL    synchronous_delivery   = FALSE;
 BOOL    syslog_duplication     = TRUE;
 int     syslog_facility        = LOG_MAIL;
index 2a57187..359fd92 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/globals.h,v 1.27 2005/09/07 10:15:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/globals.h,v 1.28 2005/09/12 10:08:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -686,6 +686,7 @@ extern BOOL    strip_trailing_dot;     /* Remove dots at ends of domains */
 extern uschar *submission_domain;      /* Domain for submission mode */
 extern BOOL    submission_mode;        /* Can be forced from ACL */
 extern uschar *submission_name;        /* User name set from ACL */
+extern BOOL    suppress_local_fixups;  /* Can be forced from ACL */
 extern BOOL    synchronous_delivery;   /* TRUE if -odi is set */
 extern BOOL    syslog_duplication;     /* FALSE => no duplicate logging */
 extern int     syslog_facility;        /* As defined by Syslog.h */
index 7544749..3f7170b 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/receive.c,v 1.23 2005/09/07 10:15:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/receive.c,v 1.24 2005/09/12 10:08:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -1160,9 +1160,10 @@ return TRUE;
 Either a non-null list of recipients, or the extract flag will be true, or
 both. The flag sender_local is true for locally generated messages. The flag
 submission_mode is true if an ACL has obeyed "control = submission". The flag
-smtp_input is true if the message is to be handled using SMTP conventions about
-termination and lines starting with dots. For non-SMTP messages, dot_ends is
-true for dot-terminated messages.
+suppress_local_fixups is true if an ACL has obeyed "control =
+suppress_local_fixups". The flag smtp_input is true if the message is to be
+handled using SMTP conventions about termination and lines starting with dots.
+For non-SMTP messages, dot_ends is true for dot-terminated messages.
 
 If a message was successfully read, message_id[0] will be non-zero.
 
@@ -1976,18 +1977,22 @@ for (h = header_list->next; h != NULL; h = h->next)
     break;
 
     /* If there is a "Sender:" header and the message is locally originated,
-    and from an untrusted caller, or if we are in submission mode for a remote
-    message, mark it "old" so that it will not be transmitted with the message,
-    unless active_local_sender_retain is set. (This can only be true if
-    active_local_from_check is false.) If there are any resent- headers in the
-    message, apply this rule to Resent-Sender: instead of Sender:. Messages
-    with multiple resent- header sets cannot be tidily handled. (For this
-    reason, at least one MUA - Pine - turns old resent- headers into X-resent-
-    headers when resending, leaving just one set.) */
+    and from an untrusted caller and suppress_local_fixups is not set, or if we
+    are in submission mode for a remote message, mark it "old" so that it will
+    not be transmitted with the message, unless active_local_sender_retain is
+    set. (This can only be true if active_local_from_check is false.) If there
+    are any resent- headers in the message, apply this rule to Resent-Sender:
+    instead of Sender:. Messages with multiple resent- header sets cannot be
+    tidily handled. (For this reason, at least one MUA - Pine - turns old
+    resent- headers into X-resent- headers when resending, leaving just one
+    set.) */
 
     case htype_sender:
     h->type = ((!active_local_sender_retain &&
-                ((sender_local && !trusted_caller) || submission_mode)
+                (
+                (sender_local && !trusted_caller && !suppress_local_fixups)
+                  || submission_mode
+                )
                ) &&
                (!resents_exist||is_resent))?
       htype_old : htype_sender;
@@ -2249,11 +2254,13 @@ ensure that it is an empty string. */
 message_subdir[0] = split_spool_directory? message_id[5] : 0;
 
 /* Now that we have the message-id, if there is no message-id: header, generate
-one, but only for local or submission mode messages. This can be
-user-configured if required, but we had better flatten any illegal characters
-therein. */
+one, but only for local (without suppress_local_fixups) or submission mode
+messages. This can be user-configured if required, but we had better flatten
+any illegal characters therein. */
 
-if (msgid_header == NULL && (sender_host_address == NULL || submission_mode))
+if (msgid_header == NULL &&
+      ((sender_host_address == NULL && !suppress_local_fixups)
+        || submission_mode))
   {
   uschar *p;
   uschar *id_text = US"";
@@ -2327,16 +2334,18 @@ for (i = 0; i < recipients_count; i++)
     rewrite_address(recipients_list[i].address, TRUE, TRUE,
       global_rewrite_rules, rewrite_existflags);
 
-/* If there is no From: header, generate one for local or submission_mode
-messages. If there is no sender address, but the sender is local or this is a
-local delivery error, use the originator login. This shouldn't happen for
-genuine bounces, but might happen for autoreplies. The addition of From: must
-be done *before* checking for the possible addition of a Sender: header,
-because untrusted_set_sender allows an untrusted user to set anything in the
-envelope (which might then get info From:) but we still want to ensure a valid
-Sender: if it is required. */
-
-if (from_header == NULL && (sender_host_address == NULL || submission_mode))
+/* If there is no From: header, generate one for local (without
+suppress_local_fixups) or submission_mode messages. If there is no sender
+address, but the sender is local or this is a local delivery error, use the
+originator login. This shouldn't happen for genuine bounces, but might happen
+for autoreplies. The addition of From: must be done *before* checking for the
+possible addition of a Sender: header, because untrusted_set_sender allows an
+untrusted user to set anything in the envelope (which might then get info
+From:) but we still want to ensure a valid Sender: if it is required. */
+
+if (from_header == NULL &&
+    ((sender_host_address == NULL && !suppress_local_fixups)
+      || submission_mode))
   {
   uschar *oname = US"";
 
@@ -2417,19 +2426,19 @@ if (from_header == NULL && (sender_host_address == NULL || submission_mode))
   }
 
 
-/* If the sender is local, or if we are in submission mode and there is an
-authenticated_id, check that an existing From: is correct, and if not, generate
-a Sender: header, unless disabled. Any previously-existing Sender: header was
-removed above. Note that sender_local, as well as being TRUE if the caller of
-exim is not trusted, is also true if a trusted caller did not supply a -f
-argument for non-smtp input. To allow trusted callers to forge From: without
-supplying -f, we have to test explicitly here. If the From: header contains
-more than one address, then the call to parse_extract_address fails, and a
-Sender: header is inserted, as required. */
+/* If the sender is local (without suppress_local_fixups), or if we are in
+submission mode and there is an authenticated_id, check that an existing From:
+is correct, and if not, generate a Sender: header, unless disabled. Any
+previously-existing Sender: header was removed above. Note that sender_local,
+as well as being TRUE if the caller of exim is not trusted, is also true if a
+trusted caller did not supply a -f argument for non-smtp input. To allow
+trusted callers to forge From: without supplying -f, we have to test explicitly
+here. If the From: header contains more than one address, then the call to
+parse_extract_address fails, and a Sender: header is inserted, as required. */
 
 if (from_header != NULL &&
      (active_local_from_check &&
-       ((sender_local && !trusted_caller) ||
+       ((sender_local && !trusted_caller && !suppress_local_fixups) ||
         (submission_mode && authenticated_id != NULL))
      ))
   {
@@ -2571,11 +2580,13 @@ if (!to_or_cc_header_exists && !bcc_header_exists)
 ******/
 
 /* If there is no date header, generate one if the message originates locally
-(i.e. not over TCP/IP) or the submission mode flag is set. Messages without
-Date: are not valid, but it seems to be more confusing if Exim adds one to
-all remotely-originated messages. */
+(i.e. not over TCP/IP) and suppress_local_fixups is not set, or if the
+submission mode flag is set. Messages without Date: are not valid, but it seems
+to be more confusing if Exim adds one to all remotely-originated messages. */
 
-if (!date_header_exists && (sender_host_address == NULL || submission_mode))
+if (!date_header_exists &&
+      ((sender_host_address == NULL && !suppress_local_fixups)
+        || submission_mode))
   header_add(htype_other, "%sDate: %s\n", resent_prefix, tod_stamp(tod_full));
 
 search_tidyup();    /* Free any cached resources */
index b30959e..c08d179 100644 (file)
@@ -1,4 +1,4 @@
-/* $Cambridge: exim/src/src/smtp_in.c,v 1.24 2005/09/07 10:15:33 ph10 Exp $ */
+/* $Cambridge: exim/src/src/smtp_in.c,v 1.25 2005/09/12 10:08:54 ph10 Exp $ */
 
 /*************************************************
 *     Exim - an Internet mail transport agent    *
@@ -812,6 +812,7 @@ fake_response = OK;                                  /* Can be set by ACL */
 no_mbox_unspool = FALSE;                             /* Can be set by ACL */
 #endif
 submission_mode = FALSE;                             /* Can be set by ACL */
+suppress_local_fixups = FALSE;                       /* Can be set by ACL */
 active_local_from_check = local_from_check;          /* Can be set by ACL */
 active_local_sender_retain = local_sender_retain;    /* Can be set by ACL */
 sender_address = NULL;