Go to the first, previous, next, last section, table of contents.


File and database lookups

Exim can be configured to look up data in files or databases in a number of different circumstances. This chapter discusses some of the common features of the data lookup facilities; particular cases are covered in more detail in subsequent chapters.

Two different styles of data lookup are implemented:

The code for each lookup type is in a separate source file which is compiled and included in the binary of Exim only if the corresponding compile-time option is set. The default settings in `src/EDITME' are:


LOOKUP_DBM=yes
LOOKUP_LSEARCH=yes

which means that only linear searching and DBM lookups are included by default.

Single-key lookup types

The following single-key lookup types are implemented:

If `*' is added to a single-key lookup type (for example, `lsearch*'), then if the initial lookup fails, the key `*' is looked up in the file to provide a default value. See also the section on partial matching below.

Alternatively, if `*@' is added to a single-key lookup type (for example `dbm*@') then, if the initial lookup fails and the key contains an @ character, a second lookup is done with everything before the last @ replaced by *. This makes it possible to provide per-domain defaults in alias files that include the domains in the keys. If the second lookup fails, then `*' is looked up.

There has been some confusion about the way `lsearch' lookups work, in particular in a domain or host list. An item in one of these lists may be a plain file name, or a file name preceded by a search type, and these behave differently. For a plain file name, for example


local_domains = /etc/local-mail-domains

each line of the file is treated as if it appeared as an item in the list, and negated items, wild cards, and regular expressions may be present. However, if an item is specified as an `lsearch' lookup, for example


local_domains = lsearch;/etc/local-mail-domains

then negated items, wild cards, and regular expressions may not be used, because `lsearch' is an indexed lookup method which, when given a key (the domain in the above example), yields a data value that corresponds to that key. The fact that the file is searched linearly does not make this kind of search any different from the other single-key lookup types, and an `lsearch' file can always be directly converted into one of the other types. Thus the keys in the file are literal strings and are not interpreted in any way.

Query-style lookup types

The following query-style lookup types are implemented:

Use of data lookups

There are three different types of configuration item in which data lookups can be specified:

  1. Any string that is to be expanded may contain explicit lookup requests. String expansions are described in chapter "String expansions".
  2. Lists of domains and other items can contain lookup requests as a way of avoiding excessively long linear lists. See section "Domain lists" in chapter "The Exim configuration file" for a full description.
  3. Some drivers can be configured directly to look up data in files.

In a string expansion, all the parameters of the lookup are specified explicitly, while for the other types there is always one implicit key involved. For example, the `local_domains' option contains a list of local domains; when it is being searched there is some domain name that is an implicit key.

This is not a problem for single-key lookups; the relevant file name is specified, and the key is implicit. For example, the list of local domains could be given as


local_domains = dbm;/local/domain/list

However, for query-style lookups the entire query has to be specified, and to do this, some means of including the implicit key is required. The special expansion variable `$key' is provided for this purpose. NIS+ could be used to look up local domains by a setting such as


local_domains = nisplus;[domain=$key],domains.org_dir

In cases where drivers can be configured to do lookups, there are always three alternative configuration options: `file' is used for single-key lookups, using an implicit key, and `query' or `queries' is specified for query-style lookups. In these cases the query is an expanded string, and the implicit key that would be used for `file' is always available as one of the normal expansion variables. The difference between `query' and `queries' is that in the latter case the string is treated as a colon-separated list of queries that are tried in order until one succeeds.

Temporary errors in lookups

Lookup functions can return temporary error codes if the lookup cannot be completed. (For example, a NIS or LDAP database might be unavailable.) When this occurs in a transport, director, or router, delivery of the message is deferred, as for any other temporary error. In other circumstances Exim may assume the lookup has failed, or may give up altogether. It is not advisable to use a lookup that might defer for critical options such as (to give an extreme example) `local_domains'.

Partial matching in single-key lookups

The normal operation of a single-key lookup is to search the file for an exact match with the given key. However, in a number of situations where domains are being looked up, it is possible to request partial matching. In this case, information in the file that has a key starting with `*.' matches any domain that ends with the components that follow the fullstop. For example, if a key in a DBM file is


*.dates.fict.book

then this matches `2001.dates.fict.book' and `1984.dates.fict.book' when partial matching is enabled. It also matches `dates.fict.book', if that key does not itself appear as a key in the file.

Partial matching is requested by adding the string `partial-' to the front of the name of a search type, for example, `partial-dbm'. The subject key is first looked up verbatim; if that fails, then `*.' is added at the start and it is looked up again. If that fails, then further lookups are tried with dot-separated components removed from the start, one-by-one, and `*.' added on the front, until there are fewer than two non-* components left. For example, if subject key is `2250.dates.fict.book' then the following keys are looked up:


2250.dates.fict.book
*.2250.dates.fict.book
*.dates.fict.book
*.fict.book

As soon as one key in the sequence is successfully looked up, the lookup finishes.

The minimum number of non-* components can be adjusted by including a number before the hyphen in the search type. For example, `partial3-lsearch' specifies a minimum of three non-* components in the key. If `partial0' is used, the original key gets shortened right down to the null string, and the final lookup is for `*' on its own.

If the search type ends in `*' or `*@', then the search for an ultimate default happens after all partial lookups have failed. If `partial0' is specified, adding `*' to the search type has no effect, because the `*' key is already included in the sequence of partial lookups.

The use of `*' in lookup partial matching differs from its use as a wildcard in domain lists and the like. Partial matching works only in terms of dot-separated components; a key such as `*fict.book' in a database file is useless, because the asterisk in a partial matching subject key is always followed by a dot.

Lookup caching

Exim caches the most recent lookup result on a per-file basis for single-key lookup types, and keeps the relevant files open. In some types of configuration this can lead to many files being kept open for messages with many recipients. To avoid hitting the operating system limit on the number of simultaneously open files, Exim closes the least recently used file when it needs to open more files than its own internal limit, which can be changed via the `lookup_open_max' option. For query-style lookups, a single data cache per lookup type is kept. The files are closed and the caches flushed at strategic points during delivery -- for example, after all directing and routing is complete.

More about NIS+

NIS+ queries consist of a NIS+ indexed name followed by an optional colon and field name. If this is given, the result of a successful query is the contents of the named field; otherwise the result consists of a concatenation of field-name=field-value pairs, separated by spaces. Empty values and values containing spaces are quoted. For example, the query


[name=mg1456],passwd.org_dir

might return the string


name=mg1456 passwd="" uid=999 gid=999 gcos="Martin Guerre"
home=/home/mg1456 shell=/bin/bash shadow=""

(split over two lines here to fit on the page), whereas


[name=mg1456],passwd.org_dir:gcos

would just return


Martin Guerre

with no quotes. A NIS+ lookup fails if NIS+ returns more than one table entry for the given indexed key.

More about LDAP

The include files and libraries needed to compile Exim with LDAP support can be obtained from


`http://www.openldap.org'

This code is a development of the original University of Michigan LDAP implementation. Other LDAP implementations exist; there is one from Netscape, and Solaris 7 contains inbuilt LDAP support. Unfortunately, though these are all compatible at the lookup function level, their error handling is different. For this reason it is necessary to set a compile-time variable when building Exim with LDAP, to indicate which LDAP library is in use. One of the following should appear in your `Local/Makefile':


LDAP_LIB_TYPE=UMICHIGAN
LDAP_LIB_TYPE=NETSCAPE
LDAP_LIB_TYPE=SOLARIS7

If LDAP_LIB_TYPE is not set, Exim uses a heuristic to guess which of the University of Michigan or Netscape libraries is in use. It cannot distinguish the Solaris 7 library.

An LDAP query takes the form of a URL as defined in the Internet Draft `draft-ietf-asid-ldapv3-url-04.txt'. For example, in the configuration of an `aliasfile' director one might have these settings:


search_type = ldap
query = "ldap:///o=University%20of%20Cambridge,c=UK\
         ?mailbox?sub?(cn=$local_part)"

If an LDAP lookup finds an entry with no attributes, it behaves as if the entry did not exist.

The `ldap' lookup type generates an error if more than one entry matches the search filter, whereas `ldapm' permits this case. It is possible for multiple values, separated by newlines, to be returned for both `ldap' and `ldapm', but in the former case you know that whatever values are returned all came from a single entry in the directory.


Go to the first, previous, next, last section, table of contents.