Taintcheck transport-process arguments
authorJeremy Harris <jgh146exb@wizmail.org>
Sun, 27 Mar 2022 19:41:05 +0000 (20:41 +0100)
committerJeremy Harris <jgh146exb@wizmail.org>
Sun, 27 Mar 2022 20:00:33 +0000 (21:00 +0100)
37 files changed:
doc/doc-docbook/spec.xfpt
doc/doc-txt/ChangeLog
src/src/child.c
src/src/deliver.c
src/src/expand.c
src/src/functions.h
src/src/routers/queryprogram.c
src/src/smtp_in.c
src/src/transport.c
src/src/transports/lmtp.c
src/src/transports/pipe.c
src/src/transports/smtp.c
test/aux-var-src/0164.F
test/aux-var-src/0173.filter
test/aux-var-src/0383.F
test/confs/0101
test/confs/0134
test/confs/0194
test/confs/0321
test/confs/0369
test/confs/0383
test/confs/0594
test/confs/5100
test/log/0164
test/log/0173
test/log/0383
test/log/0594
test/mail/0164.CALLER
test/mail/0383.CALLER
test/msglog/0594.10HmaX-0005vi-00 [deleted file]
test/paniclog/0594
test/scripts/0000-Basic/0002
test/scripts/0000-Basic/0383
test/scripts/0000-Basic/0594
test/stderr/0393
test/stderr/0594
test/stdout/0002

index 105e2fc5d514ea88b3e5005ecf5fadf7fd210d79..6c885176fdbbc31fdc3537f359745bd144f84dd9 100644 (file)
@@ -10663,16 +10663,28 @@ expansion items.
 This item inserts &"raw"& header lines. It is described with the &%header%&
 expansion item in section &<<SECTexpansionitems>>& above.
 
 This item inserts &"raw"& header lines. It is described with the &%header%&
 expansion item in section &<<SECTexpansionitems>>& above.
 
-.vitem "&*${run{*&<&'command'&>&*&~*&<&'args'&>&*}{*&<&'string1'&>&*}&&&
+.vitem "&*${run <&'options'&> {*&<&'command&~arg&~list'&>&*}{*&<&'string1'&>&*}&&&
         {*&<&'string2'&>&*}}*&"
 .cindex "expansion" "running a command"
 .cindex "&%run%& expansion item"
         {*&<&'string2'&>&*}}*&"
 .cindex "expansion" "running a command"
 .cindex "&%run%& expansion item"
-The command and its arguments are first expanded as one string. The string is
-split apart into individual arguments by spaces, and then the command is run
+This item runs an external command, as a subprocess.
+.new
+One option is supported after the word &'run'&, comma-separated.
+
+If the option &'preexpand'& is not used,
+the command string is split into individual arguments by spaces
+and then each argument is expanded.
+Then the command is run
 in a separate process, but under the same uid and gid.  As in other command
 executions from Exim, a shell is not used by default. If the command requires
 a shell, you must explicitly code it.
 in a separate process, but under the same uid and gid.  As in other command
 executions from Exim, a shell is not used by default. If the command requires
 a shell, you must explicitly code it.
+The command name may not be tainted, but the remaining arguments can be.
 
 
+If the option &'preexpand'& is used,
+.wen
+the command and its arguments are first expanded as one string. The result is
+split apart into individual arguments by spaces, and then the command is run
+as above.
 Since the arguments are split by spaces, when there is a variable expansion
 which has an empty result, it will cause the situation that the argument will
 simply be omitted when the program is actually executed by Exim. If the
 Since the arguments are split by spaces, when there is a variable expansion
 which has an empty result, it will cause the situation that the argument will
 simply be omitted when the program is actually executed by Exim. If the
@@ -10683,6 +10695,9 @@ in a string containing quotes, because it would interfere with the quotes
 around the command arguments. A possible guard against this is to wrap the
 variable in the &%sg%& operator to change any quote marks to some other
 character.
 around the command arguments. A possible guard against this is to wrap the
 variable in the &%sg%& operator to change any quote marks to some other
 character.
+.new
+Neither the command nor any argument may be tainted.
+.wen
 
 The standard input for the command exists, but is empty. The standard output
 and standard error are set to the same file descriptor.
 
 The standard input for the command exists, but is empty. The standard output
 and standard error are set to the same file descriptor.
index 1c799b6640731e3c8f91866c8c46d1a092b5a231..913518dea68ea2d464c2ea2b38349ac20a088dd8 100644 (file)
@@ -100,6 +100,18 @@ JH/23 Bug 2864: FreeBSD: fix transport hang after 4xx/5xx response. Previously
       resulted in the library waiting for the peer's Close.  If that was never
       sent we waited forever.  Fix by tracking send calls.
 
       resulted in the library waiting for the peer's Close.  If that was never
       sent we waited forever.  Fix by tracking send calls.
 
+JH/24 The ${run} expansion item now expands its command string elements after
+      splitting.  Previously it was before; the new ordering makes handling
+      zero-length arguments simpler.  The old ordering can be obtained by
+      appending a new option "preexpand", after a comma, to the "run".
+
+JH/25 Taint-check exec arguments for transport-initiated external processes.
+      Previously, tainted values could be used.  This affects "pipe", "lmtp" and
+      "queryprogram" transport, transport-filter, and ETRN commands.
+      The ${run} expansion is also affected: in "preexpand" mode no part of
+      the command line may be tainted, in default mode the executable name
+      may not be tainted.
+
 
 Exim version 4.95
 -----------------
 
 Exim version 4.95
 -----------------
index 4c0dbabd11a482ebf571cbfc576627833c86f9d4..f0db2a3b4a829867cab1a3caab365d9cedafed3e 100644 (file)
@@ -346,6 +346,7 @@ pid_t pid;
 if (is_tainted(argv[0]))
   {
   log_write(0, LOG_MAIN | LOG_PANIC, "Attempt to exec tainted path: '%s'", argv[0]);
 if (is_tainted(argv[0]))
   {
   log_write(0, LOG_MAIN | LOG_PANIC, "Attempt to exec tainted path: '%s'", argv[0]);
+  errno = EPERM;
   return (pid_t)(-1);
   }
 
   return (pid_t)(-1);
   }
 
index 8f85626a09320321e697915a74ee3c97d2993560..029b7a59b6975cb7a42debb5856fe8bcf565dae8 100644 (file)
@@ -2390,7 +2390,7 @@ if ((pid = exim_fork(US"delivery-local")) == 0)
       {
       ok = transport_set_up_command(&transport_filter_argv,
         tp->filter_command,
       {
       ok = transport_set_up_command(&transport_filter_argv,
         tp->filter_command,
-        TRUE, PANIC, addr, US"transport filter", NULL);
+        TRUE, PANIC, addr, FALSE, US"transport filter", NULL);
       transport_filter_timeout = tp->filter_timeout;
       }
     else transport_filter_argv = NULL;
       transport_filter_timeout = tp->filter_timeout;
       }
     else transport_filter_argv = NULL;
index 2d55a884666ac4d8e8fd1709b8f76673709a2949..12edd195caf222e82d396389d00875e52d40e072 100644 (file)
@@ -5527,6 +5527,7 @@ while (*s)
       {
       FILE * f;
       const uschar * arg, ** argv;
       {
       FILE * f;
       const uschar * arg, ** argv;
+      BOOL late_expand = TRUE;
 
       if ((expand_forbid & RDO_RUN) != 0)
         {
 
       if ((expand_forbid & RDO_RUN) != 0)
         {
@@ -5534,15 +5535,42 @@ while (*s)
         goto EXPAND_FAILED;
         }
 
         goto EXPAND_FAILED;
         }
 
+      /* Handle options to the "run" */
+
+      while (*s == ',')
+       {
+       if (Ustrncmp(++s, "preexpand", 9) == 0)
+         { late_expand = FALSE; s += 9; }
+       else
+         {
+         const uschar * t = s;
+         while (isalpha(*++t)) ;
+         expand_string_message = string_sprintf("bad option '%.*s' for run",
+                                                 (int)(t-s), s);
+         goto EXPAND_FAILED;
+         }
+       }
       Uskip_whitespace(&s);
       Uskip_whitespace(&s);
+
       if (*s != '{')                                   /*}*/
         {
        expand_string_message = US"missing '{' for command arg of run";
        goto EXPAND_FAILED_CURLY;                       /*"}*/
        }
       if (*s != '{')                                   /*}*/
         {
        expand_string_message = US"missing '{' for command arg of run";
        goto EXPAND_FAILED_CURLY;                       /*"}*/
        }
-      if (!(arg = expand_string_internal(s+1, TRUE, &s, skipping, TRUE, &resetok)))
-       goto EXPAND_FAILED;
-      Uskip_whitespace(&s);
+      s++;
+
+      if (late_expand)         /* this is the default case */
+       {
+       int n = Ustrcspn(s, "}");
+       arg = skipping ? NULL : string_copyn(s, n);
+       s += n;
+       }
+      else
+       {
+       if (!(arg = expand_string_internal(s, TRUE, &s, skipping, TRUE, &resetok)))
+         goto EXPAND_FAILED;
+       Uskip_whitespace(&s);
+       }
                                                        /*{*/
       if (*s++ != '}')
         {                                              /*{*/
                                                        /*{*/
       if (*s++ != '}')
         {                                              /*{*/
@@ -5562,11 +5590,12 @@ while (*s)
 
         if (!transport_set_up_command(&argv,    /* anchor for arg list */
             arg,                                /* raw command */
 
         if (!transport_set_up_command(&argv,    /* anchor for arg list */
             arg,                                /* raw command */
-            FALSE,                              /* don't expand the arguments */
-            0,                                  /* not relevant when... */
-            NULL,                               /* no transporting address */
-            US"${run} expansion",               /* for error messages */
-            &expand_string_message))            /* where to put error message */
+           late_expand,                /* expand args if not already done */
+            0,                          /* not relevant when... */
+            NULL,                       /* no transporting address */
+           late_expand,                /* allow tainted args, when expand-after-split */
+            US"${run} expansion",       /* for error messages */
+            &expand_string_message))    /* where to put error message */
           goto EXPAND_FAILED;
 
         /* Create the child process, making it a group leader. */
           goto EXPAND_FAILED;
 
         /* Create the child process, making it a group leader. */
index 5ecef6ad00146ffae87d1186943089dc87d55747..e231ce204742c94c9be70a85a3ff322f9dc50cb9 100644 (file)
@@ -616,7 +616,7 @@ extern BOOL    transport_pass_socket(const uschar *, const uschar *, const uscha
                        );
 extern uschar *transport_rcpt_address(address_item *, BOOL);
 extern BOOL    transport_set_up_command(const uschar ***, const uschar *,
                        );
 extern uschar *transport_rcpt_address(address_item *, BOOL);
 extern BOOL    transport_set_up_command(const uschar ***, const uschar *,
-                BOOL, int, address_item *, const uschar *, uschar **);
+                BOOL, int, address_item *, BOOL, const uschar *, uschar **);
 extern void    transport_update_waiting(host_item *, uschar *);
 extern BOOL    transport_write_block(transport_ctx *, uschar *, int, BOOL);
 extern void    transport_write_reset(int);
 extern void    transport_update_waiting(host_item *, uschar *);
 extern BOOL    transport_write_block(transport_ctx *, uschar *, int, BOOL);
 extern void    transport_write_reset(int);
index 644025a615d45adb9d7e9e2724440a11e239feca..0d03f1ea35566f94f61714a17ccfcdbbe60eda0f 100644 (file)
@@ -291,6 +291,7 @@ if (!transport_set_up_command(&argvptr, /* anchor for arg list */
     TRUE,                               /* expand the arguments */
     0,                                  /* not relevant when... */
     NULL,                               /* no transporting address */
     TRUE,                               /* expand the arguments */
     0,                                  /* not relevant when... */
     NULL,                               /* no transporting address */
+    FALSE,                             /* args must be untainted */
     US"queryprogram router",            /* for error messages */
     &addr->message))                    /* where to put error message */
   return DEFER;
     US"queryprogram router",            /* for error messages */
     &addr->message))                    /* where to put error message */
   return DEFER;
index 3fe3dab82700acdebf162ac634795f56140465c8..fa727ed1f789e95c7b76df4b5611a98188677495 100644 (file)
@@ -5834,7 +5834,7 @@ while (done <= 0)
        etrn_command = smtp_etrn_command;
        deliver_domain = smtp_cmd_data;
        rc = transport_set_up_command(&argv, smtp_etrn_command, TRUE, 0, NULL,
        etrn_command = smtp_etrn_command;
        deliver_domain = smtp_cmd_data;
        rc = transport_set_up_command(&argv, smtp_etrn_command, TRUE, 0, NULL,
-         US"ETRN processing", &error);
+         FALSE, US"ETRN processing", &error);
        deliver_domain = NULL;
        if (!rc)
          {
        deliver_domain = NULL;
        if (!rc)
          {
index 428d522adfa72172ca5f6e4a4177106ad855f307..105238c9c13c65251bfa75fdf0464344604987db 100644 (file)
@@ -2053,6 +2053,31 @@ else
 
 
 
 
 
 
+/* Enforce all args untainted, for consistency with a router-sourced pipe
+command, where (because the whole line is passed as one to the tpt) a
+tainted arg taints the executable name.  It's unclear also that letting an
+attacker supply command arguments is wise. */
+
+static BOOL
+arg_is_tainted(const uschar * s, int argn, address_item * addr,
+  const uschar * etext, uschar ** errptr)
+{
+if (is_tainted(s))
+  {
+  uschar * msg = string_sprintf("Tainted arg %d for %s command: '%s'",
+                               argn, etext, s);
+  if (addr)
+    {
+    addr->transport_return = FAIL;
+    addr->message = msg;
+    }
+  else *errptr = msg;
+  return TRUE;
+  }
+return FALSE;
+}
+
+
 /*************************************************
 *          Set up direct (non-shell) command     *
 *************************************************/
 /*************************************************
 *          Set up direct (non-shell) command     *
 *************************************************/
@@ -2070,6 +2095,7 @@ Arguments:
   expand_failed      error value to set if expansion fails; not relevant if
                      addr == NULL
   addr               chain of addresses, or NULL
   expand_failed      error value to set if expansion fails; not relevant if
                      addr == NULL
   addr               chain of addresses, or NULL
+  allow_tainted_args as it says; used for ${run}
   etext              text for use in error messages
   errptr             where to put error message if addr is NULL;
                      otherwise it is put in the first address
   etext              text for use in error messages
   errptr             where to put error message if addr is NULL;
                      otherwise it is put in the first address
@@ -2080,8 +2106,8 @@ Returns:             TRUE if all went well; otherwise an error will be
 
 BOOL
 transport_set_up_command(const uschar *** argvptr, const uschar * cmd,
 
 BOOL
 transport_set_up_command(const uschar *** argvptr, const uschar * cmd,
-  BOOL expand_arguments, int expand_failed, address_item *addr,
-  const uschar * etext, uschar ** errptr)
+  BOOL expand_arguments, int expand_failed, address_item * addr,
+  BOOL allow_tainted_args, const uschar * etext, uschar ** errptr)
 {
 const uschar ** argv, * s;
 int address_count = 0, argcount = 0, max_args;
 {
 const uschar ** argv, * s;
 int address_count = 0, argcount = 0, max_args;
@@ -2186,6 +2212,16 @@ if (expand_arguments)
 
       for (address_item * ad = addr; ad; ad = ad->next)
         {
 
       for (address_item * ad = addr; ad; ad = ad->next)
         {
+       /* $pipe_addresses is spefically not checked for taint, because there is
+       a testcase (321) depending on it.  It's unclear if the exact thing being
+       done really needs to be legitimate, though I suspect it reflects an
+       actual use-case that showed up a bug.
+       This is a hole in the taint-pretection, mitigated only in that
+       shell-syntax metachars cannot be injected via this route. */
+
+       DEBUG(D_transport) if (is_tainted(ad->address))
+         debug_printf("tainted element '%s' from $pipe_addresses\n", ad->address);
+
        argv[i++] = ad->address;
        argcount++;
        }
        argv[i++] = ad->address;
        argcount++;
        }
@@ -2292,7 +2328,11 @@ if (expand_arguments)
       for (int address_pipe_i = 0;
            address_pipe_argv[address_pipe_i];
            address_pipe_i++, argcount++)
       for (int address_pipe_i = 0;
            address_pipe_argv[address_pipe_i];
            address_pipe_i++, argcount++)
-        argv[i++] = address_pipe_argv[address_pipe_i];
+       {
+        uschar * s = address_pipe_argv[address_pipe_i];
+       if (arg_is_tainted(s, i, addr, etext, errptr)) return FALSE;
+        argv[i++] = s;
+       }
 
       /* Subtract one since we replace $address_pipe */
       argcount--;
 
       /* Subtract one since we replace $address_pipe */
       argcount--;
@@ -2321,6 +2361,17 @@ if (expand_arguments)
         else *errptr = msg;
         return FALSE;
         }
         else *errptr = msg;
         return FALSE;
         }
+
+      if ( f.running_in_test_harness && is_tainted(expanded_arg)
+        && Ustrcmp(etext, "queryprogram router") == 0)
+       {                       /* hack, would be good to not need it */
+       DEBUG(D_transport)
+         debug_printf("SPECIFIC TESTSUITE EXEMPTION: tainted arg '%s'\n",
+                     expanded_arg);
+       }
+      else if (  !allow_tainted_args
+             && arg_is_tainted(expanded_arg, i, addr, etext, errptr))
+       return FALSE;
       argv[i] = expanded_arg;
       }
     }
       argv[i] = expanded_arg;
       }
     }
@@ -2329,7 +2380,10 @@ if (expand_arguments)
     {
     debug_printf("direct command after expansion:\n");
     for (int i = 0; argv[i]; i++)
     {
     debug_printf("direct command after expansion:\n");
     for (int i = 0; argv[i]; i++)
-      debug_printf("  argv[%d] = %s\n", i, string_printing(argv[i]));
+      {
+      debug_printf("  argv[%d] = '%s'\n", i, string_printing(argv[i]));
+      debug_print_taint(argv[i]);
+      }
     }
   }
 
     }
   }
 
index 424210d393705ee7fc39e96226648563571c6fbd..638b52849f7dba1f325ed44d5df355d8b4c04c89 100644 (file)
@@ -489,8 +489,8 @@ if (ob->cmd)
   {
   DEBUG(D_transport) debug_printf("using command %s\n", ob->cmd);
   sprintf(CS buffer, "%.50s transport", tblock->name);
   {
   DEBUG(D_transport) debug_printf("using command %s\n", ob->cmd);
   sprintf(CS buffer, "%.50s transport", tblock->name);
-  if (!transport_set_up_command(&argv, ob->cmd, TRUE, PANIC, addrlist, buffer,
-       NULL))
+  if (!transport_set_up_command(&argv, ob->cmd, TRUE, PANIC, addrlist, FALSE,
+       buffer, NULL))
     return FALSE;
 
   /* If the -N option is set, can't do any more. Presume all has gone well. */
     return FALSE;
 
   /* If the -N option is set, can't do any more. Presume all has gone well. */
index 39875b3de8d282d42a2dce8d3efda23b402ae8b5..ed16c4c70a83c553a94c426c6b589808c00b8879 100644 (file)
@@ -304,7 +304,7 @@ the items if necessary. If it fails, this function fails (error information
 is in the addresses). */
 
 if (!transport_set_up_command(argvptr, cmd, expand_arguments, expand_fail,
 is in the addresses). */
 
 if (!transport_set_up_command(argvptr, cmd, expand_arguments, expand_fail,
-      addr, string_sprintf("%.50s transport", tname), NULL))
+      addr, FALSE, string_sprintf("%.50s transport", tname), NULL))
   return FALSE;
 
 /* Point to the set-up arguments. */
   return FALSE;
 
 /* Point to the set-up arguments. */
@@ -451,6 +451,9 @@ if (expand_arguments)
 
     for (address_item * ad = addr; ad; ad = ad->next)
       {
 
     for (address_item * ad = addr; ad; ad = ad->next)
       {
+      DEBUG(D_transport) if (is_tainted(ad->address))
+       debug_printf("tainted element '%s' from $pipe_addresses\n", ad->address);
+
       /*XXX string_append_listele() ? */
       if (ad != addr) g = string_catn(g, US" ", 1);
       g = string_cat(g, ad->address);
       /*XXX string_append_listele() ? */
       if (ad != addr) g = string_catn(g, US" ", 1);
       g = string_cat(g, ad->address);
@@ -575,6 +578,7 @@ if (!cmd || !*cmd)
   }
 if (is_tainted(cmd))
   {
   }
 if (is_tainted(cmd))
   {
+  DEBUG(D_transport) debug_printf("cmd '%s' is tainted\n", cmd);
   addr->message = string_sprintf("Tainted '%s' (command "
     "for %s transport) not permitted", cmd, tblock->name);
   addr->transport_return = PANIC;
   addr->message = string_sprintf("Tainted '%s' (command "
     "for %s transport) not permitted", cmd, tblock->name);
   addr->transport_return = PANIC;
index e38ea1502dbc8fc21e83a3bface4f7ea1178d8e8..19b06d8a928f0f13e2c3e86335aa0bac4e67864a 100644 (file)
@@ -3765,7 +3765,7 @@ if (tblock->filter_command)
   yield ERROR. */
 
   if (!transport_set_up_command(&transport_filter_argv,
   yield ERROR. */
 
   if (!transport_set_up_command(&transport_filter_argv,
-       tblock->filter_command, TRUE, DEFER, addrlist,
+       tblock->filter_command, TRUE, DEFER, addrlist, FALSE,
        string_sprintf("%.50s transport filter", tblock->name), NULL))
     {
     set_errno_nohost(addrlist->next, addrlist->basic_errno, addrlist->message, DEFER,
        string_sprintf("%.50s transport filter", tblock->name), NULL))
     {
     set_errno_nohost(addrlist->next, addrlist->basic_errno, addrlist->message, DEFER,
index b6f98f3845725bf89c4416c6e680d662c60f2471..b2d20b181cb60dc9501e0a304581ff81ac215fa5 100644 (file)
@@ -1,3 +1,8 @@
+# The map/match here detaints the $recipients
+#
 if $recipients contains pipe then
 if $recipients contains pipe then
-  pipe "DIR/aux-fixed/showenv $recipients"
+  pipe "DIR/aux-fixed/showenv \
+    \"${map {<, $recipients} \
+        {${if match_address {$item} {pipe@test.ex : another@test.ex : a-third@test.ex} {$value}}}}\""
 endif   
 endif   
+
index e58120d8a9c80e550cfb8d4424e91cbc8521184e..833d3e75a5da939525d62113776b92447a75bb86 100644 (file)
@@ -3,5 +3,9 @@
 if error_message then finish endif
 
 if $received_protocol is not scanned-ok then
 if error_message then finish endif
 
 if $received_protocol is not scanned-ok then
-  pipe "DIR/aux-fixed/resubmit $sender_address $recipients DIR/ CALLER"
+  pipe "DIR/aux-fixed/resubmit \
+       \"${if match_address {$sender_address}{CALLER@test.ex} {$value}}\" \
+       \"${map {<, $recipients} \
+               {${if match_address {$item} {userx@test.ex : usery@test.ex : userz@test.ex} { $value}}}}\" \
+       DIR/ CALLER"
 endif   
 endif   
index 78a5898a16062c9743a66ccdebdcddbbcef0eeb4..be69ca2c29f076d2eaaaa76ad19f72f901679752 100644 (file)
@@ -1,8 +1,13 @@
-# Exim filter (system filter for test 444)
+# Exim filter (system filter for test 0383)
 
 if error_message then finish endif
 
 if foranyaddress $h_to: ($thisaddress matches "^(alice)") then
 
 if error_message then finish endif
 
 if foranyaddress $h_to: ($thisaddress matches "^(alice)") then
+  pipe "DIR/aux-fixed/showenv \"${if match_address {$thisaddress}{alice@test.ex}{$value}}\" $1"
+  finish
+endif   
+
+if foranyaddress $h_to: ($thisaddress matches "^(marny)") then
   pipe "DIR/aux-fixed/showenv $thisaddress $1"
   finish
 endif   
   pipe "DIR/aux-fixed/showenv $thisaddress $1"
   finish
 endif   
index cf89fa83aa5f31d28bef33f11440b0abe7b6d25f..8fd0841cb26151f4de96b8b54cd50b0a7eb8768e 100644 (file)
@@ -25,11 +25,13 @@ all:
 mmdf_localuser:
   driver = accept
   local_part_prefix = mmdf-
 mmdf_localuser:
   driver = accept
   local_part_prefix = mmdf-
+  local_parts = userx
   transport = mmdf_local_delivery
 
 filtered_localuser:
   driver = accept
   local_part_prefix = filter-
   transport = mmdf_local_delivery
 
 filtered_localuser:
   driver = accept
   local_part_prefix = filter-
+  local_parts = userx
   transport = filtered_local_delivery
 
 bsmtp_localuser:
   transport = filtered_local_delivery
 
 bsmtp_localuser:
@@ -55,7 +57,7 @@ smtp:
 local_delivery:
   driver = pipe
   check_string = "From "
 local_delivery:
   driver = pipe
   check_string = "From "
-  command = /bin/sh -c 'cat >>DIR/test-mail/$local_part'
+  command = /bin/sh -c 'cat >>DIR/test-mail/$local_part_data'
   escape_string = ">From "
   user = CALLER
   current_directory = /
   escape_string = ">From "
   user = CALLER
   current_directory = /
@@ -63,7 +65,7 @@ local_delivery:
 bsmtp_local_delivery:
   driver = pipe
   use_bsmtp
 bsmtp_local_delivery:
   driver = pipe
   use_bsmtp
-  command = /bin/sh -c 'cat >>DIR/test-mail/$local_part'
+  command = /bin/sh -c 'cat >>DIR/test-mail/$local_part_data'
   delivery_date_add
   envelope_to_add
   return_path_add
   delivery_date_add
   envelope_to_add
   return_path_add
@@ -72,7 +74,7 @@ bsmtp_local_delivery:
 
 filtered_local_delivery:
   driver = pipe
 
 filtered_local_delivery:
   driver = pipe
-  command = /bin/sh -c 'cat >>DIR/test-mail/$local_part'
+  command = /bin/sh -c 'cat >>DIR/test-mail/$local_part_data'
   delivery_date_add
   envelope_to_add
   return_path_add
   delivery_date_add
   envelope_to_add
   return_path_add
@@ -83,7 +85,7 @@ filtered_local_delivery:
 mmdf_local_delivery:
   driver = pipe
   check_string = "\1\1\1\1\n"
 mmdf_local_delivery:
   driver = pipe
   check_string = "\1\1\1\1\n"
-  command = /bin/sh -c 'cat >>DIR/test-mail/$local_part'
+  command = /bin/sh -c 'cat >>DIR/test-mail/$local_part_data'
   escape_string = "\1\1\1\1 \n"
   message_prefix = "\1\1\1\1\n"
   message_suffix = "\1\1\1\1\n"
   escape_string = "\1\1\1\1 \n"
   message_prefix = "\1\1\1\1\n"
   message_suffix = "\1\1\1\1\n"
index 3376f05f3d14663326325e94f6234e9f17af9252..0358e12ae5731afe61e6e3548abcf91a62478647 100644 (file)
@@ -88,7 +88,7 @@ directfile:
 
 pipe:
   driver = pipe
 
 pipe:
   driver = pipe
-  command = /bin/sh -c "echo $local_part $domain >DIR/test-mail/$local_part"
+  command = /bin/sh -c "echo $local_part_data $domain_data >DIR/test-mail/$local_part_data"
   user = CALLER
 
 
   user = CALLER
 
 
index 4d0ac7c89526d84df279d60824e226f465714846..15906b996b0dea50b0b8df7bab373e6f88c20452 100644 (file)
@@ -45,7 +45,7 @@ pipe:
 piperet:
   driver = pipe
   batch_max = 100
 piperet:
   driver = pipe
   batch_max = 100
-  command = DIR/aux-fixed/TESTNUM.ret $h_ret:
+  command = DIR/aux-fixed/TESTNUM.ret "${if inlist {$h_ret:} {75:99} {$value}}"
   return_fail_output
   user = CALLER
 
   return_fail_output
   user = CALLER
 
index b063cdeb1a73ed99ea6050289eea653f2afd3c17..658ad15ce898f1514d45f3fa4453c780b4b09ba1 100644 (file)
@@ -29,7 +29,9 @@ begin transports
 
 pipe:
   driver = pipe
 
 pipe:
   driver = pipe
-  command = /non/exist/command -f <$sender_address> -d $pipe_addresses
+  command = /non/exist/command -f \
+       "<${if match_local_part {$sender_address}{CALLER@test.ex}{$value}}>" \
+       -d $pipe_addresses
   message_prefix =
   message_suffix =
   check_string =
   message_prefix =
   message_suffix =
   check_string =
index 511c541f690ed3d3badd149d3a28c27972386a15..a9eae39e54b21a3592358a5cd42e622a8d9787bd 100644 (file)
@@ -29,13 +29,13 @@ begin transports
 
 t1:
   driver = pipe
 
 t1:
   driver = pipe
-  command = /bin/sh -c 'exit $local_part'
+  command = /bin/sh -c 'exit "${if inlist {$local_part}{0:10:45}{$value}}"'
   user = CALLER
   temp_errors = 45 : 56
 
 t2:
   driver = pipe
   user = CALLER
   temp_errors = 45 : 56
 
 t2:
   driver = pipe
-  command = /bin/sh -c 'exit $local_part'
+  command = /bin/sh -c 'exit "${if inlist {$local_part}{0:10:45}{$value}}"'
   user = CALLER
   temp_errors = *
 
   user = CALLER
   temp_errors = *
 
index 44aff1cef7879eebf4b2164ea858f49a4bb6745e..4c5bcfbf60615ccecd519c848725784db962e2fd 100644 (file)
@@ -9,7 +9,7 @@ primary_hostname = myhost.test.ex
 qualify_domain = test.ex
 system_filter = DIR/aux-var/TESTNUM.F
 system_filter_pipe_transport = t1
 qualify_domain = test.ex
 system_filter = DIR/aux-var/TESTNUM.F
 system_filter_pipe_transport = t1
-
+log_selector = +received_recipients
 
 # ----- Routers -----
 
 
 # ----- Routers -----
 
index 981261206544b8b0aff1462ece737a061f61f6fb..6a877e2e9472a45626ae1ebba87b8fe00d5a68f5 100644 (file)
@@ -12,22 +12,40 @@ primary_hostname = myhost.test.ex
 
 begin routers
 
 
 begin routers
 
-r2:
+r0:
   driver = redirect
   local_part_prefix = pipe-
   local_part_suffix = =*
   caseful_local_part = true
   data = |${substr_1:$local_part_suffix}
   driver = redirect
   local_part_prefix = pipe-
   local_part_suffix = =*
   caseful_local_part = true
   data = |${substr_1:$local_part_suffix}
-  pipe_transport = t2
+  pipe_transport = t0
+
+r1:
+  driver = redirect
+  local_parts =        rtr_user
+  data = |echo $local_part
+  pipe_transport = t0
+
+r2:
+  driver = redirect
+  local_parts =        tpt_user
+  data = |unused_word
+  pipe_transport = t1
+  errors_to = ""
 
 
 # ----- Transports -----
 
 begin transports
 
 
 
 # ----- Transports -----
 
 begin transports
 
-t2:
+t0:
+  driver = pipe
+  user = CALLER
+
+t1:
   driver = pipe
   driver = pipe
+  force_command
+  command = echo $local_part
   user = CALLER
   user = CALLER
-  batch_max = 10
 
 # End
 
 # End
index 61a3711764e58b25223052a6793d74529530ff87..3cc4e8ade75ff636083bec6357d1bcb35f84bda8 100644 (file)
@@ -25,6 +25,7 @@ bounces:
 smartuser:
   driver = accept
   retry_use_local_part
 smartuser:
   driver = accept
   retry_use_local_part
+  address_data =       ${if inlist {$h_script:}{01:02:03:04:05:06:07:08:09:10} {$value}}
   transport = lmtp
 
 
   transport = lmtp
 
 
@@ -35,7 +36,7 @@ begin transports
 lmtp:
   driver = lmtp
   batch_max = 100
 lmtp:
   driver = lmtp
   batch_max = 100
-  command = DIR/bin/mtpscript DIR/aux-fixed/TESTNUM.script.$h_script: +DIR/spool/log/mainlog
+  command = DIR/bin/mtpscript DIR/aux-fixed/TESTNUM.script.$address_data +DIR/spool/log/mainlog
   timeout = 1s
   user = EXIMUSER
   ignore_quota = IGNORE_QUOTA
   timeout = 1s
   user = EXIMUSER
   ignore_quota = IGNORE_QUOTA
index b67df8c6dd6cc590477d32f0dc51d367030cf5b4..d47d17e98e8c241ba1850f3e9c338a39a2d84792 100644 (file)
@@ -1,13 +1,13 @@
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaX-0005vi-00 original recipients ignored (system filter)
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaX-0005vi-00 original recipients ignored (system filter)
-1999-03-02 09:44:33 10HmaX-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $recipients <system-filter> T=address_pipe: return message generated
+1999-03-02 09:44:33 10HmaX-0005vi-00 ** |TESTSUITE/aux-fixed/showenv "${map {<, $recipients} {${if match_address {$item} {pipe@test.ex : another@test.ex : a-third@test.ex} {$value}}}}" <system-filter> T=address_pipe: return message generated
 1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss
 1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER <CALLER@test.ex> R=user T=local_delivery
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaZ-0005vi-00 original recipients ignored (system filter)
 1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss
 1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER <CALLER@test.ex> R=user T=local_delivery
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaZ-0005vi-00 original recipients ignored (system filter)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $recipients <system-filter> T=address_pipe: return message generated
+1999-03-02 09:44:33 10HmaZ-0005vi-00 ** |TESTSUITE/aux-fixed/showenv "${map {<, $recipients} {${if match_address {$item} {pipe@test.ex : another@test.ex : a-third@test.ex} {$value}}}}" <system-filter> T=address_pipe: return message generated
 1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss
 1999-03-02 09:44:33 10HmbA-0005vi-00 => CALLER <CALLER@test.ex> R=user T=local_delivery
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss
 1999-03-02 09:44:33 10HmbA-0005vi-00 => CALLER <CALLER@test.ex> R=user T=local_delivery
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
index eab1f1f0ec28d8b0c495982dc7b3df2d39b6f746..8d964070c8b64b7964191abc08297adc3789a91b 100644 (file)
@@ -3,7 +3,7 @@
 1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex U=CALLER P=scanned-ok S=sss id=E10HmaX-0005vi-00@the.local.host.name
 1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@test.ex> R=all T=appendfile
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@test.ex U=CALLER P=scanned-ok S=sss id=E10HmaX-0005vi-00@the.local.host.name
 1999-03-02 09:44:33 10HmaY-0005vi-00 => userx <userx@test.ex> R=all T=appendfile
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaX-0005vi-00 => |TESTSUITE/aux-fixed/resubmit $sender_address $recipients TESTSUITE/ CALLER <system-filter> T=pipe
+1999-03-02 09:44:33 10HmaX-0005vi-00 => |TESTSUITE/aux-fixed/resubmit "${if match_address {$sender_address}{CALLER@test.ex} {$value}}" "${map {<, $recipients} {${if match_address {$item} {userx@test.ex : usery@test.ex : userz@test.ex} { $value}}}}" TESTSUITE/ CALLER <system-filter> T=pipe
 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaZ-0005vi-00 original recipients ignored (system filter)
 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaZ-0005vi-00 original recipients ignored (system filter)
@@ -12,5 +12,5 @@
 1999-03-02 09:44:33 10HmbA-0005vi-00 => usery <usery@test.ex> R=all T=appendfile
 1999-03-02 09:44:33 10HmbA-0005vi-00 => userz <userz@test.ex> R=all T=appendfile
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbA-0005vi-00 => usery <usery@test.ex> R=all T=appendfile
 1999-03-02 09:44:33 10HmbA-0005vi-00 => userz <userz@test.ex> R=all T=appendfile
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 => |TESTSUITE/aux-fixed/resubmit $sender_address $recipients TESTSUITE/ CALLER <system-filter> T=pipe
+1999-03-02 09:44:33 10HmaZ-0005vi-00 => |TESTSUITE/aux-fixed/resubmit "${if match_address {$sender_address}{CALLER@test.ex} {$value}}" "${map {<, $recipients} {${if match_address {$item} {userx@test.ex : usery@test.ex : userz@test.ex} { $value}}}}" TESTSUITE/ CALLER <system-filter> T=pipe
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
index 4ca9dc821d214172c55f4156d565d1f41906b3ad..7018dd54ee4fb351888df4fc4e5f20ea0dfa6bfc 100644 (file)
@@ -1,20 +1,27 @@
-1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for alice
 1999-03-02 09:44:33 10HmaX-0005vi-00 original recipients ignored (system filter)
 1999-03-02 09:44:33 10HmaX-0005vi-00 original recipients ignored (system filter)
-1999-03-02 09:44:33 10HmaX-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $thisaddress $1 <system-filter> T=t1: return message generated
-1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmaX-0005vi-00 ** |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" $1 <system-filter> T=t1: return message generated
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= <> R=10HmaX-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@test.ex
 1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaY-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
 1999-03-02 09:44:33 10HmaY-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaX-0005vi-00 Completed
-1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for marny
 1999-03-02 09:44:33 10HmaZ-0005vi-00 original recipients ignored (system filter)
 1999-03-02 09:44:33 10HmaZ-0005vi-00 original recipients ignored (system filter)
-1999-03-02 09:44:33 10HmaZ-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $1 <system-filter> T=t1: return message generated
-1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $thisaddress $1 <system-filter> T=t1: Tainted arg 1 for t1 transport command: 'marny@test.ex'
+1999-03-02 09:44:33 10HmbA-0005vi-00 <= <> R=10HmaZ-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@test.ex
 1999-03-02 09:44:33 10HmbA-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbA-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
 1999-03-02 09:44:33 10HmbA-0005vi-00 Completed
 1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
-1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmbB-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $thisaddress $1 <redking@test.ex> R=r0 T=t1: return message generated
-1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss
+1999-03-02 09:44:33 10HmbB-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for jabberwocky
+1999-03-02 09:44:33 10HmbB-0005vi-00 original recipients ignored (system filter)
+1999-03-02 09:44:33 10HmbB-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $1 <system-filter> T=t1: return message generated
+1999-03-02 09:44:33 10HmbC-0005vi-00 <= <> R=10HmbB-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@test.ex
 1999-03-02 09:44:33 10HmbC-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbC-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
 1999-03-02 09:44:33 10HmbC-0005vi-00 Completed
 1999-03-02 09:44:33 10HmbB-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbD-0005vi-00 <= CALLER@test.ex U=CALLER P=local S=sss for redking
+1999-03-02 09:44:33 10HmbD-0005vi-00 ** |TESTSUITE/aux-fixed/showenv $thisaddress $1 <redking@test.ex> R=r0 T=t1: return message generated
+1999-03-02 09:44:33 10HmbE-0005vi-00 <= <> R=10HmbD-0005vi-00 U=EXIMUSER P=local S=sss for CALLER@test.ex
+1999-03-02 09:44:33 10HmbE-0005vi-00 => CALLER <CALLER@test.ex> R=r1 T=t2
+1999-03-02 09:44:33 10HmbE-0005vi-00 Completed
+1999-03-02 09:44:33 10HmbD-0005vi-00 Completed
index db6a92e3966340f08cf02546890e72ae5291e587..4040fcdc7b9ae6ef2df7fd7ee221f3962c274ce9 100644 (file)
@@ -1,2 +1,8 @@
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
 1999-03-02 09:44:33 10HmaX-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 10HmaX-0005vi-00 == |TESTSUITE/bin/iefbr14 <pipe-userx=TESTSUITE/bin/iefbr14@test.ex> R=r2 T=t2 defer (0): Tainted 'TESTSUITE/bin/iefbr14' (command for t2 transport) not permitted
+1999-03-02 09:44:33 10HmaX-0005vi-00 == |TESTSUITE/bin/iefbr14 <pipe-userx=TESTSUITE/bin/iefbr14@test.ex> R=r0 T=t0 defer (0): Tainted 'TESTSUITE/bin/iefbr14' (command for t0 transport) not permitted
+1999-03-02 09:44:33 10HmaY-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaY-0005vi-00 == |echo rtr_user <rtr_user@test.ex> R=r1 T=t0 defer (0): Tainted 'echo rtr_user' (command for t0 transport) not permitted
+1999-03-02 09:44:33 10HmaZ-0005vi-00 <= CALLER@myhost.test.ex U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmaZ-0005vi-00 ** |unused_word <tpt_user@test.ex> R=r2 T=t1: Tainted arg 1 for t1 transport command: 'tpt_user'
+1999-03-02 09:44:33 10HmaZ-0005vi-00 |unused_word <tpt_user@test.ex>: error ignored
+1999-03-02 09:44:33 10HmaZ-0005vi-00 Completed
index 3bfb359b686bd857ca6f9be0bfcb4e83a7e8aa58..62c91e15f447c497c952d0e1d26fe4fefb294fb6 100644 (file)
@@ -22,12 +22,12 @@ This message was created automatically by mail delivery software.
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
-  pipe to |TESTSUITE/aux-fixed/showenv $recipients
+  pipe to |TESTSUITE/aux-fixed/showenv "${map {<, $recipients} {${if match_address {$item} {pipe@test.ex : another@test.ex : a-third@test.ex} {$value}}}}"
     generated by system-filter
 
 The following text was generated during the delivery attempt:
 
     generated by system-filter
 
 The following text was generated during the delivery attempt:
 
------- pipe to |TESTSUITE/aux-fixed/showenv $recipients
+------ pipe to |TESTSUITE/aux-fixed/showenv "${map {<, $recipients} {${if match_address {$item} {pipe@test.ex : another@test.ex : a-third@test.ex} {$value}}}}"
        generated by system-filter ------
 
 Test pipe script
        generated by system-filter ------
 
 Test pipe script
@@ -119,19 +119,19 @@ This message was created automatically by mail delivery software.
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
-  pipe to |TESTSUITE/aux-fixed/showenv $recipients
+  pipe to |TESTSUITE/aux-fixed/showenv "${map {<, $recipients} {${if match_address {$item} {pipe@test.ex : another@test.ex : a-third@test.ex} {$value}}}}"
     generated by system-filter
 
 The following text was generated during the delivery attempt:
 
     generated by system-filter
 
 The following text was generated during the delivery attempt:
 
------- pipe to |TESTSUITE/aux-fixed/showenv $recipients
+------ pipe to |TESTSUITE/aux-fixed/showenv "${map {<, $recipients} {${if match_address {$item} {pipe@test.ex : another@test.ex : a-third@test.ex} {$value}}}}"
        generated by system-filter ------
 
 Test pipe script
 Running as: CALLER
 ------------------
 Args:
        generated by system-filter ------
 
 Test pipe script
 Running as: CALLER
 ------------------
 Args:
-  pipe@test.ex, another@test.ex, a-third@test.ex
+  pipe@test.ex,another@test.ex,a-third@test.ex
 ----------current-----------
 /
 ----------env-----------
 ----------current-----------
 /
 ----------env-----------
index 2e62b0671ea2679afd4736d4cf681a9bb5d2f678..fb2f4f25c831351267196b1493d5e40ec9e1a8f0 100644 (file)
@@ -22,12 +22,12 @@ This message was created automatically by mail delivery software.
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
-  pipe to |TESTSUITE/aux-fixed/showenv $thisaddress $1
+  pipe to |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" $1
     generated by system-filter
 
 The following text was generated during the delivery attempt:
 
     generated by system-filter
 
 The following text was generated during the delivery attempt:
 
------- pipe to |TESTSUITE/aux-fixed/showenv $thisaddress $1
+------ pipe to |TESTSUITE/aux-fixed/showenv "${if match_address {$thisaddress}{alice@test.ex}{$value}}" $1
        generated by system-filter ------
 
 Test pipe script
        generated by system-filter ------
 
 Test pipe script
@@ -119,6 +119,59 @@ Content-type: text/plain; charset=us-ascii
 
 This message was created automatically by mail delivery software.
 
 
 This message was created automatically by mail delivery software.
 
+A message that you sent could not be delivered to one or more of its
+recipients. This is a permanent error. The following address(es) failed:
+
+  pipe to |TESTSUITE/aux-fixed/showenv $thisaddress $1
+    generated by system-filter
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/delivery-status
+
+Reporting-MTA: dns; myhost.test.ex
+
+Action: failed
+Final-Recipient: rfc822;system-filter
+Status: 5.0.0
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: message/rfc822
+
+Return-path: <CALLER@test.ex>
+Received: from CALLER by myhost.test.ex with local (Exim x.yz)
+       (envelope-from <CALLER@test.ex>)
+       id 10HmaZ-0005vi-00
+       for marny@test.ex;
+       Tue, 2 Mar 1999 09:44:33 +0000
+To: marny@test.ex
+Message-Id: <E10HmaZ-0005vi-00@myhost.test.ex>
+From: CALLER_NAME <CALLER@test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM--
+
+From MAILER-DAEMON Tue Mar 02 09:44:33 1999
+Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz)
+       id 10HmbC-0005vi-00
+       for CALLER@test.ex;
+       Tue, 2 Mar 1999 09:44:33 +0000
+X-Failed-Recipients: system-filter
+Auto-Submitted: auto-replied
+From: Mail Delivery System <Mailer-Daemon@test.ex>
+To: CALLER@test.ex
+References: <E10HmbB-0005vi-00@myhost.test.ex>
+Content-Type: multipart/report; report-type=delivery-status; boundary=NNNNNNNNNN-eximdsn-MMMMMMMMMM
+MIME-Version: 1.0
+Subject: Mail delivery failed: returning message to sender
+Message-Id: <E10HmbC-0005vi-00@myhost.test.ex>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+--NNNNNNNNNN-eximdsn-MMMMMMMMMM
+Content-type: text/plain; charset=us-ascii
+
+This message was created automatically by mail delivery software.
+
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
 A message that you sent could not be delivered to one or more of its
 recipients. This is a permanent error. The following address(es) failed:
 
@@ -149,7 +202,7 @@ LOCAL_PART_PREFIX=
 LOCAL_PART_SUFFIX=
 LOGNAME=system-filter
 ME=
 LOCAL_PART_SUFFIX=
 LOGNAME=system-filter
 ME=
-MESSAGE_ID=10HmaZ-0005vi-00
+MESSAGE_ID=10HmbB-0005vi-00
 PATH=/bin:/usr/bin
 QUALIFY_DOMAIN=test.ex
 RECIPIENT=system-filter@test.ex
 PATH=/bin:/usr/bin
 QUALIFY_DOMAIN=test.ex
 RECIPIENT=system-filter@test.ex
@@ -160,11 +213,11 @@ USER=system-filter
 >From CALLER@test.ex Tue Mar 02 09:44:33 1999
 Received: from CALLER by myhost.test.ex with local (Exim x.yz)
        (envelope-from <CALLER@test.ex>)
 >From CALLER@test.ex Tue Mar 02 09:44:33 1999
 Received: from CALLER by myhost.test.ex with local (Exim x.yz)
        (envelope-from <CALLER@test.ex>)
-       id 10HmaZ-0005vi-00
+       id 10HmbB-0005vi-00
        for jabberwocky@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 To: jabberwocky@test.ex
        for jabberwocky@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 To: jabberwocky@test.ex
-Message-Id: <E10HmaZ-0005vi-00@myhost.test.ex>
+Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
 From: CALLER_NAME <CALLER@test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
 From: CALLER_NAME <CALLER@test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
@@ -186,11 +239,11 @@ Content-type: message/rfc822
 Return-path: <CALLER@test.ex>
 Received: from CALLER by myhost.test.ex with local (Exim x.yz)
        (envelope-from <CALLER@test.ex>)
 Return-path: <CALLER@test.ex>
 Received: from CALLER by myhost.test.ex with local (Exim x.yz)
        (envelope-from <CALLER@test.ex>)
-       id 10HmaZ-0005vi-00
+       id 10HmbB-0005vi-00
        for jabberwocky@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 To: jabberwocky@test.ex
        for jabberwocky@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 To: jabberwocky@test.ex
-Message-Id: <E10HmaZ-0005vi-00@myhost.test.ex>
+Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
 From: CALLER_NAME <CALLER@test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
 From: CALLER_NAME <CALLER@test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
@@ -199,18 +252,18 @@ Date: Tue, 2 Mar 1999 09:44:33 +0000
 
 From MAILER-DAEMON Tue Mar 02 09:44:33 1999
 Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz)
 
 From MAILER-DAEMON Tue Mar 02 09:44:33 1999
 Received: from EXIMUSER by myhost.test.ex with local (Exim x.yz)
-       id 10HmbC-0005vi-00
+       id 10HmbE-0005vi-00
        for CALLER@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 X-Failed-Recipients: redking@test.ex
 Auto-Submitted: auto-replied
 From: Mail Delivery System <Mailer-Daemon@test.ex>
 To: CALLER@test.ex
        for CALLER@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 X-Failed-Recipients: redking@test.ex
 Auto-Submitted: auto-replied
 From: Mail Delivery System <Mailer-Daemon@test.ex>
 To: CALLER@test.ex
-References: <E10HmbB-0005vi-00@myhost.test.ex>
+References: <E10HmbD-0005vi-00@myhost.test.ex>
 Content-Type: multipart/report; report-type=delivery-status; boundary=NNNNNNNNNN-eximdsn-MMMMMMMMMM
 MIME-Version: 1.0
 Subject: Mail delivery failed: returning message to sender
 Content-Type: multipart/report; report-type=delivery-status; boundary=NNNNNNNNNN-eximdsn-MMMMMMMMMM
 MIME-Version: 1.0
 Subject: Mail delivery failed: returning message to sender
-Message-Id: <E10HmbC-0005vi-00@myhost.test.ex>
+Message-Id: <E10HmbE-0005vi-00@myhost.test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
 --NNNNNNNNNN-eximdsn-MMMMMMMMMM
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
 --NNNNNNNNNN-eximdsn-MMMMMMMMMM
@@ -249,7 +302,7 @@ LOCAL_PART_PREFIX=
 LOCAL_PART_SUFFIX=
 LOGNAME=redking
 ME=
 LOCAL_PART_SUFFIX=
 LOGNAME=redking
 ME=
-MESSAGE_ID=10HmbB-0005vi-00
+MESSAGE_ID=10HmbD-0005vi-00
 PATH=/bin:/usr/bin
 QUALIFY_DOMAIN=test.ex
 RECIPIENT=redking@test.ex
 PATH=/bin:/usr/bin
 QUALIFY_DOMAIN=test.ex
 RECIPIENT=redking@test.ex
@@ -260,11 +313,11 @@ USER=redking
 >From CALLER@test.ex Tue Mar 02 09:44:33 1999
 Received: from CALLER by myhost.test.ex with local (Exim x.yz)
        (envelope-from <CALLER@test.ex>)
 >From CALLER@test.ex Tue Mar 02 09:44:33 1999
 Received: from CALLER by myhost.test.ex with local (Exim x.yz)
        (envelope-from <CALLER@test.ex>)
-       id 10HmbB-0005vi-00
+       id 10HmbD-0005vi-00
        for redking@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 To: redking@test.ex
        for redking@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 To: redking@test.ex
-Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
+Message-Id: <E10HmbD-0005vi-00@myhost.test.ex>
 From: CALLER_NAME <CALLER@test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
 From: CALLER_NAME <CALLER@test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
@@ -286,11 +339,11 @@ Content-type: message/rfc822
 Return-path: <CALLER@test.ex>
 Received: from CALLER by myhost.test.ex with local (Exim x.yz)
        (envelope-from <CALLER@test.ex>)
 Return-path: <CALLER@test.ex>
 Received: from CALLER by myhost.test.ex with local (Exim x.yz)
        (envelope-from <CALLER@test.ex>)
-       id 10HmbB-0005vi-00
+       id 10HmbD-0005vi-00
        for redking@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 To: redking@test.ex
        for redking@test.ex;
        Tue, 2 Mar 1999 09:44:33 +0000
 To: redking@test.ex
-Message-Id: <E10HmbB-0005vi-00@myhost.test.ex>
+Message-Id: <E10HmbD-0005vi-00@myhost.test.ex>
 From: CALLER_NAME <CALLER@test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
 From: CALLER_NAME <CALLER@test.ex>
 Date: Tue, 2 Mar 1999 09:44:33 +0000
 
diff --git a/test/msglog/0594.10HmaX-0005vi-00 b/test/msglog/0594.10HmaX-0005vi-00
deleted file mode 100644 (file)
index f91a4a3..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-1999-03-02 09:44:33 Received from CALLER@myhost.test.ex U=CALLER P=local S=sss
-1999-03-02 09:44:33 |TESTSUITE/bin/iefbr14 <pipe-userx=TESTSUITE/bin/iefbr14@test.ex> R=r2 T=t2 defer (0): Tainted 'TESTSUITE/bin/iefbr14' (command for t2 transport) not permitted
index dc309d8a3e4160c4d28844ddcd525b870c627da1..1f53b724d647bdb31a73a647b3ab5cb2e30c3fee 100644 (file)
@@ -1 +1,2 @@
-1999-03-02 09:44:33 10HmaX-0005vi-00 == |TESTSUITE/bin/iefbr14 <pipe-userx=TESTSUITE/bin/iefbr14@test.ex> R=r2 T=t2 defer (0): Tainted 'TESTSUITE/bin/iefbr14' (command for t2 transport) not permitted
+1999-03-02 09:44:33 10HmaX-0005vi-00 == |TESTSUITE/bin/iefbr14 <pipe-userx=TESTSUITE/bin/iefbr14@test.ex> R=r0 T=t0 defer (0): Tainted 'TESTSUITE/bin/iefbr14' (command for t0 transport) not permitted
+1999-03-02 09:44:33 10HmaY-0005vi-00 == |echo rtr_user <rtr_user@test.ex> R=r1 T=t0 defer (0): Tainted 'echo rtr_user' (command for t0 transport) not permitted
index 463ad96e95222de94b67b03784ffcf05a8a4a518..d169518b6e7e3dc827c3844ae57c081b71a30a85 100644 (file)
@@ -802,6 +802,8 @@ rc=$runrc
 rc=$runrc
 ${if eq{1}{2}{${run{/non/exist}}}{1!=2}}
 rc=$runrc
 rc=$runrc
 ${if eq{1}{2}{${run{/non/exist}}}{1!=2}}
 rc=$runrc
+${run,preexpand {DIR/aux-fixed/0002.runfile 0}}
+rc=$runrc
 
 # PRVS
 
 
 # PRVS
 
index ab2f4480845df04907cb0481a2212856430da4f0..cf33255672ce15c0023d32e963c03df519beec93 100644 (file)
@@ -2,6 +2,9 @@
 exim -odi alice
 To: alice@test.ex
 ****
 exim -odi alice
 To: alice@test.ex
 ****
+exim -odi marny
+To: marny@test.ex
+****
 exim -odi jabberwocky
 To: jabberwocky@test.ex
 ****
 exim -odi jabberwocky
 To: jabberwocky@test.ex
 ****
index 5fbc9319c503235f8bbb20c1b4b849716b5b0cb2..73b565e48c119f23e4c65226fd4b184c4596bf3f 100644 (file)
@@ -2,3 +2,12 @@
 exim -odi pipe-userx=DIR/bin/iefbr14@test.ex
 A test message.
 ****
 exim -odi pipe-userx=DIR/bin/iefbr14@test.ex
 A test message.
 ****
+#
+exim -odi rtr_user@test.ex
+This one has an ok executable but tainted arg, pipecmd set by router
+****
+exim -odi tpt_user@test.ex
+This one has an ok executable but tainted arg, pipecmd set by transport
+****
+#
+no_msglog_check
index ac13db4cdca3a8fba867eada142e212e3313366c..dcd490152ccdec36311c62bba58e286fc57ed902 100644 (file)
@@ -14,7 +14,7 @@ dropping to exim gid; retaining priv uid
 direct command:
   argv[0] = '/bin/cat'
 direct command after expansion:
 direct command:
   argv[0] = '/bin/cat'
 direct command after expansion:
-  argv[0] = /bin/cat
+  argv[0] = '/bin/cat'
 appendfile transport entered
 appendfile: mode=600 notify_comsat=0 quota=0 warning=0
   file=TESTSUITE/test-mail/userx format=unix
 appendfile transport entered
 appendfile: mode=600 notify_comsat=0 quota=0 warning=0
   file=TESTSUITE/test-mail/userx format=unix
@@ -102,7 +102,7 @@ dropping to exim gid; retaining priv uid
 direct command:
   argv[0] = '${if={1}{1}{}{}}'
 direct command after expansion:
 direct command:
   argv[0] = '${if={1}{1}{}{}}'
 direct command after expansion:
-  argv[0] = 
+  argv[0] = ''
 appendfile transport entered
 appendfile: mode=600 notify_comsat=0 quota=0 warning=0
   file=TESTSUITE/test-mail/userx format=unix
 appendfile transport entered
 appendfile: mode=600 notify_comsat=0 quota=0 warning=0
   file=TESTSUITE/test-mail/userx format=unix
index dc309d8a3e4160c4d28844ddcd525b870c627da1..1f53b724d647bdb31a73a647b3ab5cb2e30c3fee 100644 (file)
@@ -1 +1,2 @@
-1999-03-02 09:44:33 10HmaX-0005vi-00 == |TESTSUITE/bin/iefbr14 <pipe-userx=TESTSUITE/bin/iefbr14@test.ex> R=r2 T=t2 defer (0): Tainted 'TESTSUITE/bin/iefbr14' (command for t2 transport) not permitted
+1999-03-02 09:44:33 10HmaX-0005vi-00 == |TESTSUITE/bin/iefbr14 <pipe-userx=TESTSUITE/bin/iefbr14@test.ex> R=r0 T=t0 defer (0): Tainted 'TESTSUITE/bin/iefbr14' (command for t0 transport) not permitted
+1999-03-02 09:44:33 10HmaY-0005vi-00 == |echo rtr_user <rtr_user@test.ex> R=r1 T=t0 defer (0): Tainted 'echo rtr_user' (command for t0 transport) not permitted
index f340b9426679d2672a3f54525dd5bd9745dd6017..74219a6f320f401ea59f3575530420cc8ea25ce0 100644 (file)
@@ -774,6 +774,10 @@ xyz
 > >><<
 > rc=0
 > 1!=2
 > >><<
 > rc=0
 > 1!=2
+> rc=0
+> abcd
+1234
+
 > rc=0
 > 
 > # PRVS
 > rc=0
 > 
 > # PRVS