[Dovecot] Exposing global (default) sieve script through Managesieve
Hi folks,
I'm setting up a dovecot server with managesieve support. I'd like to offer spamfiltering through a Sieve script to my users by default, but still allow them to modify the filtering rules through Managesieve.
I found the sieve_global_path configuration option, which seems perfect for what I want. I can configure a default script there, which will work for all users until they set upload their own sieve script using managesieve.
However, when configured like this, the user experience isn't quite perfect. When users open the managesieve interface on their client, there is no trace of the default filters, so users might think the spamfiltering is done in some other manner. Now, when they create a filtering rule (e.g., to sort out mail to mailing lists), that rule will overwrite the default spamfiltering rule causing all the spam to spill into the user's mailbox. I'm afraid that most users won't realize they have to manually recreate the spamfiltering rule to fix this. Also, they might not know how to write the rule, even if they do...
I've considered a few existing ways to fix this:
Use sieve_before / sieve_after to make sure that the default script is always executed, in addition to any user-supplied scripts. This removes the surprise, but removes the option for users to tweak the spamfiltering rules.
Don't use sieve_global_path, but instead distribute the default script to each user's homedir on user creation. This prevents making changes to the default script for existing users and in my setup, user creation and (mail)homedir creation are nicely separated through an LDAP directory, I'd rather not go this route.
When using the Roundcube webmail application as the IMAP client, I can point Roundcube at the default sieve script. Now, when Roundcube sees there are no scripts through ManageSieve, it shows a (fake) "default" script with the correct contents. As soon as the user changes this script or creates a new script, it is actually uploaded to Dovecot, causing the edited script to be used instead of the global script.
This option has the user experience I'm looking for, but having this out-of-band connection from Roundcube to the default script configured with dovecot is ugly (and tricky, since these run on different hosts in my setup). The biggest problem is of course that this only works for Roundcube, not for any other IMAP client my users might use.
So, I was wondering: Wouldn't it make sense for the managesieve plugin to do something similar to roundcube: When the user has no sieve script configured, let it fake a single "default" script, showing the contents of the global script?
Since the ManageSieve protocol doesn't seem to support any way to flag this situation, it would be fooling the clients a bit, but I'm not sure if that's really a problem.
While the user has not script named "default" in his sieve_dir:
- include a script called "default" in the LISTSCRIPTS output.
- return the contents of the sieve_global_path in the GETSCRIPT "default" command.
- remove any sieve symlink after a SETACTIVE "default" command (as if SETACTIVE "" was given). This causes dovecot to fall back to the sieve_global_path script.
- the DELETESCRIPT "default" command should fail. This might confuse clients and users, since it is listed in LISTSCRIPTS but cannot be deleted, but I think most users will understand they can't delete the default script.
- RENAMESCRIPT "default" "some_name" should copy the sieve_global_path script into the user's sieve_dir. This will effectively copy the script instead of renaming it (since it will still be magically listed in LISTSCRIPTS), so that might be confusing.
All other commands work just like they do now (in particular, PUTSCRIPT "default" uploads a script called "default" into the user's sieve_dir, preventing all of the above from applying.
As noted above, this change might cause some confusion, but I think that is manageable. On additional thing is that running SETACTIVE "" will not completely disable sieve processing (as would be expected), but will (again) cause the sieve_global_path script to be run. This is already the case currently, though, and should probably be considered a separate problem (whose root cause is the lack of a difference between "no script script configured yet" and "active script disabled", both remove the sieve symlink). Also, this problem might be a feature in some setups, so fixing it might not be so easy...
So, any thoughts on this? Any fundamental problems I'm missing? (Not-so) obvious alternatives?
Gr.
Matthijs
Hi Matthijs,
On 6/1/2012 8:27 PM, Matthijs Kooijman wrote:
I'm setting up a dovecot server with managesieve support. I'd like to offer spamfiltering through a Sieve script to my users by default, but still allow them to modify the filtering rules through Managesieve.
I found the sieve_global_path configuration option, which seems perfect for what I want. I can configure a default script there, which will work for all users until they set upload their own sieve script using managesieve.
However, when configured like this, the user experience isn't quite perfect. When users open the managesieve interface on their client, there is no trace of the default filters, so users might think the spamfiltering is done in some other manner. Now, when they create a filtering rule (e.g., to sort out mail to mailing lists), that rule will overwrite the default spamfiltering rule causing all the spam to spill into the user's mailbox. I'm afraid that most users won't realize they have to manually recreate the spamfiltering rule to fix this. Also, they might not know how to write the rule, even if they do...
You asked this one on IRC a while back right?
I've considered a few existing ways to fix this:
- Use sieve_before / sieve_after to make sure that the default script is always executed, in addition to any user-supplied scripts. This removes the surprise, but removes the option for users to tweak the spamfiltering rules.
Right.
- Don't use sieve_global_path, but instead distribute the default script to each user's homedir on user creation. This prevents making changes to the default script for existing users and in my setup, user creation and (mail)homedir creation are nicely separated through an LDAP directory, I'd rather not go this route.
Well, we could achieve something that looks very similar from the outside: we could do some sort of copy-on-write scheme in which users see the default script as the active one, until they first modify their Sieve configuration through ManageSieve. Once they modify their default script, they'll get their own copy. If they activate a script different from the default and then later decide to deactivate it, their default will not return as the (implicit) active one. This would be very different from the current global default script behavior. It is more like an initial placeholder and template, than something that is always active when the user has no active script of its own.
When using the Roundcube webmail application as the IMAP client, I can point Roundcube at the default sieve script. Now, when Roundcube sees there are no scripts through ManageSieve, it shows a (fake) "default" script with the correct contents. As soon as the user changes this script or creates a new script, it is actually uploaded to Dovecot, causing the edited script to be used instead of the global script
This option has the user experience I'm looking for, but having this out-of-band connection from Roundcube to the default script configured with dovecot is ugly (and tricky, since these run on different hosts in my setup). The biggest problem is of course that this only works for Roundcube, not for any other IMAP client my users might use.
Agreed, this is ugly since it uses a side-channel. Client dependence is also very bad.
So, I was wondering: Wouldn't it make sense for the managesieve plugin to do something similar to roundcube: When the user has no sieve script configured, let it fake a single "default" script, showing the contents of the global script?
Since the ManageSieve protocol doesn't seem to support any way to flag this situation, it would be fooling the clients a bit, but I'm not sure if that's really a problem.
While the user has not script named "default" in his sieve_dir:
- include a script called "default" in the LISTSCRIPTS output.
- return the contents of the sieve_global_path in the GETSCRIPT "default" command.
- remove any sieve symlink after a SETACTIVE "default" command (as if SETACTIVE "" was given). This causes dovecot to fall back to the sieve_global_path script.
- the DELETESCRIPT "default" command should fail. This might confuse clients and users, since it is listed in LISTSCRIPTS but cannot be deleted, but I think most users will understand they can't delete the default script.
- RENAMESCRIPT "default" "some_name" should copy the sieve_global_path script into the user's sieve_dir. This will effectively copy the script instead of renaming it (since it will still be magically listed in LISTSCRIPTS), so that might be confusing.
All other commands work just like they do now (in particular, PUTSCRIPT "default" uploads a script called "default" into the user's sieve_dir, preventing all of the above from applying.
This looks sensible. The only thing that may be an issue is the DELETESCRIPT "default" situation you describe above, but I'm confident most - if not all clients - will handle that gracefully.
As noted above, this change might cause some confusion, but I think that is manageable. On additional thing is that running SETACTIVE "" will not completely disable sieve processing (as would be expected), but will (again) cause the sieve_global_path script to be run. This is already the case currently, though, and should probably be considered a separate problem (whose root cause is the lack of a difference between "no script script configured yet" and "active script disabled", both remove the sieve symlink). Also, this problem might be a feature in some setups, so fixing it might not be so easy...
The copy-on-write scheme I describe above may solve this, as it remembers (somehow) the status of the account: either an untouched/unconfigured account or an account with no active scripts. This behavior could be combined with the solution you describe above.
Any fundamental problems I'm missing? (Not-so) obvious alternatives?
None that I see right now.
In my last release of Pigeonhole I added support for putting scripts inside a dict database (or any other storage facility once implemented). Support for ManageSieve accessing such alternative data stores is lacking still, but, once I implement that, I also intend to address the issue you describe here. I'm probably going to structure it very similar to Dovecot's own mail storage library, meaning that plugins can override certain aspects of the storage's behavior. This should allow for all kinds of magic in the script storage, including what you describe above.
As always, such big changes will take some time...
Regards,
Stephan.
Hi Stephan,
You asked this one on IRC a while back right? Yup, that was me.
The copy-on-write scheme I describe above may solve this, as it
remembers (somehow) the status of the account: either an
untouched/unconfigured account or an account with no active scripts.
This behavior could be combined with the solution you describe above. Yeah, the copy-on-write approach is probably a good idea.
A downside of the copy-on-write approach is that if you change the global script later on, it doesn't affect users that made any changes to their sieve configuration (as opposed to my proposal, where only changes to the actual "default" script would prevent this). However, I mentioning this just for completeness, since I don't really think this is much of a problem.
Also, the "no sieve configured" case could be detected by the existence of a sieve_directory, perhaps?
In my last release of Pigeonhole I added support for putting scripts
inside a dict database (or any other storage facility once implemented).
Support for ManageSieve accessing such alternative data stores is
lacking still, but, once I implement that, I also intend to address the
issue you describe here. I'm probably going to structure it very similar
to Dovecot's own mail storage library, meaning that plugins can override
certain aspects of the storage's behavior. This should allow for all
kinds of magic in the script storage, including what you describe above. Would it make sense to implement such magin inside the script storage, or on top of it? The latter means the magic will work for every storage implemented, which would be an advantage?
In any case, if there is some lookout onto this feature, I might configure the Roundcube plugin thing now and upgrade to a real solution at some later point.
Gr.
Matthijs
On 6/3/2012 10:57 PM, Matthijs Kooijman wrote:
The copy-on-write scheme I describe above may solve this, as it remembers (somehow) the status of the account: either an untouched/unconfigured account or an account with no active scripts. This behavior could be combined with the solution you describe above. Yeah, the copy-on-write approach is probably a good idea.
A downside of the copy-on-write approach is that if you change the global script later on, it doesn't affect users that made any changes to their sieve configuration (as opposed to my proposal, where only changes to the actual "default" script would prevent this). However, I mentioning this just for completeness, since I don't really think this is much of a problem.
Also, the "no sieve configured" case could be detected by the existence of a sieve_directory, perhaps?
Something like that, yes.
In my last release of Pigeonhole I added support for putting scripts inside a dict database (or any other storage facility once implemented). Support for ManageSieve accessing such alternative data stores is lacking still, but, once I implement that, I also intend to address the issue you describe here. I'm probably going to structure it very similar to Dovecot's own mail storage library, meaning that plugins can override certain aspects of the storage's behavior. This should allow for all kinds of magic in the script storage, including what you describe above. Would it make sense to implement such magic inside the script storage, or on top of it? The latter means the magic will work for every storage implemented, which would be an advantage?
Definitely on top.
Regards,
Stephan.
participants (2)
-
Matthijs Kooijman
-
Stephan Bosch