Roundcube: Vacation message with Virtualmin Plugin

None of the vacation/forwarding plugins work with Virtualmin so this is my workaround. Firstly, users need to be created as Mail and FTP users, since we will be using FTP to place the .forward files. Download and unzip the plugin:

wget http://downloads.sourceforge.net/project/rcubevacation/vacation-1.9.9.zip?use_mirror=ovh&ts=1280145947
unzip vacation-1.9.9.zip
cd vacation
vi config.ini

We are going to use Usermin’s own function (installing the Vacation program doesn’t work) – so change these lines:

binary = "/etc/usermin/forward/autoreply.pl"
alias_identities = false

At this point I usually edit default.txt and change the default text. Now, I have mail usernames in Virtualmin formatted user@domain, so a few changes need to be made to accommodate this:

cd lib
vi dotforward.class.php

We are going to change some lines. Type :set number to see line numbers.
Line 42 change to:
$arrDotForward[] = $this->options['keepcopy'] = "\\".str_replace('@','-',$this->options['username']);
Line 94 change to:
$this->options['keepcopy'] = ($first_element == str_replace('@','-',$this->options['username']));

We need to tell the script the path to the mailbox, so we need to add some code. There’s a gap around line 68 which we can put the following in – note that this is very hacky and will only work with top level domains (not subdomains) where the username is the first part of the domain. If anyone has a better way to do this, do let me know (the virtualmin files containing the home directory paths are in /etc/webmin/virtual-server/domains but are readable by the root user only or we could parse /etc/passwd for the usernames…):

$user_parts = explode('@',$this->options['username']);
$domain_parts = explode('.',$user_parts[1]);
$this->options['flags'] = '/home/'.$domain_parts[0].'/homes/'.$user_parts[0].'/.vacation.msg';

[EDIT – thanks to Iain, the code to get the correct directory from /etc/passwd follows – use this instead of the previous code block:]

$user_accounts = file_get_contents( "/etc/passwd");
$matches = preg_grep( "/" . $this->options['username'] . "/i", explode( "\n",$user_accounts));
$user_info = explode( ":", current($matches));
$this->options['flags'] = $user_info[5] . '/.vacation.msg';

[/EDIT]

Now just add the plugin to the plugins array:

cd ../../../config/
vi main.inc.php

Change the line to:
$rcmail_config['plugins'] = array('vacation');

Update: in Roundcube 0.5 the page layout has changed and the plugin displays incorrectly. To fix this, edit plugins/vacation/skins/default/vacation.css and add in some padding:
#pagecontent {
width: 800px;
padding-top:70px;
}

Tagged , , , , , . Bookmark the permalink.

7 Responses to Roundcube: Vacation message with Virtualmin Plugin

  1. Iain says:

    Thanks for this, it really helped. I created a quick hack to parse the /etc/passwd as I couldn’t get your hack to work reliably on my system as Virtualmin seemed to be inconsistent with creating directories. Anyway, here’s what I put in instead:

    $user_accounts = file_get_contents( "/etc/passwd");
    $matches = preg_grep( "/" . $this->options['username'] . "/i", explode( "\n",$user_accounts));
    $user_info = explode( ":", current($matches));
    $this->options['flags'] = $user_info[5] . '/.vacation.msg';

    That seems to work fine. No error checking but at least it doesn’t make an assumptions about the directory structure.

    Thanks again for the help!

  2. Pierre says:

    Hello,
    I have been trying to make this (not your hack but postfix+roundcube+vacation) work for a few days … and while googling some more, happened to find your post ….
    I am pretty much stuck at the vacation library point … I got the rc plugin to display properly, I use sshftp driver, but no message get ever sent back …
    Your solution sounds like very interesting but … I am already discouraged: I checked in “/etc/usermin/forward/”, no “autoreply.pl” there … just a single “config” file with cryptic info …
    Is autoreply.pl the result of some previous installation ? virtualmin pro (myself using the GPL version) ? any idea ?
    Pierre.

  3. Pierre says:

    Hello
    I finally got this to work … found a binary in /usr/share/usermin/forward/autoreply.pl …
    Next step (but this seems to be above my level of competence) : handle autoreply-tracking (to avoid multiple autoreplies to same person), start and stop date … because all this looks possible with autoreply.pl according to http://www.martin-thierry.nom.fr/dotclear2/post/2012/04/25/Utilisation-de-webmin-postfix-autoreply (in french).
    But how to implement this from the vacation plugin … no idea !
    Thanks anyway for your article !
    Pierre.

  4. cheesefather says:

    Glad you located it, not sure why it wasn’t where mine is! Good luck with the tracking, I’d be interested to hear how it turns out…

  5. jackychen says:

    i follow this config .
    but i still fail…
    this is my config.ini
    ==================
    [default]
    driver = “ftp”
    ; subject = “Default subject”
    subject = “Out of office”
    body = “default.txt”

    [dotforward]
    ; binary = “/usr/bin/vacation”
    binary = “/etc/usermin/forward/autoreply.pl”
    flags = “”
    message = “.vacation.msg”
    database = “.vacation.db”
    ; alias_identities = true
    alias_identities = false
    set_envelop_sender = false
    always_keep_message = true
    =====================

    Error message
    ======================
    CONFIGURATION ERROR

    Vacation plugin: Cannot login to FTP-server ‘wm.xxx.com.tw’ with username: jackychen@xxx.com.tw
    Please read the INSTALL instructions!
    ================================

  6. Thanks for posting this, much appreciated and very helpful.

    However, touching /etc/passwd with PHP from the web server sounds like a terrifying idea. I did some quick research, and in bash you can get a user’s home directory in the variable “~username”, e.g. “echo ~jsmith”. So, it seems like a much safer method to run that command from the shell, rather than file_get_contents(‘/etc/passwd’) and reading that file with all the hased passwords via the web server.

    For example, the following code should work I think (I’ve tested it as a snippet, though not in the context of the plugin):
    $username = escapeshellcmd($this->options['username']);
    $home = shell_exec("echo ~$username");
    $this->options['flags'] = $home . '/.vacation.msg';

    I’d feel much safer running that on my web server than parsing /etc/passwd.

    Hope that helps!

Leave a Reply

Your email address will not be published. Required fields are marked *

*