Dovecot Dictionaries¶
Dovecot’s lib-dict can be used to access simple key-value databases. This is used by, for example, Quota Backend: dict, Key-value authentication (dict) database, Last Login Plugin, and IMAP METADATA. The dictionaries can be accessed either directly by the mail processes or they can be accessed via Dictionary Proxy Process processes.
Currently supported dict backends are:
Name |
Description |
---|---|
Flat Files |
|
FS (lib-fs wrapper) |
|
LDAP (read only) |
|
Memcached (ASCII protocol) |
|
Memcached (Binary protocol) |
|
Proxy |
|
Redis |
|
SQL |
New in version v2.3.17.
Starting version 2.3.17, the dict server process keeps the last 10 idle dict backends cached for maximum of 30 seconds. Practically this acts as a connection pool for dict-redis, dict-memcached and dict-ldap. Note that this doesn’t affect dict-sql, because it already had its own internal cache.
Flat Files¶
file:<path>
The file will simply contain all the keys that are used. Not very efficient for large databases, but good for small ones such as a single user’s quota.
Filesystem (lib-fs wrapper)¶
New in version v2.2.11.
fs:<driver>:<driver args>
This is a wrapper for lib-fs, which most importantly has the posix
backend. So using:
fs:posix:prefix=/var/lib/dovecot/dict/
Would create a separate file under /var/lib/dovecot/dict
for each key.
LDAP¶
New in version v2.2.24.
LDAP support is very similar to SQL support, but there is no write support.
See LDAP.
Configuration¶
dict {
somedict = ldap:/path/to/dovecot-ldap-dict.conf.ext
}
Parameters in .ext file:
Parameter |
Required |
Description |
---|---|---|
|
YES |
LDAP connection URI as expected by OpenLDAP. |
|
NO |
DN or upn to use for binding. (default: none) |
|
NO |
Enable debug. |
|
NO |
Password to use, only SIMPLE auth is supported at the moment. (default: none) |
|
NO |
How long to wait for reply, in seconds. (default: 30 seconds) |
|
NO |
Use TLS?
|
Configuration Examples¶
To map a key to a search:
map {
pattern = priv/test/mail
filter = (mail=*) # the () is required
base_dn = ou=container,dc=domain
username_attribute = uid # default is cn
value_attribute = mail
}
To do a more complex search:
map {
pattern = priv/test/mail/$location
filter = (&(mail=*)(location=%{location}) # the () is required
base_dn = ou=container,dc=domain
username_attribute = uid # default is cn
value_attribute = mail
fields {
location=$location
}
}
Memcached (ASCII Protocol)¶
Note
Memcached dict support is considered deprecated and will be removed in the future. Users are advised to upgrade to Redis.
New in version v2.2.9.
This driver uses the “legacy” Memcache ASCII protocol.
https://github.com/memcached/memcached/blob/master/doc/protocol.txt
memcached_ascii:param=value:param2=value2:...
Supported parameters are:
Parameter |
Required |
Description |
---|---|---|
|
NO |
Memcached server host (default:
|
|
NO |
Memcached server port (default: |
|
NO |
Prefix to add to all keys (default: none) |
|
NO |
Abort lookups after specified number of
milliseconds (default: |
Memcached (Binary Protocol)¶
Note
Memcached dict support is considered deprecated and will be removed in the future. Users are advised to upgrade to Redis.
New in version v2.2.9.
This driver uses the “new” Memcache binary protocol.
See: https://code.google.com/p/memcached/wiki/MemcacheBinaryProtocol
memcached:param=value:param2=value2:...
Supported parameters are:
Parameter |
Required |
Description |
---|---|---|
|
NO |
Memcached server host (default:
|
|
NO |
Memcached server port (default: |
|
NO |
Prefix to add to all keys (default: none) |
|
NO |
Abort lookups after specified number of
milliseconds (default: |
Proxy¶
proxy:[<dict path>]:<destination dict>
Proxying is used to perform all dictionary accessing via the dict processes. (The dict processes exist only if dict proxying is used.) This is especially useful with backends where their initialization is relatively expensive, such as SQL. The dict processes will perform connection pooling.
If <dict path>
is specified, it points to the socket where the dict server
is answering. The default is to use $base_dir/dict
. Usually this is
changed to dict-async
if the dict backend support asynchronous lookups
(e.g. ldap, pgsql, cassandra). The dict-async service allows more than one
client, so this configuration prevents creating unnecessarily many dict
processes.
The <destination dict>
contains the dict name in the dict { .. }
settings. For example: proxy:dict-async:quota
.
See Dictionary Proxy Process for more information about the dict server.
Redis¶
New in version v2.2.9.
redis:param=value:param2=value2:...
Supported parameters are:
Parameter |
Required |
Description |
---|---|---|
|
NO |
Database number (default: |
|
NO |
Expiration value for all keys (in seconds) (default: no expiration) |
|
NO |
Redis server host (default: |
|
NO |
Redis server port (default: |
|
NO |
Prefix to add to all keys (default: none) |
|
NO |
Abort lookups after specified number of
milliseconds (default: |
SQL¶
<sql driver>:<path to dict-sql config>
The <sql driver>
component contains the SQL driver name, such as
mysql
, pgsql
, sqlite
, or cassandra
.
The dict-sql config file consists of SQL server configuration and mapping of keys to SQL tables/fields.
See SQL.
SQL Connect String¶
connect = host=localhost dbname=mails user=sqluser password=sqlpass
The connect setting is exactly the same as used for SQL Authentication.
SQL Mapping¶
SQL mapping is done with a dict key pattern and fields. When a dict lookup or update is done, Dovecot goes through all the maps and uses the first one whose pattern matches the dict key.
For example when using dict for a per-user quota value the map looks like:
map {
pattern = priv/quota/storage
table = quota
username_field = username
value_field = quota_bytes
}
The dict key must match exactly
priv/quota/storage
. The dict keys are hardcoded in the Dovecot code, so depending on what functionality you’re configuring you need to know the available dict keys used it.This is a private dict key (
priv/
prefix), which means that there must be a username_field. Theusername_field
is assumed to be (at least part of) the primary key. In this example we don’t have any other primary keys.With MySQL the above map translates to SQL queries:
SELECT quota_bytes FROM quota WHERE username = '$username_field'
INSERT INTO quota (username, quota_bytes) VALUES ('$username_field', '$value') ON DUPLICATE KEY UPDATE quota_bytes='$value'
You can also access multiple SQL fields. For example
acl_shared_dict
can contain:
map {
pattern = shared/shared-boxes/user/$to/$from
table = user_shares
value_field = dummy
fields {
from_user = $from
to_user = $to
}
}
The
acl_shared_dict
always uses1
as the value, so here thevalue_field
is calleddummy
.The SQL
from_user
andto_user
fields are the interesting ones. Typically the extra fields would be part of the primary key.With MySQL the above map translates to SQL queries:
SELECT dummy FROM user_shares WHERE from_user = '$from' AND to_user = '$to'
INSERT INTO user_shares (from_user, to_user, dummy) VALUES ('$from', '$to', '$value') ON DUPLICATE KEY UPDATE dummy='$value'