Technology from the trenches

Setting up Sieve and Vacation Messages on Mac OS X Server

mail.jpg The documentation for setting up sieve on Mac OS X server is sparse, at best:

To enable Sieve support:
1. Add the following entry in /etc/services/:
sieve 2000/tcp #Sieve mail filtering
2. Reload the mail service.

Right. This will enable the service, but it doesn’t configure it. This short article describes how to do both.

1. Create the Sieve Directory

For those without much experience, Apple’s documentation doesn’t mean much, plus its missing some important steps. The first step, which isn’t mentioned, is to create the sieve directory, where the sieve steps are to be located on your filesystem. You’ll be working in the Terminal application for this whole procedure. To create the sieve directory with the appropriate ownership in Leopard, do:

sudo mkdir /usr/sieve
sudo chown _cyrus:mail /usr/sieve

2. Enable the Sieve Service

The next step is to open /etc/services with a text editor — I use ‘vi’, but Apple helps newbies out by shipping the pico text editor with Leopard. To load the services file into pico:

sudo pico /etc/services

Use the arrow keys to scroll down, or, press Control-W, and type in ‘callbook’, followed by enter. There is already a service for port 2000 listed in Leopard’s services file: callbook. I have no idea what callbook is, so I replace it with sieve:

sieve 2000/tcp #Sieve mail filtering
callbook 2000/udp # callbook
#callbook 2000/tcp # callbook

Save your changes by pressing Control-o, and exit with Control-x. Sieve will be enabled as soon as the mail service is restarted. Before you do that though, setup a mail administrator account.

3. Setup a Mail Administrator Account

In order to install sieve scripts for other users, you need a mail administrator account. You should add a special account with a secure password for this task, but you could just add your own user account as a mail administrator. Supposing we have a special account named “mailadmin”, to enable it as a Cyrus mail administrator, open the /etc/imapd.conf file in your text editor, and change the first line:

admins: cyrusimap, mailadmin

Once the admin account is created, make sure that mail is enabled for the account, then send an email to it. The account’s mail box must exist before sieveshell will work with it.

4. Restart the Mail Service

You can restart the mail services by using the Server Admin application, or by running this at the command line:

sudo serveradmin stop mail
sudo serveradmin status mail
... ( it should indicate that the mail service is stopped ) ...
sudo serveradmin start mail
sudo serveradmin status mail
... ( it should now indicate that the mail service is running ) ...

You can tell if the sieve service is running by checking to see if the server is listening on TCP port 2000, by running this command:

netstat -an | grep 2000
tcp4 0 0 *.2000 *.* LISTEN
tcp6 0 0 *.2000 *.* LISTEN

5. Add a Sieve Script

Now all you need to do is add sieve scripts for users. Sieve scripts are text files. To add sieve scripts, you can use the sieveshell command, which is located in the obscure location, /usr/bin/cyrus/sieve/sieveshell. I suggest that you make life easier by symlinking it to your /usr/bin directory:

sudo ln -s /usr/bin/cyrus/sieve/sieveshell /usr/bin/sieveshell

Apple’s Mail Administration manual has several example scripts. The most common is probably a vacation message, so I’ll use that example. Copy and paste the example vacation script into a text file (’pico vacation.msg’):

#--------
# This is a sample script for vacation rules.
# Read the comments following the pound/hash to find out
# what the script is doing.
#---------
#
# Make sure the vacation extension is used.
require "vacation";
# Define the script as a vacation script
vacation
# Send the vacation response to any given sender only once every seven days
no matter how many messages are sent from him.
:days 7
#For every message sent to these addresses
:addresses ["bob@example.com", "robert.fakeuser@server.com"]
# Make a message with the following subject
:subject "Out of Office Reply"
# And make the body of the message the following
"I’m out of the office and will return on December 31. I won’t be able to
replay until 6 months after that. Love, Bob.";
# End of Script

Note that there are two addresses between the brackets on the “:addresses” line. Be sure to put any aliases that you have for your address in a comma-separated list, or they won’t get an automated reply.

Going with the example and supposing that I have a user named “bob”, I would then add this sieve script, which is saved to an arbitrarily-named text file, “vacation.msg”, by running the following on the command line:

sieveshell --user=bob --authname=mailadmin localhost

This will get you into the interactive sieveshell. Type ‘help’ to see available commands. Assuming that your saved sieve script vacation.msg is in the current directory, install it for bob by running:

put vacation.msg

Verify that its there by running list. The last step is to activate the script with the activate command:

activate vacation.msg
list

That’s it. There will now be a directory, /usr/sieve/b/bob that contains bob’s sieve data, and you should get an automatic reply when you send an email to bob@example.com.

Tags: , , , ,

44 Responses to “Setting up Sieve and Vacation Messages on Mac OS X Server”

  1. Baochun Says:

    Interesting — except “enable vacation.msg” should be “activate vacation.msg”.

  2. Brent Says:

    Oops! Thanks — fixed.

  3. Phil Greer Says:

    to get squirrelmail to work with sieve:

    Download the most recent avelsieve distribution from the web page at http://email.uoa.gr/projects/squirrelmail/avelsieve_download.php. I used the more recent Dev Branch version: avelsieve-1.9.6.tar.gz.

    Un-tar this in the squirrelmail plugins directory ( /usr/share/squirrelmail/plugins ), again as root or using sudo via the Terminal and cd into ( avelsieve/config/ ). Copy the example config ‘config_sample.php’ to ‘config.php’ IN THE SAME DIRECTORY. You don’t really need to edit anything in the config.

    Run the SquirrelMail config perl script;
    % sudo /etc/squirrelmail/config/conf.pl

    Choose Option 8, “Plugins” from the menu, and enable “avelsieve” by selecting it from the resultant list. Save your changes and quit the utility.

    Login in to one of the mail accounts using SquirrelMail, and the “Filters” menu should now be an option - choosing this allows you to create your sieve scripts, including a vacation mail ‘auto-reply’.

    Looking in the /usr/sieve/a/admin directory (for example) should show the following files;

    lrwx—— 1 cyrusima wheel 12 Nov 4 11:41 defaultbc -> phpscript.bc
    -rw——- 1 cyrusima wheel 232 Nov 4 11:42 phpscript.bc
    -rw——- 1 cyrusima wheel 1056 Nov 4 11:42 phpscript.script

  4. Gary Says:

    HI, I’m new to this and need some help. I’m following your instructions to the letter, but when I get to the part where I type:

    sieveshell –user=bob –authname=mailadmin localhost

    All I get is the following message:
    unable to connect to server at /usr/bin/sieveshell line 169, line 1.

    What have I done wrong?

  5. Brent Says:

    Hi Gary,

    When you run:

    netstat -an | grep 2000

    Does it say:

    tcp4 0 0 *.2000 *.* LISTEN
    tcp6 0 0 *.2000 *.* LISTEN

    ?

    If so, what happens when you `ping localhost’ ?

  6. Jeff Says:

    I was having he same problem as Gary. The system.log reported “No worthy mechs found”. Guessing this was referring to SASL authentication mechanisms I went into Server Admin and enabled Login and PLAIN authentication for IMAP and SMTP. sieveshell now prompts for a password but does not accept the user password or the mail administrator password. Stuck again.

  7. Brent Says:

    When you run sieveshell, you are not connecting to IMAP. You are connecting to the sieve service. So, when you run ‘netstat’ as per above, do you get the output mentioned above, indicating that the sieve service is actually running?

    If so, is your user or mail administrator username listed on the admin line of /etc/imapd.conf, as per step 3, above?

  8. nick Says:

    will this still work if my mail database is stored on a different hard drive than my leopard server install is on? i have mirrored drives in the xserve that work solely as mail storage.

  9. Brent Says:

    The location of your mail storage has nothing to do with the sieve service.

  10. nick Says:

    many thanks.

  11. John Evans Says:

    This is a great step-by-step. Thanks.
    I ran into the same issue. Any resolution on this?

  12. Brent Says:

    Hi John, what issue did you run into?

  13. Brent Says:

    On 2008-Apr-10, at 11:48 AM, NetMojo Blog wrote:
    Author: Brent
    Comment:
    Hi John, what issue did you run into?

    Hi Brent,

    I followed your directions to the letter and get to the part of logging into the sieveshell and get:


    $ sieveshell --user=johnevans --authname=mailadmin localhost
    connecting to localhost
    Please enter your password:
    unable to connect to server at /usr/bin/sieveshell line 169, line 1.

    The netstat worked, and I even rebooted the machine.

    Any idea?

    John Evans

  14. Brent Says:

    When I run:


    sieveshell –user=userfoo –authname=mailadmin

    And enter the wrong password for user ‘mailadmin’, I get a similar result to yours:


    unable to connect to server at /usr/bin/sieveshell line 169, line 3.

    However, if I enter the correct password for user ‘mailadmin’, it connects successfully. To verify that you are using the correct password, you can use the serversetup utility:


    $ sudo /System/Library/ServerSetup/serversetup -verifyNamePassword shortname password

  15. John Evans Says:

    Double triple checked and the password I’m using is valid.

  16. Brent Says:

    If you used the serversetup utility to verify the password, then the question to ask is why isn’t the sieve service authenticating your user? One way to find out is to watch the /var/log/system.log file when you try to authenticate with sieveshell.

    I tried testing with three scenarios. The first one, I used a fake username (”fakeuser”), and got this in the system.log:


    Apr 14 14:02:13 myserver perl[57674]: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No credentials cache found)
    Apr 14 14:02:22 myserver sieve[57704]: AOD: user opts: get attributes for user: fakeuser failed with error: -14479
    Apr 14 14:02:22 myserver sieve[57704]: badlogin: localhost[::1] SIEVE-PLAIN (-1)
    Apr 14 14:02:24 myserver sieve[57704]: AOD: authentication error: cannot find user: fakeuser (0)
    Apr 14 14:02:24 myserver sieve[57704]: badlogin: localhost[::1] SIEVE-CRAM-MD5 (-4)
    Apr 14 14:02:24 myserver perl[57701]: No worthy mechs found

    The second test, I used a real user (”realuser”), but one that is not listed on the admins: line of /etc/imapd.conf:


    Apr 14 14:11:02 myserver perl[59199]: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No credentials cache found)
    Apr 14 14:11:05 myserver sieve[59200]: illegal authorization attempt: - realuser - is not an admin user
    Apr 14 14:11:10 myserver perl[59199]: No worthy mechs found

    For the third scenario, I use a real user (”realadmin”) that is listed on the admins: line of /etc/imapd.conf, however, I use the wrong password:


    Apr 14 14:16:10 myserver perl[59987]: GSSAPI Error: Unspecified GSS failure. Minor code may provide more information (No credentials cache found)
    Apr 14 14:16:13 myserver /usr/sbin/PasswordService[89]: client response doesn't match what we generated
    Apr 14 14:16:13 myserver sieve[59989]: AOD: crypt authentication error: authentication failed for user: realadmin (-14090)
    Apr 14 14:16:13 myserver sieve[59989]: badlogin: localhost[::1] SIEVE-PLAIN (-6)
    Apr 14 14:16:14 myserver /usr/sbin/PasswordService[89]: client response doesn't match what we generated

    If your output matches one of these three sets of output, then you should know what the problem is. If it is the 3rd one — wrong password — then perhaps the problem is with the password itself. Sieveshell is a perl script, maybe there are some characters that break it, and therefore can’t be used in the password (with this service).

    Cheers,
    Brent

  17. Evan Cunningham Says:

    Hello..

    Sorry.. For whatever reason, when I try running sieveshell, it says command not found. Any ideas?

  18. Brent Says:

    Try step 5: sudo ln -s /usr/bin/cyrus/sieve/sieveshell /usr/bin/sieveshell

  19. Evan Cunningham Says:

    I ran step 5 again, and it says the file exists. I followed the instructions above to a T and when I try and run sieveshell, it still says command not found.

    Do I have to install Sieve? From all the instructions I’ve read so far it seems that Sieve is installed by default, and all you have to do is activate it.

    I’m running Mac OS X Server 10.4.11

  20. Brent Says:

    Then, oddly, /usr/bin is not in your PATH. Run it with the full path:

    /usr/bin/sieveshell

    Brent

  21. Evan Cunningham Says:

    I ran

    /usr/bin/sieveshell

    and it returned with no such file or directory. Is there a way I can reinstall sieveshell?

  22. Evan Cunningham Says:

    It’s also odd.. when I run ls, I can see sieveshell in the bin directory. I’m not much of a terminal guru.. I’ve gotta be missing something simple. I mean it appears to be in the directory. I just can’t figure out why it won’t run.

    thanks for your help by the way!

  23. Brent Says:

    Strange; try /usr/bin/cyrus/sieve/sieveshell

    What does ls -l /usr/bin/cyrus/sieve say? Are you sure that you aren’t making a typing error, like “seive” instead of “sieve”?

  24. Evan Cunningham Says:

    I ran /usr/bin/cyrus/sieve/sieveshell and it returned:

    -bash: /usr/bin/cyrus/sieve/sieveshell: No such file or directory

    Yet when I do a file listing, I can see sieveshell.. heh.. this is usually the kind of luck I have with this stuff.

  25. Evan Cunningham Says:

    running: ls -l /usr/bin/cyrus/sieve

    No such file or directory

  26. Brent Says:

    What about:


    ls -l /bin/sh
    ls -l `which perl`
    ls -l /usr/bin/perl

    Try:

    export PATH=$PATH:/bin:/usr/bin
    sieveshell

  27. Evan Cunningham Says:

    still no luck..

    ls -l /bin/sh
    returns:
    -r-xr-xr-x 1 root wheel 1068844 Apr 10 2007 /bin/sh

    ls -l `which perl`
    returns:
    -rwxr-xr-x 1 root wheel 43444 Jul 1 2006 /usr/bin/perl

    ls -l /usr/bin/perl
    returns:
    -rwxr-xr-x 1 root wheel 43444 Jul 1 2006 /usr/bin/perl

    the export command you gave me doesn’t seem to do anything.. I’m probably entering it incorrectly.

  28. Brent Says:

    Sorry, earlier I meant: ls -l /usr/bin/cyrus/sieveshell

    I’m wondering if it is executable. Try ’sh /usr/bin/cyrus/sieveshell’

    It is unclear whether your shell (bash) is saying that there is no such file named ‘/usr/bin/cyrus/sieveshell’, or whether sieveshell is producing that message by running something. If you look inside sieveshell, you’ll see that it’s a shell script that runs perl:


    #! /bin/sh
    exec perl -x -S $0 ${1+"$@"} # -*-perl-*-
    #!perl -w
    #
    # Copyright (c) 2000 Carnegie Mellon University. All rights reserved.
    #
    ...

    Everything is in your PATH, so what is it that isn’t being found?…

    Can you do:


    perl -we 'print "Perl works!\n";'

    ?

  29. Evan Cunningham Says:

    ls: /usr/bin/cyrus/sieveshell: No such file or directory

    sh /usr/bin/cyrus/sieveshell
    returns:
    ~ admin$ sh /usr/bin/cyrus/sieveshell
    /usr/bin/cyrus/sieveshell: /usr/bin/cyrus/sieveshell: No such file or directory

  30. Evan Cunningham Says:

    perl -we ‘print “Perl works!\n”;’

    Perl works!

  31. Brent Says:

    So what does:

    ls -l /usr/bin/cyrus

    look like?

  32. Evan Cunningham Says:

    starck:~ admin$ ls -l /usr/bin/cyrus/sieveshell
    ls: /usr/bin/cyrus/sieveshell: No such file or directory

  33. Brent Says:

    Update:

    So you may want to do:

    ln -sf /usr/bin/cyrus/test/sieveshell /usr/bin/sieveshell, to replace the broken symlink that you created earlier.

    Cheers,
    Brent

    On May 15, 2008, at 16:03 , Evan Cunningham wrote:

    Okay..

    /usr/bin/cyrus/test/sieveshell

    running the line above seems to have finally launched sieveshell. Thank you so much for your help! I’m not sure why it’s inside a test directory.. I’ll see what I can sort out from here.

    evan

    On 15-May-08, at 2:58 PM, Brent wrote:

    OK, try looking for it this way:

    sudo find /usr -name “sieveshell” -print

  34. HEMOglobina Says:

    Will this work on OS X Server Tiger (10.4.10)?

  35. Brent Says:

    Yes, probably.

  36. HEMOglobina Says:

    I’m trying this on Tiger but I’m having the following output. When I run:


    mainserver:~/Documents localadmin$ sieveshell --user=maria --authname=mailadmin localhost
    connecting to localhost
    dyld: lazy symbol binding failed: Symbol not found: _init_net
    Referenced from: /System/Library/Perl/5.8.6/darwin-thread-multi-2level/auto/Cyrus/SIEVE/managesieve/managesieve.bundle
    Expected in: dynamic lookup
    dyld: Symbol not found: _init_net
    Referenced from: /System/Library/Perl/5.8.6/darwin-thread-multi-2level/auto/Cyrus/SIEVE/managesieve/managesieve.bundle
    Expected in: dynamic lookup
    Trace/BPT trap
    mainserver:~/Documents localadmin$

    My system.log outputs:

    Jul 8 15:57:52 mainserver crashdump[1755]: perl crashed
    Jul 8 15:57:52 mainserver crashdump[1755]: crash report written to: /Users/localadmin/Library/Logs/CrashReporter/perl.crash.log

    The perl.crash.log reads:

    Host Name: mainserver
    Date/Time: 2008-07-08 15:57:52.579 +0000
    OS Version: 10.4.9 (Build 8P2137)
    Report Version: 4
    Command: perl
    Path: /usr/bin/perl
    Parent: bash [1638]
    Version: ??? (???)
    PID: 1754
    Thread: Unknown
    Link (dyld) error:
    Symbol not found: _init_net
    Referenced from: /System/Library/Perl/5.8.6/darwin-thread-multi-2level/auto/Cyrus/SIEVE/managesieve/managesieve.bundle
    Expected in: dynamic lookup

    Any tips on fixing this?
    Thanks a lot for your help and the great article.

  37. Brent Says:

    According to this post:

    http://lists.apple.com/archives/Macos-x-server/2007/Jan/msg00346.html

    It’s an Apple screw-up. They compiled sieve against PPC libraries but not x86 ones. I would follow the advice in the thread: file the bug report with Apple, and wait for a fix.

    Although, that post is from Jan 2007 and it’s still not fixed in July 2008!?! That’s pretty bad.

  38. Thomas Eklund Says:

    Hi Brent,

    I’m having a small problem… When I run :
    /usr/bin/cyrus/sieve/sieveshell –user=myuser –authname=mailadmin localhost
    If I give a wrong password I get this :
    Jul 14 12:38:56 Server105 sieve[78036]: badlogin: localhost[::1] SIEVE-LOGIN (-6)

    If I type the correct password I get the following in syslog :
    Jul 14 12:39:18 Server105 perl[78035]: No worthy mechs found

    And as an error :
    unable to connect to server at /usr/bin/cyrus/sieve/sieveshell line 169, line 2.

    Thanky for your tuto ;)
    Just hope to get it working…

  39. robert jakub Says:

    try creating /usr/sieve

    mkdir /usr/sieve
    chown _cyrus:mail /usr/sieve

    and try again.

    regards,
    rj.

  40. ED Says:

    When I connect to localhost have this.

    Bad Protocol from MANABESIEVE server:EOL2

    THX

  41. ED Says:

    sorry it is MANAGESIEVE

  42. Antialias Says:

    Thanks a lot for this great documentation! I’ve got sieve up and running (with avelsieve as well). The sieve scripts work fine with every account, except for the mailadmin account itself. This account was created as described in section 3 of this documentation. Any advice on this one!

  43. Brent Says:

    I just updated section 3 — the IMAP admin account’s mailbox must exist in IMAP before the sieve scripts work with it.

  44. Antialias Says:

    The mailadmin mailbox does exist. Mail sent to this account (or any of its postfix aliases) slip through the sieve filters and goes directly into the inbox.

Leave a Reply