A. Example: Using smapd with MeTA1

In this appendix we will show how to use the ‘mysql’ module (see section mysql module) to configure local user and alias maps for MeTA1. For this purpose, we will assume that the actual data is stored in two tables in a MySQL database. The two maps will be served by two separate databases, each of which uses a separate configuration file.

To reduce the number of connections to the MySQL server, the MySQL database will be opened at the module level and shared between the two smap databases. Thus, the module initialization in ‘smapd.conf’ looks like:

module mysql mysql config-group=smap

The ‘config-group’ parameter refers to a group name in the default ‘/etc/my.cnf’ file that contains information about the MySQL database and credentials for accessing it. The following is a sample snippet from ‘/etc/my.cnf’:

database   = Mail
user       = smap
password   = guessme
socket     = /tmp/mysql.sock

A.1 Configure local_user_map.

Let's configure ‘local_user_map’ first. User data will be stored in the table ‘userdb’, which has the following structure:

  user varchar(32) NOT NULL default '',
  mailbox text
  PRIMARY KEY (user)

The smap database is defined as follows:

database userdb mysql \
    query="SELECT user FROM userdb WHERE user='$key'"

The ‘defaultdb’ parameter tells it to use the default SQL database opened in the module initialization instruction. The ‘query’ parameter supplies the SQL query to run (the ‘${key}’ variable will be expanded to the value of the actual lookup key, prior to executing the query). Finally, ‘positive-reply’ defines the reply to give if the query returns some tuples. The database only verifies whether the user is present or not, so no additional result is supplied in the reply.

A.2 Configure aliases

We are going to store aliases in the table ‘aliases’ which has the following structure:

  user varchar(32) NOT NULL default '',
  alias text
  PRIMARY KEY (user)

It will be served by ‘alias’ database, defined as follows:

database alias mysql \
    defaultdb \
    query="SELECT alias FROM aliases WHERE user='$key'" \
    positive-reply="OK $alias"

It differs from the ‘userdb’ database only in that it returns a result section with its positive reply.

A.3 Dispatch Rules

The following rules dispatch queries based on their map names to the two databases:

dispatch map alias database aliasdb
dispatch map userdb database userdb

A.4 MeTA1 configuration

Finally we need to inform MeTA1 about new maps. This is done in the file ‘/etc/meta1/meta1.conf’, section ‘smar’.

First, the ‘userdb’ map:

  map password { type = passwd; }
  map userdb {
        type = socket;
        path = "/var/spool/meta1/smap/userdb";
        mapname = userdb;
  map locusr {
        type = sequence;
        maps = { password, userdb };

  local_user_map {
       name = "locusr";
       flags = { localpart, local_domains };

As a result, MeTA1 will look up users in the system database first, and, if that fails, in the SQL database.

Next, the ‘aliasdb’ map:

  map lum {
        type = socket;
        path = "/var/spool/meta1/smap/userdb";
        mapname = aliases;
  map stdal { file = "aliases.db"; type = hash; }
  map aliasmap { type = sequence; maps = { lum, stdal }; }
  aliases {
        name = aliasmap;
        flags = { localpart, local_domains };

As for ‘userdb’, this map declaration also uses two different databases. First, it asks smapd to find the alias. If it returns a negative reply, the map falls back to the default ‘aliases.db’ database.