Pigeonhole Sieve Configuration
==============================

Script Locations
----------------

The Sieve interpreter can retrieve Sieve scripts from several types of
locations. The default 'file' location type is a local filesystem path pointing
to a Sieve script file or a directory containing multiple Sieve script files.
More complex setups can use other location types such as 'ldap' or 'dict' to
fetch Sieve scripts from remote databases.

All settings that specify the location of one ore more Sieve scripts accept the
following syntax::

---%<-------------------------------------------------------------------------
location = [<type>:]path[;<option>[=<value>][;...]]
---%<-------------------------------------------------------------------------

The following script location types are implemented by default:

file :
  The location path is a file system path pointing to the script file or a
  directory containing script files with names structured as
  '<script-name>.sieve'. Read <this wiki page>
  [Pigeonhole.Sieve.Configuration.File.txt] for more information and examples.

dict :
  The location path is a Dovecot dict uri. Read <this wiki page>
  [Pigeonhole.Sieve.Configuration.Dict.txt] for more information and examples.

ldap :
  LDAP database lookup. The location path is a configuration file with LDAP
  options. Read <this wiki page> [Pigeonhole.Sieve.Configuration.LDAP.txt] for
  more information and examples.

If the type prefix is omitted, the script location type is 'file' and the
location is interpreted as a local filesystem path pointing to a Sieve script
file or directory.

The following options are defined for all location types:

name=<script-name> :
  Set the name of the Sieve script that this location points to. If the name of
  the Sieve script is not contained in the location path and the location of a
  single script is specified, this option is required (e.g. for 'dict'
  locations that must point to a particular script). If the name of the script
  is contained in the location path, the value of the name option overrides the
  name retrieved from the location. If the Sieve interpreter explicitly queries
  for a specific name (e.g. to let the Sieve include extension
  [http://tools.ietf.org/html/draft-ietf-sieve-include-05] retrieve a script
  from the 'sieve_global=' location), this option has no effect.

bindir=<dirpath> :
  Points to the directory where the compiled binaries for this script location
  are stored. This directory is created automatically if possible. If this
  option is omitted, the behavior depends on the location type. For 'file' type
  locations, the binary is then stored in the same directory as where the
  script file was found if possible. For `dict' type locations, the binary is
  not stored at all in that case. Don't specify the same directory for
  different script locations, as this will result in undefined behavior.
  Multiple mail users can share a single script directory if the script
  location is the same and all users share the same system credentials (uid,
  gid).

*NOTE*: Pigeonhole versions before v0.3.1 do not support the location syntax
described here. These versions only support bare filesystem paths pointing to
files or directores as script storage location. Also, in that case a few
additional <deprecated settings> [Pigeonhole.Sieve.Configuration.txt] are
needed for configuration.

Basic Configuration
-------------------

To use Sieve, you will first need to make sure you are using Dovecot <LDA.txt>
or <LMTP.txt> for delivering incoming mail to users' mailboxes. Then, you need
to enable the Pigeonhole Sieve plugin in your configuration:

---%<-------------------------------------------------------------------------
protocol lda {
  mail_plugins = $mail_plugins sieve
}
protocol lmtp {
  mail_plugins = $mail_plugins sieve
}
---%<-------------------------------------------------------------------------

The sieve plugin recognizes the following configuration options in the 'plugin'
section of the config file (default values are shown if applicable):

sieve = file:~/sieve;active=~/.dovecot.sieve :
  The location of the user's main Sieve script or script storage. The 
  <LDA.txt> Sieve plugin uses this to find the active script for Sieve
  filtering at delivery. The Sieve include extension
  [http://tools.ietf.org/html/draft-ietf-sieve-include-05] uses this location
  for retrieving ":personal" scripts.

:
  This location is also where the <ManageSieve> [Pigeonhole.ManageSieve.txt]
  service will store the user's scripts, if supported by the location type. For
  the 'file' location type, the location will then be the path to the storage
  directory for all the user's personal Sieve scripts. <ManageSieve>
  [Pigeonhole.ManageSieve.txt] maintains a symbolic link pointing to the
  currently active script (the script executed at delivery). The location of
  this symbolic link can be configured using the ';active=<path>' option.

:
  For Pigeonhole versions before v0.3.1, this setting can only be a filesystem
  path pointing to a script file, or - when <ManageSieve>
  [Pigeonhole.ManageSieve.txt] is used - it is the location of the symbolic
  link pointing to the active script in the storage directory. That storage
  directory is then configured using the deprecated 'sieve_dir' setting.

sieve_default = (v0.3+) :
  The location of the default personal sieve script file which gets executed
  ONLY if user's private Sieve script does not exist,
  e.g.'file:/var/lib/dovecot/default.sieve' (check the <multiscript section>
  [Pigeonhole.Sieve.Configuration.txt] for instructions on running global Sieve
  scripts before and after the user's personal script). This is usually a
  global script, so be sure to pre-compile the specified script manually in
  that case using the 'sievec' command line tool, as explained <here>
  [Pigeonhole.Sieve.Usage.txt]. This setting used to be called
  'sieve_global_path', but that name is now deprecated.

sieve_default_name = (v0.4.8+) :
  The name by which the default Sieve script is visible to <ManageSieve>
  [Pigeonhole.ManageSieve.txt] clients. Normally, it is not visible at all.
  Refer to the <visible default script section>
  [Pigeonhole.Sieve.Configuration.txt] for more information.

sieve_global = :
  Location for :global include scripts for the Sieve include extension
  [http://tools.ietf.org/html/draft-ietf-sieve-include-05]. This setting used
  to be called 'sieve_global_dir', but that name is now deprecated.

sieve_extensions = :
  Which Sieve language extensions are available to users. By default, all
  supported extensions are available, except for deprecated extensions,
  extensions that add the ability to change messages, extensions that require
  explicit configuration or extensions that are still under development. Some
  system administrators may want to disable certain Sieve extensions or enable
  those that are not available by default. All supported extensions are listed
  <here> [Pigeonhole.Sieve.txt]. Normally, all enabled extensions must be
  listed for this setting, but starting with Sieve version 0.1.7, this setting
  can use '+' and '-' to specify differences relative to the default. For
  example 'sieve_extensions = +imapflags' will enable the deprecated imapflags
  extension [http://tools.ietf.org/html/draft-melnikov-sieve-imapflags-03] in
  addition to all extensions enabled by default.

sieve_global_extensions = (v0.3+) :
  Which Sieve language extensions are ONLY avalable in global scripts. This can
  be used to restrict the use of certain Sieve extensions to administrator
  control, for instance when these extensions can cause security concerns. This
  setting has higher precedence than the 'sieve_extensions' setting (above),
  meaning that the extensions enabled with this setting are never available to
  the user's personal script no matter what is specified for the
  'sieve_extensions' setting. The syntax of this setting is similar to the
  'sieve_extensions' setting, with the difference that extensions are enabled
  or disabled for exclusive use in global scripts. Currently, no extensions are
  marked as such by default.

sieve_plugins = :
  The Pigeonhole Sieve interpreter can have plugins of its own. Using this
  setting, the used plugins can be specified. Check the <Sieve plugins page>
  [Pigeonhole.Sieve.Plugins.txt] for available plugins.

sieve_user_log = :
  The path to the file where the user log file is written. If not configured, a
  default location is used. If the main user's personal Sieve (as configured
  with 'sieve=') is a file, the logfile is set to '<filename>.log' by default.
  If it is not a file, the default user log file is '~/.dovecot.sieve.log'.

recipient_delimiter = +:
  The separator that is expected between the :user and :detail address parts 
  introduced by the subaddress extension [http://tools.ietf.org/html/rfc5233/].
  This may also be a sequence of characters (e.g. '--'). The current
  implementation looks for the separator from the left of the localpart and
  uses the first one encountered. The :user part is left of the separator and
  the :detail part is right. This setting is also used by Dovecot's <LMTP.txt>
  service with identical semantics.

sieve_redirect_envelope_from = sender (v0.4.4+):
  Specifies what envelope sender address is used for redirected messages.
  Normally, the Sieve "redirect" command copies the sender address for the
  redirected message from the processed message. So, the redirected message
  appears to originate from the original sender. The following values are
  supported for this setting:
  "sender" :
    The sender address is used (default)

  "recipient" :
    The final recipient address is used

  "orig_recipient" :
    The original recipient is used

  "<user@domain>" :
    Redirected messages are always sent from user@domain. The angle brackets
    are mandatory. The null "<>" address is also supported.

:
  When the envelope sender of the processed message is the null address "<>",
  the envelope sender of the redirected message is also always "<>",
  irrespective of what is configured for this setting.

For example:

---%<-------------------------------------------------------------------------
plugin {
...
   # The location of the user's main script storage. The active script
   # in this storage is used as the main user script executed during
   # delivery. The include extension fetches the :personal scripts
   # from this location. When ManageSieve is used, this is also where
   # scripts are uploaded. This example uses the file system as
   # storage, with all the user's scripts located in the directory
   # `~/sieve' and the active script (symbolic link) located at
   # `~/.dovecot.sieve'.
   sieve = file:~/sieve;active=~/.dovecot.sieve

   # If the user has no personal active script (i.e. if the location
   # indicated in sieve= does not exist or has no active script), use
   # this one:
   sieve_default = /var/lib/dovecot/sieve/default.sieve

   # The include extension fetches the :global scripts from this
   # location.
   sieve_global = /var/lib/dovecot/sieve/global/
}
---%<-------------------------------------------------------------------------

Configurable Limits
-------------------

sieve_max_script_size = 1M :
  The maximum size of a Sieve script. The compiler will refuse to compile any
  script larger than this limit. If set to 0, no limit on the script size is
  enforced.

sieve_max_actions = 32 :
  The maximum number of actions that can be performed during a single script
  execution. If set to 0, no limit on the total number of actions is enforced.

sieve_max_redirects = 4 :
  The maximum number of redirect actions that can be performed during a single
  script execution. The meaning of 0 differs based on your version. For
  versions v0.3.0 and beyond this means that redirect is prohibited. For older
  versions, however, this means that the number of redirects is /unlimited/, so
  be careful.

Extension-specific Configuration
--------------------------------

The following Sieve language extensions have specific configuration
options/needs:

 * <duplicate> [Pigeonhole.Sieve.Extensions.Duplicate.txt]
 * <editheader> [Pigeonhole.Sieve.Extensions.Editheader.txt] (configuration
   required)
 * <include> [Pigeonhole.Sieve.Extensions.Include.txt]
 * <spamtest and virustest> [Pigeonhole.Sieve.Extensions.SpamtestVirustest.txt]
   (configuration required)
 * <vacation and vacation-seconds> [Pigeonhole.Sieve.Extensions.Vacation.txt]

Per-user Sieve script location
------------------------------

By default, the Dovecot Sieve plugin looks for the user's Sieve script file in
the user's home directory ('~/.dovecot.sieve'). This requires that the <home
directory> [VirtualUsers.txt] is set for the user.

If you want to store the script elsewhere, you can override the default using
the 'sieve' setting, which specifies the path to the user's script file. This
can be done in two ways:

 1. Define the 'sieve' setting in the plugin section of 'dovecot.conf'.
 2. Return 'sieve' extra field from <userdb extra fields>
    [UserDatabase.ExtraFields.txt].

For example, to use a Sieve script file named '<username>.sieve' in
'/var/sieve-scripts', use:

---%<-------------------------------------------------------------------------
plugin {
...

 sieve = /var/sieve-scripts/%u.sieve
}
---%<-------------------------------------------------------------------------

You may use templates like %u, as shown in the example. See all <variables>
[Variables.txt].

A relative path (or just a filename) will be interpreted to point under the
user's home directory.

Executing Multiple Scripts Sequentially
---------------------------------------

The Dovecot Sieve plugin allows executing multiple Sieve scripts sequentially.
The extra scripts can be executed before and after the user's private script.
For example, this allows executing global Sieve policies before the user's
script. This is not possible using the 'sieve_default' setting, because that is
only used when the user's private script does not exist. The following settings
in the 'plugin' section of the Dovecot config file control the execution
sequence:

sieve_before = :

sieve_before2 = :

sieve_before3 = (etc..) :
  Location Sieve of scripts that need to be executed before the user's personal
  script. If a 'file' location 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 locations can
  be specified by appending an increasing number to the setting name. The Sieve
  scripts found from these locations 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 = :

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
only executed if an implicit or explicit "keep" is in effect. Thus, to end all
script execution, a script must not execute keep and it must cancel the
implicit keep, e.g. by executing "'discard; stop;'". This means that the
command "'keep;'" has different semantics when used in a sequence of scripts.
For normal Sieve execution, "'keep;'" is equivalent to "'fileinto "INBOX";'",
because both cause the message to be stored in INBOX. However, in sequential
script execution, it only controls whether the next script is executed. Storing
the message into INBOX (the default folder) is not done until the last script
in the sequence executes (implicit) keep. To force storing the message into
INBOX earlier in the sequence, the fileinto command can be used (with "':copy'"
or together with "'keep;'").

Apart from the keep action, all actions triggered in a script in the sequence
are executed before continuing to the next script. This means that when a
script in the sequence encounters an error, actions from earlier executed
scripts are not affected. The sequence is broken however, meaning that the
script execution of the offending script is aborted and no further scripts are
executed. An implicit keep is executed in stead.

Just as for executing a single script the normal way, the Dovecot Sieve plugin
takes care never to duplicate deliveries, forwards or responses. When vacation
actions are executed multiple times in different scripts, the usual error is
not triggered: the subsequent duplicate vacation actions are simply discarded.

For example:

---%<-------------------------------------------------------------------------
plugin {
...
   # 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

   # Domain-level scripts retrieved from LDAP
   sieve_before2 = ldap:/etc/dovecot/sieve-ldap.conf;name=ldap-domain

   # User-specific scripts executed before the user's personal script.
   #   E.g. a vacation script managed through a non-ManageSieve GUI.
   sieve_before3 = /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_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 <here>
[Pigeonhole.Sieve.Usage.txt].

Visible Default Script
----------------------

The 'sieve_default=' setting specifies the location of a default script that is
executed when the user has no active personal script. Normally, this default
script is invisible to the user; i.e., it is not listed in <ManageSieve>
[Pigeonhole.ManageSieve.txt]. To give the user the ability to see and read the
default script, it is possible to make it visible under a specific configurable
name using the 'sieve_default_name' setting. This feature is only supported for
Pigeonhole versions 0.4.8 and higher.

ManageSieve will magically list the default script under that name, even though
it does not actually exist in the user's normal script storage location. This
way, theManageSieve client can see that it exists and it can retrieve its
contents. If no normal script is active, the default is always listed as
active. The user can replace the default with a custom script, by uploading it
under the default script's name. If that custom script is ever deleted, the
default script will reappear from the shadows implicitly.

This way, ManageSieve clients will not need any special handling for this
feature. If the name of the default script is equal to the name the client uses
for the main script, it will initially see and read the default script when the
user account is freshly created. The user can edit the script, and when the
edited script is saved through theManageSieve client, it will will override the
default script. If the user ever wants to revert to the default, the user only
needs to delete the edited script and the default will reappear.

The name by which the default script will be known is configured using the
'sieve_default_name' setting. Of course, the 'sieve_default' setting needs to
point to a valid script location as well for this to work. If the default
script does not exist at the indicated location, it is not shown.

For example:

---%<-------------------------------------------------------------------------
plugin {
...
  sieve = file:~/sieve;active=~/.dovecot.sieve

  sieve_default = /var/lib/dovecot/sieve/default.sieve
  sieve_default_name = roundcube
}
---%<-------------------------------------------------------------------------

Deprecated Settings
-------------------

These settings are deprecated in newer versions, but still recognized:

sieve_global_path = (< v0.2):
  The deprecated name for the 'sieve_default' setting.

sieve_dir = ~/sieve (< v0.3.1):
  Directory for :personal include scripts for the include extension
  [http://tools.ietf.org/html/draft-ietf-sieve-include-05]. The Sieve
  interpreter only recognizes files that end with a '.sieve' extension, so the
  include extension expects a file called 'name.sieve' to exist in the
  'sieve_dir' directory for a script called 'name'. When using <ManageSieve>
  [Pigeonhole.ManageSieve.txt], this is also the directory where scripts are
  uploaded. For recent Pigeonhole versions, this location is configured as part
  of the 'sieve' setting.

sieve_global_dir = (< v0.3.1):
  Directory for :global include scripts for the include extension
  [http://tools.ietf.org/html/draft-ietf-sieve-include-05]. The Sieve
  interpreter only recognizes files that end with a '.sieve' extension, so the
  include extension expects a file called 'name.sieve' to exist in the
  'sieve_global_dir' directory for a script called 'name'. For recent
  Pigeonhole versions, a more generic version of this setting is called
  'sieve_global' and allows locations other than file system directories.

Migration
---------

General Dovecot 2.0 changes
---------------------------

 * Note that the Dovecot v2.0 <LDA.txt> does not create mailfolders
   automatically by default anymore. If your configuration relies on this, you
   need to enable the 'lda_mailbox_autocreate' setting for <LDA.txt> or start
   using the Sieve mailbox extension's ':create' tag for *fileinto* commands.
 * Dovecot v2.0 adds support for <LMTP.txt>. Much like the <Dovecot LDA>
   [LDA.txt], it can make use of the Pigeonhole Sieve plugin. Since the
   <LMTP.txt> service has its own 'prototocol lmtp' section in the config file,
   you need to add the Sieve plugin to the 'mail_plugins' setting there too
   when you decide to use <LMTP.txt>.

From CMUSieve (Dovecot v1.0/v1.1)
---------------------------------

For the most part, migration from CMUSieve to Pigeonhole Sieve is just a matter
of changing the used plugin name from *cmusieve* to *sieve* in the
'mail_plugins' option in the 'protocol lda' section of the config file (as
explained <above> [Pigeonhole.Sieve.Configuration.txt]). However, there are a
few important differences in the supported Sieve language features:

 * The *imapflags* extension is now called *imap4flags*. The CMUSieve
   implementation is based on an old draft specification
   [http://tools.ietf.org/html/draft-melnikov-sieve-imapflags-03] that is not
   completely compatible with the new version
   [http://tools.ietf.org/html/rfc5232/]. Particularly, the *mark* and *unmark*
   commands were removed from the new specification. For backwards
   compatibility, support for the old imapflags extension can be enabled using
   the 'sieve_extensions' setting (as explained <above>
   [Pigeonhole.Sieve.Configuration.txt]). This is disabled by default.
 * The *notify* extension is now called *enotify*. The CMUSieve implementation
   is based on an old draft specification
   [http://tools.ietf.org/html/draft-martin-sieve-notify-01] that is not
   completely compatible with the new version
   [http://tools.ietf.org/html/rfc5435/]. Particularly, the *denotify* command
   and *$text$* substitutions were removed from the new specification. For
   backwards compatibility, support for the old imapflags extension can be
   enabled using the 'sieve_extensions' setting (as explained <above>
   [Pigeonhole.Sieve.Configuration.txt]). This is disabled by default.
 * The include extension [http://tools.ietf.org/html/draft-ietf-sieve-include]
   now requires your script /file/ names to end with ".sieve". This means that
   'include :personal "myscript"' won't work unless your script file is called
   "'myscript.sieve'" on disk. Also note that the "'.sieve'" extension has no
   special meaning within the Sieve script; if you 'include "myscript.sieve"',
   the Sieve interpreter will look for a script file called
   'myscript.sieve.sieve' and not 'myscript.sieve'.
 * Be sure to use *UTF8* for the mailbox argument of the *fileinto* command.
   Older CMUSieve installations used modified UTF7 (as IMAP does) for the
   mailbox parameter. If not adjusted, the Pigeonhole Sieve plugin will use the
   wrong folder name for storing the message.

From Dovecot Sieve v0.1.x (Dovecot v1.2)
----------------------------------------

 * The 'sieve_subaddress_sep' setting for the Sieve subaddress extension
   [http://tools.ietf.org/html/rfc5233/] is now known as 'recipient_delimiter'.
   Although 'sieve_subaddress_sep' is still recognized for backwards
   compatibility, it is recommended to update the setting to the new name,
   since the <LMTP.txt> service also uses the 'recipient_delimiter' setting.

(This file was created from the wiki on 2016-03-16 04:44)
