dovecot-2.1-pigeonhole: Added support for specifying multiple si...

pigeonhole at rename-it.nl pigeonhole at rename-it.nl
Mon Apr 30 10:10:50 EEST 2012


details:   http://hg.rename-it.nl/dovecot-2.1-pigeonhole/rev/b2ff597c2279
changeset: 1618:b2ff597c2279
user:      Stephan Bosch <stephan at rename-it.nl>
date:      Mon Apr 30 09:10:44 2012 +0200
description:
Added support for specifying multiple sieve_before and sieve_after paths.
Additional paths are specified by adding a sequence number (starting at 2) to the setting name.
Added support for specifying home-relative paths for sieve_before and sieve_after.
This enables administrators to specify user-specific global Sieve scripts that cannot be viewed or changed by virtual users.

diffstat:

 INSTALL                                  |  44 ++++++++++++++++-----
 README                                   |  10 ++--
 doc/example-config/conf.d/90-sieve.conf  |  14 ++++-
 src/lib-sieve/sieve.c                    |  20 +++++++++
 src/plugins/lda-sieve/lda-sieve-plugin.c |  66 ++++++++++++++++++-------------
 5 files changed, 107 insertions(+), 47 deletions(-)

diffs (251 lines):

diff -r f146790b5db3 -r b2ff597c2279 INSTALL
--- a/INSTALL	Fri Apr 27 02:28:13 2012 +0200
+++ b/INSTALL	Mon Apr 30 09:10:44 2012 +0200
@@ -260,15 +260,25 @@
 config file control the execution sequence:
 
  sieve_before =
+ sieve_before2 =
+ sieve_before3 = (etc..)
    Path to a script file or a directory containing script files that need to be
-   executed before the user's script. If the path points to a directory, all the
-   Sieve scripts contained therein (with the proper .sieve extension) are
-   executed. The order of execution is determined by the file names, using a
-   normal 8bit per-character comparison. 
+   executed before the user's personal script. If the path points to a
+   directory, all the Sieve scripts contained therein (with the proper .sieve
+   extension) are executed. The order of execution within that directory is
+   determined by the file names, using a normal 8bit per-character comparison.
+   
+   Multiple script file or directory paths can be specified by appending an
+   increasing number. The Sieve scripts found from these paths are added to the
+   script execution sequence in the specified order. Reading the numbered
+   sieve_before settings stops at the first missing setting, so no numbers may
+   be skipped.
 
  sieve_after =
-   Identical to sieve_before, only the specified scripts are executed after the
-   user's script (only when keep is still in effect!). 
+ sieve_after2 =
+ sieve_after3 = (etc..)
+   Identical to sieve_before, but the specified scripts are executed after the
+   user's script (only when keep is still in effect, as explained below). 
 
 The script execution ends when the currently executing script in the sequence
 does not yield a "keep" result: when the script terminates, the next script is 
@@ -302,17 +312,29 @@
 
 plugin {
 ...
-   # Scripts executed before the user's script.
+   # Global scripts executed before the user's personal script.
    #   E.g. handling messages marked as dangerous
    sieve_before = /var/lib/dovecot/sieve/discard-virusses.sieve
 
-   # Scripts executed after the user's script (if keep is still in effect)
+   # User-specific scripts executed before the user's personal script.
+   #   E.g. a vacation script managed through a non-ManageSieve GUI.
+   sieve_before2 = /var/vmail/%d/%n/sieve-before
+
+   # User-specific scripts executed after the user's personal script.
+   # (if keep is still in effect)
+   #   E.g. user-specific default mail filing rules
+   sieve_after = /var/vmail/%d/%n/sieve-after
+
+   # Global scripts executed after the user's personal script 
+   # (if keep is still in effect)
    #   E.g. default mail filing rules.
-   sieve_after = /var/lib/dovecot/sieve/after.d/
+   sieve_after2 = /var/lib/dovecot/sieve/after.d/
 }
 
-IMPORTANT: Be sure to manually pre-compile the scripts specified by sieve_before 
-and sieve_after using the sievec tool, as explained in the README file.
+IMPORTANT: The scripts specified by sieve_before and sieve_after are often
+located in global locations to which the Sieve interpreter has no write access.
+In that case be sure to manually pre-compile those scripts using the sievec
+tool, as explained in the README file.
 
 Sieve Interpreter - Extension Configuration
 -------------------------------------------
diff -r f146790b5db3 -r b2ff597c2279 README
--- a/README	Fri Apr 27 02:28:13 2012 +0200
+++ b/README	Mon Apr 30 09:10:44 2012 +0200
@@ -209,11 +209,11 @@
 
 sievec /var/lib/dovecot/sieve/global/
 
-This is necessary for scripts listed in the sieve_default, sieve_before and
-sieve_after settings. For global scripts that are only included in other scripts
-using the include extension, this step is not necessary, since included scripts
-are incorporated into the binary produced for the main script located in a
-user directory.
+This is often necessary for scripts listed in the sieve_default, sieve_before
+and sieve_after settings. For global scripts that are only included in other
+scripts using the include extension, this step is not necessary, since included
+scripts are incorporated into the binary produced for the main script located in
+a user directory.
 
 Compile and Runtime Logging
 ===========================
diff -r f146790b5db3 -r b2ff597c2279 doc/example-config/conf.d/90-sieve.conf
--- a/doc/example-config/conf.d/90-sieve.conf	Fri Apr 27 02:28:13 2012 +0200
+++ b/doc/example-config/conf.d/90-sieve.conf	Mon Apr 30 09:10:44 2012 +0200
@@ -28,14 +28,20 @@
   # Path to a script file or a directory containing script files that need to be
   # executed before the user's script. If the path points to a directory, all
   # the Sieve scripts contained therein (with the proper .sieve extension) are
-  # executed. The order of execution is determined by the file names, using a
-  # normal 8bit per-character comparison. 
+  # executed. The order of execution within a directory is determined by the
+  # file names, using a normal 8bit per-character comparison. Multiple script
+  # file or directory paths can be specified by appending an increasing number.
   #sieve_before =
+  #sieve_before2 =
+  #sieve_before3 = (etc...)
 
   # Identical to sieve_before, only the specified scripts are executed after the
-  # user's script (only when keep is still in effect!). 
+  # user's script (only when keep is still in effect!). Multiple script file or
+  # directory paths can be specified by appending an increasing number.
   #sieve_after =
-   
+  #sieve_after2 = 
+  #sieve_after2 = (etc...)
+
   # Which Sieve language extensions are available to users. By default, all 
   # supported extensions are available, except for deprecated extensions or
   # those that are still under development. Some system administrators may want
diff -r f146790b5db3 -r b2ff597c2279 src/lib-sieve/sieve.c
--- a/src/lib-sieve/sieve.c	Fri Apr 27 02:28:13 2012 +0200
+++ b/src/lib-sieve/sieve.c	Mon Apr 30 09:10:44 2012 +0200
@@ -6,6 +6,7 @@
 #include "istream.h"
 #include "buffer.h"
 #include "eacces-error.h"
+#include "home-expand.h"
 
 #include "sieve-limits.h"
 #include "sieve-settings.h"
@@ -715,6 +716,25 @@
 	if ( error_r != NULL )
 		*error_r = SIEVE_ERROR_NONE;
 
+	if ( (path[0] == '~' && (path[1] == '/' || path[1] == '\0')) || 
+		(((svinst->flags & SIEVE_FLAG_HOME_RELATIVE) != 0 ) && path[0] != '/') ) {
+		/* Home-relative path. change to absolute. */
+		const char *home = sieve_environment_get_homedir(svinst);
+
+		if ( home != NULL ) {
+			if ( path[0] == '~' && (path[1] == '/' || path[1] == '\0') )
+				path = home_expand_tilde(path, home);
+			else
+				path = t_strconcat(home, "/", path, NULL);
+		} else {
+			sieve_sys_error(svinst,
+				"sieve dir path %s is relative to home directory, "
+				"but home directory is not available.", path);
+			*error_r = SIEVE_ERROR_TEMP_FAIL;
+			return NULL;
+		}
+	}
+
 	/* Specified path can either be a regular file or a directory */
 	if ( stat(path, &st) != 0 ) {
 		switch ( errno ) {
diff -r f146790b5db3 -r b2ff597c2279 src/plugins/lda-sieve/lda-sieve-plugin.c
--- a/src/plugins/lda-sieve/lda-sieve-plugin.c	Fri Apr 27 02:28:13 2012 +0200
+++ b/src/plugins/lda-sieve/lda-sieve-plugin.c	Mon Apr 30 09:10:44 2012 +0200
@@ -562,7 +562,9 @@
 	struct sieve_exec_status estatus;
 	struct sieve_error_handler *master_ehandler;
 	const char *user_location, *default_location, *sieve_before, *sieve_after;
+	const char *setting_name;
 	ARRAY_TYPE(sieve_scripts) script_sequence;
+	unsigned int after_index;
 	bool debug = mdctx->dest_user->mail_debug;
 	enum sieve_error error;
 	int ret = 0;
@@ -651,21 +653,27 @@
 
 		t_array_init(&script_sequence, 16);
 
-		sieve_before = mail_user_plugin_getenv(mdctx->dest_user, "sieve_before");
-		if ( sieve_before != NULL && *sieve_before != '\0' ) {
-			if ( lda_sieve_multiscript_get_scripts(svinst, "sieve_before",
-				sieve_before, master_ehandler, &script_sequence) == 0 && debug ) {
-				sieve_sys_debug(svinst, "sieve_before location not found: %s",
-					sieve_before);
+		i = 2;
+		setting_name = "sieve_before";
+		sieve_before = mail_user_plugin_getenv(mdctx->dest_user, setting_name);
+		while ( sieve_before != NULL && *sieve_before != '\0' ) {
+			if ( debug && lda_sieve_multiscript_get_scripts
+				(svinst, setting_name, sieve_before, master_ehandler,
+					&script_sequence) == 0 ) {
+				sieve_sys_debug(svinst, "%s location not found: %s",
+					setting_name, sieve_before);
 			}
+			setting_name = t_strdup_printf("sieve_before%u", i++);
+			sieve_before = mail_user_plugin_getenv(mdctx->dest_user, setting_name);
+		}
 
-			if ( debug ) {
-				scripts = array_get(&script_sequence, &count);
-				for ( i = 0; i < count; i ++ ) {
-					sieve_sys_debug(svinst, "executed before user's Sieve script(%d): %s",
-						i+1, sieve_script_location(scripts[i]));
-				}				
-			}
+		if ( debug ) {	
+			scripts = array_get(&script_sequence, &count);
+			for ( i = 0; i < count; i ++ ) {
+				sieve_sys_debug(svinst,
+					"executed before user's personal Sieve script(%d): %s",
+					i+1, sieve_script_location(scripts[i]));
+			}				
 		}
 
 		if ( srctx.main_script != NULL ) {
@@ -678,23 +686,27 @@
 			}
 		}
 
-		sieve_after = mail_user_plugin_getenv(mdctx->dest_user, "sieve_after");
-		if ( sieve_after != NULL && *sieve_after != '\0' ) {
-			unsigned int after_index = array_count(&script_sequence);
+		after_index = array_count(&script_sequence);
 
-			if ( lda_sieve_multiscript_get_scripts(svinst, "sieve_after",
+		i = 2;
+		setting_name = "sieve_after";
+		sieve_after = mail_user_plugin_getenv(mdctx->dest_user, setting_name);
+		while ( sieve_after != NULL && *sieve_after != '\0' ) {
+			if ( lda_sieve_multiscript_get_scripts(svinst, setting_name,
 				sieve_after, master_ehandler, &script_sequence) == 0 && debug ) {
-				sieve_sys_debug(svinst, "sieve_after location not found: %s",
-					sieve_after);
+				sieve_sys_debug(svinst, "%s location not found: %s",
+					setting_name, sieve_after);
 			}
-
-			if ( debug ) {
-				scripts = array_get(&script_sequence, &count);
-				for ( i = after_index; i < count; i ++ ) {
-					sieve_sys_debug(svinst, "executed after user's Sieve script(%d): %s",
-						i+1, sieve_script_location(scripts[i]));
-				}				
-			}
+			setting_name = t_strdup_printf("sieve_after%u", i++);
+			sieve_after = mail_user_plugin_getenv(mdctx->dest_user, setting_name);
+		}
+	
+		if ( debug ) {
+			scripts = array_get(&script_sequence, &count);
+			for ( i = after_index; i < count; i ++ ) {
+				sieve_sys_debug(svinst, "executed after user's Sieve script(%d): %s",
+					i+1, sieve_script_location(scripts[i]));
+			}				
 		}
 
 		srctx.scripts =


More information about the dovecot-cvs mailing list