diff --git a/conf/dovecot_sieve.txt b/conf/sieve-spam.txt similarity index 85% rename from conf/dovecot_sieve.txt rename to conf/sieve-spam.txt index 5428adb..6f364fe 100644 --- a/conf/dovecot_sieve.txt +++ b/conf/sieve-spam.txt @@ -1,7 +1,7 @@ require ["regex", "fileinto", "imap4flags"]; if allof (header :regex "X-Spam-Status" "^Yes") { - setflag "\\\\Seen"; + setflag "\\Seen"; fileinto "Spam"; stop; } diff --git a/management/mailconfig.py b/management/mailconfig.py index d21069a..653b98f 100755 --- a/management/mailconfig.py +++ b/management/mailconfig.py @@ -84,16 +84,6 @@ def add_mail_user(email, pw, env): if "INBOX" not in existing_mboxes: utils.shell('check_call', ["doveadm", "mailbox", "create", "-u", email, "-s", "INBOX"]) if "Spam" not in existing_mboxes: utils.shell('check_call', ["doveadm", "mailbox", "create", "-u", email, "-s", "Spam"]) - # Create the user's sieve script to move spam into the Spam folder, and make it owned by mail. - maildirstat = os.stat(env["STORAGE_ROOT"] + "/mail/mailboxes") - (em_user, em_domain) = email.split("@", 1) - user_mail_dir = env["STORAGE_ROOT"] + ("/mail/mailboxes/%s/%s" % (em_domain, em_user)) - if not os.path.exists(user_mail_dir): - os.makedirs(user_mail_dir) - os.chown(user_mail_dir, maildirstat.st_uid, maildirstat.st_gid) - shutil.copyfile(utils.CONF_DIR + "/dovecot_sieve.txt", user_mail_dir + "/.dovecot.sieve") - os.chown(user_mail_dir + "/.dovecot.sieve", maildirstat.st_uid, maildirstat.st_gid) - # Update things in case any new domains are added. return kick(env, "mail user added") @@ -222,3 +212,4 @@ if __name__ == "__main__": if len(sys.argv) > 1 and sys.argv[1] == "update": from utils import load_environment print(kick(load_environment())) + diff --git a/setup/mail-dovecot.sh b/setup/mail-dovecot.sh index 00403fc..003a20b 100755 --- a/setup/mail-dovecot.sh +++ b/setup/mail-dovecot.sh @@ -20,7 +20,8 @@ source /etc/mailinabox.conf # load global vars # Install packages. apt_install \ - dovecot-core dovecot-imapd dovecot-lmtpd dovecot-sqlite sqlite3 dovecot-sieve + dovecot-core dovecot-imapd dovecot-lmtpd dovecot-sqlite sqlite3 \ + dovecot-sieve dovecot-managesieved # The dovecot-imapd dovecot-lmtpd packages automatically enable IMAP and LMTP protocols. @@ -86,18 +87,35 @@ tools/editconf.py /etc/dovecot/conf.d/15-lda.conf \ # SIEVE -# Enable the Dovecot sieve plugin which let's us set a script that automatically moves -# spam into the user's Spam mail filter. (Note: Be careful if we want to use multiple -# plugins later.) -# -# The actual sieve script is copied into user mailboxes at the time the user account -# is created. Our script moves spam into the user's Spam folder. +# Enable the Dovecot sieve plugin which let's users run scripts that process +# mail as it comes in. We'll also set a global script that moves mail marked +# as spam by Spamassassin into the user's Spam folder. sudo sed -i "s/#mail_plugins = .*/mail_plugins = \$mail_plugins sieve/" /etc/dovecot/conf.d/20-lmtp.conf -# PERMISSIONS +cat > /etc/dovecot/conf.d/99-local-sieve.conf << EOF; +plugin { + # The path to our global sieve which handles moving spam to the Spam folder. + sieve_before = /etc/dovecot/sieve-spam.sieve -# Make the place for mailboxes. -mkdir -p $STORAGE_ROOT/mail + # The path to the user's main active script. ManageSieve will create a symbolic + # link here to the actual sieve script. It should not be in the mailbox directory + # (because then it might appear as a folder) and it should not be in the sieve_dir + # (because then I suppose it might appear to the user as one of their scripts). + sieve = $STORAGE_ROOT/mail/sieve/%d/%n.sieve + + # Directory for :personal include scripts for the include extension. This + # is also where the ManageSieve service stores the user's scripts. + sieve_dir = $STORAGE_ROOT/mail/sieve/%d/%n +} +EOF + +# Copy the global sieve script into where we've told Dovecot to look for it. Then +# compile it. Global scripts must be compiled now because Dovecot won't have +# permission later. +cp `pwd`/conf/sieve-spam.txt /etc/dovecot/sieve-spam.sieve +sievec /etc/dovecot/sieve-spam.sieve + +# PERMISSIONS # Ensure configuration files are owned by dovecot and not world readable. chown -R mail:dovecot /etc/dovecot @@ -107,6 +125,10 @@ chmod -R o-rwx /etc/dovecot mkdir -p $STORAGE_ROOT/mail/mailboxes chown -R mail.mail $STORAGE_ROOT/mail/mailboxes +# Same for the sieve scripts. +mkdir -p $STORAGE_ROOT/mail/sieve +chown -R mail.mail $STORAGE_ROOT/mail/sieve + # Allow the IMAP port in the firewall. ufw_allow imaps diff --git a/setup/migrate.py b/setup/migrate.py index 86788ff..9256634 100755 --- a/setup/migrate.py +++ b/setup/migrate.py @@ -36,6 +36,15 @@ def migration_1(env): except: pass +def migration_2(env): + # Delete the .dovecot_sieve script everywhere. This was formerly a copy of our spam -> Spam + # script. We now install it as a global script, and we use managesieve, so the old file is + # irrelevant. Also delete the compiled binary form. + for fn in glob.glob(os.path.join(env["STORAGE_ROOT"], 'mail/mailboxes/*/*/.dovecot.sieve')): + os.unlink(fn) + for fn in glob.glob(os.path.join(env["STORAGE_ROOT"], 'mail/mailboxes/*/*/.dovecot.svbin')): + os.unlink(fn) + def get_current_migration(): ver = 0 while True: diff --git a/setup/webmail.sh b/setup/webmail.sh index 2b20262..95b6c83 100755 --- a/setup/webmail.sh +++ b/setup/webmail.sh @@ -62,7 +62,7 @@ cat - > /usr/local/lib/roundcubemail/config/config.inc.php <