Dovecot Sieve implementation?


I just upgraded my roundcube to 0.3 to find out it has some nice plugins.
So I coded a virtualmin driver for their password plugin, so users can change passwords from within roundcube via the Virtualmin remote API.

Now, I would love to offer mail filtering management from roundcube, as usermin is (let’s face it) pretty awful and no-one uses it.
Roundcube offers a sieve plugin, which is fine, but Virtualmin makes use of Procmail. One of the big advantages of sieve is that it is tightly integrated in dovecot and with managesieve you have a service that allows roundcube in this case to manage filters without needing ftp access or other strange hacks.

So I digged a bit, and found out that basically dovecot (at least on debian lenny) already comes with LDA and Managesieve support, so it would be no problem to implement in the postfix config file (mailbox_command), but then I would loose antivirus/antispam checking, and possibly some other stuff, which Virtualmin implements via procmail.

So my question here: is it possible, maybe by changing something to the Virtualmin procmail template (if there is any) to pass the mail to the dovecot deliver service, isntead of delivering directly to inbox?
So basically procmail would do its stuff, then pass the thing on to dovecot, and dovecot will do its filter stuff and deliver it to the mailbox.
That would be a nice workaround I could definetly live with…

Please let me know :wink:


I suspect you’ve found this already, but even if not for yourself, perhaps others could benefit from the Dovecot LDA page, which details how to use the “deliver” command:

So how would that tie into the tools currently on the system?

I think all you’d have to do is add the appropriate command to the end of the /etc/procmailrc file. With that, spam/virus processing would take place first, after which your email will be handed over to Dovecot’s tools.

Personally, I’d love to see a procmail plugin, but sieve is pretty good at what it does :wink:


Good to know that this is possible.
However, I’m not really good at procmail…
So I looked at it, and i suspec these two lines:
have to disappear in favor of something else? or maybe somethig like ORGMAIL=path/to/deliver -parameters or something?
any clues? :slight_smile:

I’d leave those two lines there in case something goes awry; they aren’t causing anything to be delivered, they’re just telling procmail what the defaults are.

You can tell procmail to pipe an email into a program by using the | character:


You could put something like that at the end of the /etc/procmailrc file.

There’s some additional examples of procmail usage in the procmailex manpage.


thank you very much, i will try to implement all this soon, and hopefully get a nice webmail :slight_smile:

yay, got it working pretty easilly thanks to you andreychek
basically added this at the bottom of /etc/procmailrc

:0 w
| /usr/lib/dovecot/deliver

as also explained on
with the needed config settings in /etc/dovecot.conf i got filters working, and quota as well, using the fs backend :wink:

Hi Hal900,

I got filtering working with managesieve and now i’m trying to found how to make possible for user to change their password.

You said you’ve coded a plugin to work with password plugin in Roundcube, could you please help me to make this possible too ?

Thanks in advance.

that’s how i did it.
i got the password plugin for redmine from their website, then i made following modifications (i assume you are in plugins/password/):

in i set $rcmail_config['password_driver'] = 'virtualmin'; and $rcmail_config['password_confirm_current'] = false;
then i added these new parameters at the bottom of the file:

// Virtualmin Driver options
// -------------------------
// The host which changes the password
$rcmail_config['password_virtualmin_host'] = 'hostname';

// TCP port used for DirectAdmin connections
$rcmail_config['password_virtualmin_port'] = 10000;

// CP admin password
$rcmail_config['password_virtualmin_rpwd'] = 'foo';

IMPORTANT: make sure you chmod your to 0600

now i created the file drivers/virtualmin.php with the following content:


function password_save($curpass, $passwd){

    $rcmail = rcmail::get_instance();

    $da_user    = $_SESSION['username'];
        $da_domain  = explode("_", $da_user);
        $da_domain  = $da_domain[0];
    $da_newpass = $passwd;
    $da_host    = $rcmail->config->get('password_virtualmin_host');
    $da_port    = $rcmail->config->get('password_virtualmin_port');
        $da_rpwd    = $rcmail->config->get('password_virtualmin_rpwd');

        $response = shell_exec("wget -O - --quiet --http-user=root --http-passwd={$da_rpwd} --no-check-certificate 'https://{$da_host}:{$da_port}/virtual-se$

    elseif(!strpos($response, "success"))
        return PASSWORD_ERROR;
        return PASSWORD_SUCCESS;



and of course enabled the password plugin in the roundcube config.
the implementation could be cleaner I guess, and also please note that the virtualmin driver assumes you have usernames in the domain_user style, which is my case. you will need to adapt it for your system, see the explode( part where i get the domain name out of the username.

hope this helps :wink:

UPDATE: dont ask me why this editor screws up the code content, but the “em” tags actually are _ underscores…

nice, cant edit previous comment now… theres a line which is cut off… here the complete one:

$response = shell_exec("wget -O - --quiet --http-user=root --http-passwd={$da_rpwd} --no-check-certificate 'https://{$da_host}:{$da_port}/virtual-server/remote.cgi?program=modify-user&domain={$da_domain}&user={$da_user}&pass={$da_newpass}'");

btw i wonder if a mail user is able to run the command line to change its password. in this case the password setting would not be needed, whereas password_confirm_current should be set to true and the current password then sent to the command line.
this would improve things on security a bit, i will try it later :wink:

To improve security you can create extra-admin with only rights for mail administration…

Hello Hal9000,

I’ve tried to integrate deliver with procmail as you did on a Debian Lenny 5.0 system
(completely installed via virtualmin gpl script), but no success. Managing
sieve filters via roundcube 0.3 does work properly, scripts are created in ~/.dovecot.sieve

But when postfix tries to deliver mail, filtering doesn’t work and in procmail.log I get for every mail:

procmail: Program failure (78) of “/usr/lib/dovecot/deliver”
From Thu Oct 8 16:52:30 2009
Subject: SPAM
Folder: /home/t3yaml/homes/test/Maildir/new/ 400
Time:1255013550 User:test.t3yaml Size:450 Dest:/home/t3yaml/homes/test/Maildir/new/ Mode:None

Last lines of /etc/procmailrc are as advised:

:0 w
| /usr/lib/dovecot/deliver

Could you please post your procmailrc and dovecot.conf (relevant parts) so I could
compare things?

Thanx in advance,

Hello Hal9000,

Can you elaborate on what exactly does it take to pipe the mail from procmail to managesieve for roundcube filters to work on virtualmin?

Putting :0 w | /usr/lib/dovecot/deliver alone doesn’t help much. You mentioned some modifications to dovecot.conf, can you please post here the modifications you made?

Thank you

it’s been a while, so i don’t quite remember what i did, but this is how my procmailrc looks today

VIRTUALMIN=|/etc/webmin/virtual-server/ $LOGNAME
* ?/usr/bin/test "$VIRTUALMIN" != ""
:0 w

please keep in mind that i am running a debian system, so path may differ for other distros.
hope this helps…

I put it just like you did and still no luck.

[root@ns1 ~]# cat /etc/procmailrc
VIRTUALMIN=|/etc/webmin/virtual-server/ $LOGNAME

  • ?/usr/bin/test “$VIRTUALMIN” != “”
    :0 w
    | $DELIVER

You mentioned something about modifications to /etc/dovecot.conf, can you please post relevant parts of it?

mine looks something like this:

[root@ns1 ~]# dovecot -n # 1.2.10: /etc/dovecot.conf # OS: Linux 2.6.18-164.10.1.el5 x86_64 CentOS release 5.4 (Final) protocols: imap imaps pop3 pop3s managesieve login_dir: /var/run/dovecot/login login_executable(default): /usr/libexec/dovecot/imap-login login_executable(imap): /usr/libexec/dovecot/imap-login login_executable(pop3): /usr/libexec/dovecot/pop3-login login_executable(managesieve): /usr/libexec/dovecot/managesieve-login mail_location: maildir:~/Maildir mail_executable(default): /usr/libexec/dovecot/imap mail_executable(imap): /usr/libexec/dovecot/imap mail_executable(pop3): /usr/libexec/dovecot/pop3 mail_executable(managesieve): /usr/libexec/dovecot/managesieve mail_plugin_dir(default): /usr/lib64/dovecot/imap mail_plugin_dir(imap): /usr/lib64/dovecot/imap mail_plugin_dir(pop3): /usr/lib64/dovecot/pop3 mail_plugin_dir(managesieve): /usr/lib64/dovecot/managesieve managesieve_implementation_string(default): dovecot managesieve_implementation_string(imap): dovecot managesieve_implementation_string(pop3): dovecot managesieve_implementation_string(managesieve): Cyrus timsieved v2.2.13 lda: postmaster_address: auth default: passdb: driver: pam userdb: driver: passwd

i have this portion which might be useful, dunno:

protocol managesieve {
  # Login executable location.
  #login_executable = /usr/libexec/dovecot/managesieve-login

  # MANAGESIEVE executable location. See IMAP's mail_executable above for
  # examples how this could be changed.
  #mail_executable = /usr/libexec/dovecot/managesieve

  # Maximum MANAGESIEVE command line length in bytes. This setting is
  # directly borrowed from IMAP. But, since long command lines are very
  # unlikely with MANAGESIEVE, changing this will not be very useful.
  #managesieve_max_line_length = 65536

  # Specifies the location of the symlink pointing to the active script in
  # the sieve storage directory. This must match the SIEVE setting used by
  # deliver (refer to for more
  # info). Variable substitution with % is recognized.

  # This specifies the path to the directory where the uploaded scripts must
  # be stored. In terms of '%' variable substitution it is identical to
  # dovecot's mail_location setting used by the mail protocol daemons.

  # If, for some inobvious reason, the sieve_storage remains unset, the
  # managesieve daemon uses the specification of the mail_location to find out
  # where to store the sieve files (see explaination in README.managesieve).
  # The example below, when uncommented, overrides any global mail_location
  # specification and stores all the scripts in '~/mail/sieve' if sieve_storage
  # is unset. However, you should always use the sieve_storage setting.
  # mail_location = mbox:~/mail

  # To fool managesieve clients that are focused on timesieved you can
  # specify the IMPLEMENTATION capability that the dovecot reports to clients
  # (default: dovecot).
  #managesieve_implementation_string = Cyrus timsieved v2.2.13

## LDA specific settings

protocol lda {
  # Address to use when sending rejection mails.
  postmaster_address = admin@XXXXXX.XXX

  # Hostname to use in various parts of sent mails, eg. in Message-Id.
  # Default is the system's real hostname.
  #hostname =

  # Support for dynamically loadable plugins. mail_plugins is a space separated
  # list of plugins to load.
  mail_plugins = quota
  #mail_plugin_dir = /usr/lib/dovecot/modules/lda

  # Binary to use for sending mails.
  sendmail_path = /usr/sbin/sendmail

  # UNIX socket path to master authentication server to find users.
  #auth_socket_path = /var/run/dovecot/auth-master

  # Enabling Sieve plugin for server-side mail filtering
  mail_plugins = cmusieve

again, paths are for a debian system so might need adjustment

I’m not sure where is the problem but now I see in procmail.log …

procmail: Program failure (75) of “/usr/libexec/dovecot/deliver”

this looks like a permission problem ?

Nevermind, I got it working. Just don’t ask me how grin

Thanks again for the help.

how? restarted dovecot? ghgh…

Nah, restarted dovecot hundreds of times. Trial and error I guess. Can’t tell for sure what exactly did the job right.

I’ll post later the relevant files just in case someone else needs them.

for the future generations: look into the damned log files :wink:

looking into the procmail.log gave me nothing more than you. But enabling logging in the dovecot’s lda protocol gave much info. You need to configure the lda section as follows:

protocol lda { # Address to use when sending rejection mails. postmaster_address =

Enabling Sieve plugin for server-side mail filtering

mail_plugins = sieve

These two settings are crucial for the LDA/sieve to work. Be extra caucious - in the mail_plugins there is a cmusieve present, replace it with sieve.

In the /etc/procmailrc file you need to add (at the bottom is fine):

:0 w

(paths from ubuntu 10.04)

And now it works like a charm!