User's guide

1. Features

• Easy to use
• Search for users (typo tolerant)
• Supports all vmailmgr features
• Templates
• Multiple Languages
• TCP/IP and UNIX domain sockets supported
RFC2606 compliant

2. Requirements

PHP >= 4.1.0 is an absolute must, as vmmi relies on the super global variables introduced in 4.1.0. You shouldn't be using a PHP version older than 4.1.1 anyway, due to the *serious* remote buffer overlow vulnerability. vmmi will also work when register_globals is turned on.

3. Screenshots

Login screen, where you can login with example.com or user@example.com.
Overview screen showing all available mailboxes and forwarding addresses.
Search for a user. Notice the wrong spelling.
Adding an account.
Setting an autoresponder. Note that autoresponses only work if you have set up the autoresponder package (VMailMgr HOWTO, Chapter 3.6 Enabling processing of autoresponse). The documentation is not right on how the script should look like, though. The correct script looks like this:
#!/bin/sh
if test -s $MAILDIR/autoresponse/message.txt
then
  qmail-autoresponder message.txt $MAILDIR/autoresponse
fi
I've submitted this already to the mailing list, but it has not yet been fixed in the documentation.
This is how it looks embedded into the control panel at TsunamiHost. I just changed the template colors a bit.

4. Installation

4.1 TCP/IP or Unix Domain sockets?

First download and unpack the archive:

  wget http://daniel.lorch.cc/files/vmmi/vmmi-x.xx.tar.gz
  tar zxf vmmi-x.xx.tar.gz

Open config.php in your favorite editor. You have to tell vmmi whether you are running VMailMgr on TCP/IP or UNIX Domain sockets. By default, vmmi is set up to run on TCP/IP sockets. Verify whether host and port are correct:

  /* uncomment if vmailmgr runs with TCP/IP sockets */

  class my_vmailmgr extends vmailmgr {
    var $tcp_host = "localhost";
    var $tcp_port = 322;
  }

If you are running VMailMgr on Unix Domain sockets instead, you have to comment out the above lines and uncomment the lines with the unix domain sockets:

  /* uncomment if vmailmgr runs with TCP/IP sockets */

  // class my_vmailmgr extends vmailmgr {
  //   var $tcp_host = "localhost";
  //   var $tcp_port = 322;
  // }

  /* uncomment if vmailmgr runs with UNIX domain sockets */

  class my_vmailmgr extends vmailmgr {
    var $unix_socket = "/tmp/.vmailmgrd";
  }

Now scroll down to the bottom and look for the variable $salt:

  $salt = "";

Choose a passphrase and write it between "". This is explained further in 4.2.

4.2 Security Tips - Important!

Read this chapter carefully.

VMailMgr is a daemon that sits in the background and could be accessed by any user on your system. Therefore VMailMgr only accepts commands when it gets a valid user password. vmmi has to store this password somewhere and that's exactly the problem. The user password is stored in a session and PHP sessions are stored by default in /tmp. Although this password is encrypted (see chapter 4.1, passphrase $salt) someone who gains access to these files might crack another user's password. Our goal is to prevent malicious users of getting access to these files.

On most setups PHP is running as module and all scripts are executed as the user under which the webserver runs. Preventing the webserver from being able to read sessions would obviously not be a good solution as it would hinder people from actually using sessions. As you know, PHP session filenames are (intentionally) hard to guess - primarily to prevent session spoofing. It is therefore sufficient to prevent PHP from being able to list the contents of a directory ("r"), while still being able to enter ("x") and create ("w") files in it - if a cracker does not know the filename, how should he be able to get access to it? The optimal permissions for our session directory would therefore be "wx".

We also have to keep someone of changing back these permissions. If our session directory would be owned by the webserver user, these permissions could be easily changed from a PHP script. We therefore let this directory be owned by root and only apply group ownership to the directory.

I chose /var/spool/php_sessions/ to be this directory, but you may also choose another name for it. I don't suggest you to put it in /tmp though, as this directory usually gets wiped on every server restart.

In the following example I am assuming that the UID under which your webserver runs is 'www-data'. Change this otherwise:

  mkdir /var/spool/php_sessions/
  chmod 1733 /var/spool/php_sessions/
  chown root:www-data /var/spool/php_sessions/

You may have noticed the 1 in the chmod command. It applies the "sticky bit" to the directory which ensures that only the user who created a file in this directory is able to delete it. It's not necessary, but can't harm you either. The permissions should now look like this:

  drwx-wx-wt    2 root     www-data     4096 Aug  5 23:45 php_sessions

We have to let PHP know where to store the sessions in future. Open php.ini and search for a directive called 'session.save_path':

  session.save_path = /var/spool/php_sessions/

Restart your webserver to commit these changes ("apachectl graceful" with apache).

5. Customization

5.1 Templates

vmmi allows you to entirely customize its look by creating templates. I suggest you to make a copy of ./templates/default/ and apply modifications to it, though, rather than starting from scratch.

All HTML is stored in template.html and all images/CSS files/flash files have to reside in the same directory. To enable your template, open config.php and look for:

  $template = 'default';

This name corresponds to the directory name you just created. Supposed your template is stored in ./templates/foobar/ your config should look like this:

  $template = 'foobar';

There is some additional information on the template engine on my website, if you're interested. The pages are built up like this:

Login screen

+------------------------+
| header                 |
+------------------------+
| index_header           |
+------------------------+
| index_welcome          |
+------------------------+
| index_language_element |
+------------------------+
| index_login            |
+------------------------+
| index_footer           |
+------------------------+
| footer                 |
+------------------------+

Main screen

+------------------------+
| header                 |
+------------------------+
| main_header            |
+------------------------+
| navigation             |
+------------------------+
| quicksearch            |
+------------------------+
| main_table_start       |
+------------------------+
| main_table_element     |
+------------------------+
| main_table_end         |
+------------------------+
| main_catchall_start    |
+------------------------+
| main_catchall_element  |
+------------------------+
| main_catchall_end      |
+------------------------+
| main_footer            |
+------------------------+
| footer                 |
+------------------------+

Required images: image_edit, image_remove, image_account, image_alias, image_edit, image_remove

Search

+------------------------+
| header                 |
+------------------------+
| main_header            |
+------------------------+
| navigation             |
+------------------------+
| quicksearch            |
+------------------------+
| quicksearch_result     |
+------------------------+
| main_table_start       |
+------------------------+
| main_table_element     |
+------------------------+
| main_table_end         |
+------------------------+
| main_footer            |
+------------------------+
| footer                 |
+------------------------+

Required images: image_edit, image_remove, image_account, image_alias, image_edit, image_remove

Add Account

+------------------------+
| header                 |
+------------------------+
| add_account_header     |
+------------------------+
| navigation             |
+------------------------+
| add_account_form       |
+------------------------+
| add_account_footer     |
+------------------------+
| footer                 |
+------------------------+

Add Alias

+------------------------+
| header                 |
+------------------------+
| add_alias_header       |
+------------------------+
| navigation             |
+------------------------+
| add_alias_form         |
+------------------------+
| add_alias_footer       |
+------------------------+
| footer                 |
+------------------------+

Settings

+------------------------+
| header                 |
+------------------------+
| settings_header        |
+------------------------+
| navigation             |
+------------------------+
| settings_form          |
+------------------------+
| settings_footer        |
+------------------------+
| footer                 |
+------------------------+

User Account

+------------------------+
| header                 |
+------------------------+
| user_account_header    |
+------------------------+
| user_account_form      |
+------------------------+
| user_account_footer    |
+------------------------+
| footer                 |
+------------------------+

User Alias

+------------------------+
| header                 |
+------------------------+
| user_alias_header      |
+------------------------+
| user_alias_form        |
+------------------------+
| user_alias_footer      |
+------------------------+
| footer                 |
+------------------------+

Error

+------------------------+
| header                 |
+------------------------+
| error_header           |
+------------------------+
| error_message          |
+------------------------+
| error_footer           |
+------------------------+
| footer                 |
+------------------------+

Note: All pages have the common header/footer parts, and also their own page_header/page_footer. You can also do a `grep \$parts filename.php` to see what template parts are used in a particular file.

5.2 Language Files

Currently available languages:

Language Contributed by
Deutsch Daniel Lorch
English Daniel Lorch
Français David Rivier
Indonesian Alamsyah Rasyid
Italiano Valerio Felici
Português Fernando Teodoro
Serbian Bojan Suzic
Swedish Fredrik Steen

Language files are stored in ./languages/ using the INI-format. When creating new language files you first have to open ./inc/common.php and look for an array that looks like this:

  $available_languages = array(
    'de' => 'Deutsch',
    'en' => 'English'
  );

This array tells vmmi what languages are available. The array key corresponds to the filename + ".lang". Now before you start working on a translation you might want to ask me whether someone is already working on your language.

Supposed you want to create a japanese translation, first add this language to the array shown above:

  $available_languages = array(
    'de' => 'Deutsch',
    'en' => 'English',
    'jp' => 'Japanese'
  );

And now create a copy of 'en.lang' to 'jp.lang'. The first few lines require some explanation:

  [author]

  name   = Daniel Lorch
  e-mail = daniel@lorch.cc
  web    = http://daniel.lorch.cc/

  [language]

  name     = English
  encoding = iso-8859-1

The author-section is obvious: Enter your contact info for credits. The "encoding" part is the character encoding inserted in the header of every HTML file. Here's a list:

  utf-8 (Unicode, worldwide)
  iso-8859-1 (Western Europe)
  iso-8859-2 (Central Europe)
  iso-8859-3 (Maltese)
  iso-8859-4 (Baltic Rim)
  iso-8859-5 (Cyrillic)
  iso-8859-6-i (Arabic)
  iso-8859-7 (Greek)
  iso-8859-8-i (Hebrew)
  iso-8859-9 (Turkish)
  iso-8859-10 (Latin 6)
  iso-8859-13 (Latin 7)
  iso-8859-14 (Celtic)
  iso-8859-15 (Latin 9)
  us-ascii (basic English)
  euc-jp (Japanese, Unix)
  shift_jis (Japanese, Win/Mac)
  iso-2022-jp (Japanese, email)
  euc-kr (Korean)
  gb2312 (Chinese, simplified)
  big5 (Chinese, traditional)
  tis-620 (Thai)
  koi8-r (Russian)
  koi8-u (Ukrainian)
  macintosh (MacRoman)
  windows-1250 (Central Europe)
  windows-1251 (Cyrillic)
  windows-1252 (Western Europe)
  windows-1253 (Greek)
  windows-1254 (Turkish)
  windows-1255 (Hebrew)
  windows-1256 (Arabic)
  windows-1257 (Baltic Rim)

If you don't know which one to pick just leave it blank and I'll fill it out for you. If you want to share your translation with the community, just send it to me and I'll include it with the vmmi package.

6. Showcase mode

6.1 Introduction

The showcase module imitates the behaviour of the VMailMgr daemon. This is useful for:

• Showcases (demonstration of vmmi)
• Creating templates / writing language files on an environment where no VMailMgr daemon is available

Because the showcase module fakes all functions of VMailMgr there is no need for a daemon and there is absolutely no risk involved, as all changes applied only happen virtually - the users can mess around as much as they like. To enable the showcase module you have to make vm.php point to another file. vm.php is a softlink pointing to the module which should be used:

  cd vm
  ln -sf vm.showcase.php vm.php

If you'd like to go back to the real mode again, just make vm.php point to vm.interface.php, which is the real interface:

  cd vm
  ln -sf vm.interface.php vm.php

The default domain and password is demo.com/demo.

6.2 Customization

Open ./vm/vm.showcase.php in your favorite editor. There is an array called $_SESSION['userlist'] with some demo data (Peter and Linda). This is the initial setting of what people will see when they log in.

To change the domain/password scroll down some lines where it says:

  /* configuration part */
  var $my_domain = 'demo.com';
  var $my_pass   = 'demo';

I also suggest you to modify the HTML template to automatically insert the domain/password so the users don't have to type it in. Open ./templates/default/template.html and go to section 'index_login' and add 'value=' parameters to the text input fields:

  <input type="text" name="form[domain]" class="text" value="demo.com"><br>
  ..
  <input type="password" name="form[password]" class="text" value="demo"><br><br>

by Daniel Lorch 2002