[exim-cvs] Sieve: add redirect router option for inbox name

Top Page
Delete this message
Reply to this message
Author: Exim Git Commits Mailing List
Date:  
To: exim-cvs
Subject: [exim-cvs] Sieve: add redirect router option for inbox name
Gitweb: https://git.exim.org/exim.git/commitdiff/c7ff32cf0e6d2089261b223012aa8fdc3ed37933
Commit:     c7ff32cf0e6d2089261b223012aa8fdc3ed37933
Parent:     96e1245c1aad58dff560f929fd90972933a65341
Author:     Jeremy Harris <jgh146exb@???>
AuthorDate: Mon Jul 22 20:56:29 2024 +0100
Committer:  Jeremy Harris <jgh146exb@???>
CommitDate: Mon Jul 22 23:56:18 2024 +0100


    Sieve: add redirect router option for inbox name
---
 doc/doc-docbook/filter.xfpt  |  6 +++++-
 doc/doc-docbook/spec.xfpt    | 22 +++++++++++++++++++++-
 doc/doc-txt/NewStuff         | 22 +++++++++++++---------
 doc/doc-txt/OptionLists.txt  |  5 +++++
 src/src/routers/redirect.c   |  6 ++++--
 src/src/sieve.c              | 36 +++++++++++++++++++++++++++---------
 src/src/structs.h            |  5 +++--
 test/confs/0428              |  9 +++++++++
 test/log/0428                |  3 +++
 test/mail/0428.inbox.changed | 15 +++++++++++++++
 test/scripts/0000-Basic/0428 |  3 +++
 11 files changed, 108 insertions(+), 24 deletions(-)


diff --git a/doc/doc-docbook/filter.xfpt b/doc/doc-docbook/filter.xfpt
index 77b295ce9..87c268203 100644
--- a/doc/doc-docbook/filter.xfpt
+++ b/doc/doc-docbook/filter.xfpt
@@ -355,10 +355,14 @@ contains an additional address besides the one the test checks for.


.section "Semantics of keep" "SEC11"
-The &(keep)& command is equivalent to
+.new
+The &(keep)& command is by default equivalent to
.code
fileinto "inbox";
.endd
+but, when called from a redirect router, the destination can be set
+by using the &%sieve_inbox%& option on the router.
+.wen
It saves the message and resets the implicit keep flag. It does not set the
implicit keep flag; there is no command to set it once it has been reset.

diff --git a/doc/doc-docbook/spec.xfpt b/doc/doc-docbook/spec.xfpt
index 4abe2c9cb..cc5198ac5 100644
--- a/doc/doc-docbook/spec.xfpt
+++ b/doc/doc-docbook/spec.xfpt
@@ -22223,6 +22223,12 @@ subject to address rewriting. Otherwise, they are treated like new addresses
and are rewritten according to the global rewriting rules.


+.option sieve_inbox redirect string&!! &"inbox"&
+.new
+The value of this option is passed to a Sieve filter to specify the
+name of the mailbox used for "keep" operations (explicit or implicit).
+.wen
+
.option sieve_subaddress redirect string&!! unset
The value of this option is passed to a Sieve filter to specify the
:subaddress part of an address.
@@ -23259,7 +23265,11 @@ fileinto "folder23";
.endd
In this situation, the expansion of &%file%& or &%directory%& in the transport
must transform the relative path into an appropriate absolute filename. In the
-case of Sieve filters, the name &'inbox'& must be handled. It is the name that
+case of Sieve filters, the name &'inbox'& must be handled. It is the
+.new
+default
+.wen
+name that
is used as a result of a &"keep"& action in the filter. This example shows one
way of handling this requirement:
.code
@@ -23275,6 +23285,12 @@ With this setting of &%file%&, &'inbox'& refers to the standard mailbox
location, absolute paths are used without change, and other folders are in the
&_mail_& directory within the home directory.

+.new
+An alternative for the &"keep"& aspect is to use the &%sieve_inbox%& option
+on the redirect router that calls the Sieve filter,
+to explicitly set the filename used.
+.wen
+
&*Note 1*&: While processing an Exim filter, a relative path such as
&_folder23_& is turned into an absolute path if a home directory is known to
the router. In particular, this is the case if &%check_local_user%& is set. If
@@ -23285,6 +23301,10 @@ path to the transport.
&*Note 2*&: An absolute path in &$address_file$& is not treated specially;
the &%file%& or &%directory%& option is still used if it is set.

+.new
+&*Note 3*&: Permitting a user to enable writes to an absolute path
+may be a security issue.
+.wen



diff --git a/doc/doc-txt/NewStuff b/doc/doc-txt/NewStuff
index 778c3259e..012d71d68 100644
--- a/doc/doc-txt/NewStuff
+++ b/doc/doc-txt/NewStuff
@@ -6,6 +6,10 @@ Before a formal release, there may be quite a lot of detail so that people can
test from the snapshots or the Git before the documentation is updated. Once
the documentation is updated, this file is reduced to a short list.

+Version 4.98
+------------
+ 1. A sieve_inbox option for redirect routers
+
Version 4.98
------------
1. The dkim_status ACL condition may now be used in data ACLs
@@ -14,23 +18,23 @@ Version 4.98

  3. The dkim_timestamps signing option now accepts zero to include a current
     timestamp but no expiry timestamp.  Code by Simon Arlott; testsuite
-    additions by jgh.
+    additions by jgh


- 4. The recipients_max main option is now expanded.
+ 4. The recipients_max main option is now expanded

- 5. Setting variables for "exim -be" can set a tainted value.
+ 5. Setting variables for "exim -be" can set a tainted value

- 6. A dns:fail event.
+ 6. A dns:fail event

- 7. The dsearch lookup supports search for a sub-path.
+ 7. The dsearch lookup supports search for a sub-path

- 8. Include mailtest utility for simple connection checking.
+ 8. Include mailtest utility for simple connection checking

- 9. Add SMTP WELLKNOWN extension.
+ 9. Add SMTP WELLKNOWN extension

  10. Sqlite3 can be used for the hints databases (vs. DBD, NDB, GBDM, TDB).
-     Add "USE_SQLITE = y" and "DBMLIB = -lsqlite3" in Local/Makefile, to override 
-     the settings done in the OS/Makefile-<platform> file.
+     Add "USE_SQLITE = y" and "DBMLIB = -lsqlite3" in Local/Makefile, to
+     override the settings done in the OS/Makefile-<platform> file


 Version 4.97
 ------------
diff --git a/doc/doc-txt/OptionLists.txt b/doc/doc-txt/OptionLists.txt
index 987f096ba..e7b284760 100644
--- a/doc/doc-txt/OptionLists.txt
+++ b/doc/doc-txt/OptionLists.txt
@@ -535,6 +535,11 @@ server_set_id                        string*         unset         authenticator
 set                     string*         unset       routers         4.93
 shadow_condition                     string*         unset         transports
 shadow_transport                     string          unset         transports
+sieve_inbox                 string*         "inbox"       redirect         4.99
+sieve_enotify_mailto_owner         string*         "inbox"       redirect
+sieve_subaddress             string*         "inbox"       redirect
+sieve_useraddress             string*         "inbox"       redirect
+sieve_vacation_directory         string*         "inbox"       redirect
 size_addition                        integer         1024          smtp              1.91
 skip_syntax_errors                   boolean         false         redirect          4.00
 smtp_accept_keepalive                boolean         true          main
diff --git a/src/src/routers/redirect.c b/src/src/routers/redirect.c
index 08b7726b7..4da658781 100644
--- a/src/src/routers/redirect.c
+++ b/src/src/routers/redirect.c
@@ -92,6 +92,7 @@ optionlist redirect_router_options[] = {
       LOFF(bit_options) },


   { "sieve_enotify_mailto_owner", opt_stringptr, LOFF(sieve_enotify_mailto_owner) },
+  { "sieve_inbox",      opt_stringptr,    LOFF(sieve_inbox) },
   { "sieve_subaddress",   opt_stringptr,    LOFF(sieve_subaddress) },
   { "sieve_useraddress",  opt_stringptr,    LOFF(sieve_useraddress) },
   { "sieve_vacation_directory", opt_stringptr,    LOFF(sieve_vacation_directory) },
@@ -566,10 +567,11 @@ redirect.pw = pw;
 redirect.string = (redirect.isfile = (ob->file != NULL))
   ? ob->file : ob->data;


+sieve.inbox = ob->sieve_inbox;
+sieve.subaddress = ob->sieve_subaddress;
sieve.vacation_dir = ob->sieve_vacation_directory;
-sieve.enotify_mailto_owner = ob->sieve_enotify_mailto_owner;
sieve.useraddress = ob->sieve_useraddress;
-sieve.subaddress = ob->sieve_subaddress;
+sieve.enotify_mailto_owner = ob->sieve_enotify_mailto_owner;

 frc = rda_interpret(&redirect, options, ob->include_directory, &sieve, &ugid,
   &generated, &addr->message, ob->skip_syntax_errors ? &eblock : NULL,
diff --git a/src/src/sieve.c b/src/src/sieve.c
index db37f44fa..dbe64cffa 100644
--- a/src/src/sieve.c
+++ b/src/src/sieve.c
@@ -80,6 +80,7 @@ struct Sieve {
   BOOL    require_vacation;
   BOOL    vacation_ran;
 #endif
+  const uschar *inbox;
   const uschar *vacation_directory;
   const uschar *subaddress;
   const uschar *useraddress;
@@ -963,9 +964,10 @@ Returns:      nothing
 */


static void
-add_addr(address_item **generated, uschar *addr, int file, int maxage, int maxmessages, int maxstorage)
+add_addr(address_item ** generated, const uschar * addr, int file, int maxage,
+ int maxmessages, int maxstorage)
{
-address_item *new_addr;
+address_item * new_addr;

 for (new_addr = *generated; new_addr; new_addr = new_addr->next)
   if (  Ustrcmp(new_addr->address, addr) == 0
@@ -975,8 +977,10 @@ for (new_addr = *generated; new_addr; new_addr = new_addr->next)
     )
      )
     {
-    if ((filter_test != FTEST_NONE && debug_selector != 0) || (debug_selector & D_filter) != 0)
-      debug_printf_indent("Repeated %s `%s' ignored.\n", file ? "fileinto" : "redirect", addr);
+    if (  filter_test != FTEST_NONE && debug_selector != 0
+       || (debug_selector & D_filter) != 0)
+      debug_printf_indent("Repeated %s `%s' ignored.\n",
+              file ? "fileinto" : "redirect", addr);


     return;
     }
@@ -2775,7 +2779,7 @@ while (*filter->pc)
       return -1;
     if (exec)
       {
-      add_addr(generated, US"inbox", 1, 0, 0, 0);
+      add_addr(generated, filter->inbox, 1, 0, 0, 0);
       filter->keep = 0;
       }
     }
@@ -3513,6 +3517,7 @@ Arguments:
     enotify_mailto_owner    owner of mailto notifications
     useraddress            string expression for :user part of address
     subaddress            string expression for :subaddress part of address
+    inbox            string expression for "keep"
   generated   where to hang newly-generated addresses
   error       where to pass back an error text


@@ -3536,16 +3541,27 @@ DEBUG(D_route) debug_printf_indent("Sieve: start of processing\n");
expand_level++;
sieve.filter = filter;

+GET_OPTION("sieve_vacation_directory");
 if (!sb || !sb->vacation_dir)
   sieve.vacation_directory = NULL;
 else if (!(sieve.vacation_directory = expand_cstring(sb->vacation_dir)))
   {
   *error = string_sprintf("failed to expand \"%s\" "
-    "(sieve_vacation_directory): %s", sb->vacation_dir,
-    expand_string_message);
+    "(sieve_vacation_directory): %s", sb->vacation_dir, expand_string_message);
+  return FF_ERROR;
+  }
+
+GET_OPTION("sieve_vacation_directory");
+if (!sb || !sb->inbox)
+  sieve.inbox = US"inbox";
+else if (!(sieve.inbox = expand_cstring(sb->inbox)))
+  {
+  *error = string_sprintf("failed to expand \"%s\" "
+    "(sieve_inbox): %s", sb->inbox, expand_string_message);
   return FF_ERROR;
   }


+GET_OPTION("sieve_enotify_mailto_owner");
if (!sb || !sb->enotify_mailto_owner)
sieve.enotify_mailto_owner = NULL;
else if (!(sieve.enotify_mailto_owner = expand_cstring(sb->enotify_mailto_owner)))
@@ -3556,8 +3572,10 @@ else if (!(sieve.enotify_mailto_owner = expand_cstring(sb->enotify_mailto_owner)
return FF_ERROR;
}

+GET_OPTION("sieve_useraddress");
sieve.useraddress = sb && sb->useraddress
? sb->useraddress : CUS "$local_part_prefix$local_part$local_part_suffix";
+GET_OPTION("sieve_subaddress");
sieve.subaddress = sb ? sb->subaddress : NULL;

 #ifdef COMPILE_SYNTAX_CHECKER
@@ -3567,7 +3585,7 @@ if (parse_start(&sieve, 1, generated) == 1)
 #endif
   if (sieve.keep)
     {
-    add_addr(generated, US"inbox", 1, 0, 0, 0);
+    add_addr(generated, sieve.inbox, 1, 0, 0, 0);
     msg = US"Implicit keep";
     r = FF_DELIVERED;
     }
@@ -3583,7 +3601,7 @@ else
   r = FF_ERROR;
   *error = msg;
 #else
-  add_addr(generated, US"inbox", 1, 0, 0, 0);
+  add_addr(generated, sieve.inbox, 1, 0, 0, 0);
   r = FF_DELIVERED;
 #endif
   }
diff --git a/src/src/structs.h b/src/src/structs.h
index c11a5c6b1..95a1c1099 100644
--- a/src/src/structs.h
+++ b/src/src/structs.h
@@ -896,10 +896,11 @@ typedef struct redirect_block {
 /* Sieve control data */


typedef struct sieve_block {
- const uschar * vacation_dir;
+ const uschar * inbox;
const uschar * enotify_mailto_owner;
- const uschar * useraddress;
const uschar * subaddress;
+ const uschar * useraddress;
+ const uschar * vacation_dir;
} sieve_block;

/* Structure for passing arguments to check_host() */
diff --git a/test/confs/0428 b/test/confs/0428
index bb2c414fe..0f6614bcf 100644
--- a/test/confs/0428
+++ b/test/confs/0428
@@ -134,6 +134,15 @@ r2_14:
file_transport = t1
reply_transport = t3

+r2_15:
+  driver = redirect
+  local_parts = userx_inbox
+  allow_filter
+  data = "#Sieve filter\nkeep;\n"
+  user = CALLER
+  sieve_inbox = inbox.changed
+  file_transport = t1
+
 r2:
   driver = redirect
   allow_filter
diff --git a/test/log/0428 b/test/log/0428
index 7b0f948fc..7d20a6927 100644
--- a/test/log/0428
+++ b/test/log/0428
@@ -51,3 +51,6 @@
 1999-03-02 09:44:33 10HmbN-000000005vi-0000 => TESTSUITE/test-mail/userx14 <userx14-suffix2@???> R=r2_14 T=t1
 1999-03-02 09:44:33 10HmbN-000000005vi-0000 => TESTSUITE/test-mail/userx-sawsuffix <userx14-suffix@???> R=r2_14 T=t1
 1999-03-02 09:44:33 10HmbN-000000005vi-0000 Completed
+1999-03-02 09:44:33 10HmbO-000000005vi-0000 <= CALLER@??? U=CALLER P=local S=sss
+1999-03-02 09:44:33 10HmbO-000000005vi-0000 => TESTSUITE/test-mail/inbox.changed <userx_inbox@???> R=r2_15 T=t1
+1999-03-02 09:44:33 10HmbO-000000005vi-0000 Completed
diff --git a/test/mail/0428.inbox.changed b/test/mail/0428.inbox.changed
new file mode 100644
index 000000000..262d1a50d
--- /dev/null
+++ b/test/mail/0428.inbox.changed
@@ -0,0 +1,15 @@
+From CALLER@??? Tue Mar 02 09:44:33 1999
+Return-path: <CALLER@???>
+Envelope-to: userx_inbox@???
+Delivery-date: Tue, 2 Mar 1999 09:44:33 +0000
+Received: from CALLER by mail.test.ex with local (Exim x.yz)
+    (envelope-from <CALLER@???>)
+    id 10HmbO-000000005vi-0000
+    for userx_inbox@???;
+    Tue, 2 Mar 1999 09:44:33 +0000
+Message-Id: <E10HmbO-000000005vi-0000@???>
+From: CALLER_NAME <CALLER@???>
+Date: Tue, 2 Mar 1999 09:44:33 +0000
+
+Test 15
+
diff --git a/test/scripts/0000-Basic/0428 b/test/scripts/0000-Basic/0428
index 24c1b1265..f5aaa4124 100644
--- a/test/scripts/0000-Basic/0428
+++ b/test/scripts/0000-Basic/0428
@@ -101,3 +101,6 @@ exim -odi -f someone@??? userx14-suffix userx14-suffix2
         }   
 Test 14
 ****
+exim -odi userx_inbox
+Test 15
+****


--
## subscription configuration (requires account):
## https://lists.exim.org/mailman3/postorius/lists/exim-cvs.lists.exim.org/
## unsubscribe (doesn't require an account):
## exim-cvs-unsubscribe@???
## Exim details at http://www.exim.org/
## Please use the Wiki with this list - http://wiki.exim.org/