Exim 4.10 Specification chapter 14

Previous Next Contents (Exim 4.10 Specification)

# 14. Generic options for routers

This chapter describes the generic options that apply to all routers. For a general description of how a router operates, see sections 3.8 and 3.9.

### address_data

Type: string, expanded
Default: unset

The string is expanded just before the router is run, that is, after all the pre-condition tests have succeeded. If the expansion is forced to fail, the router declines. Other expansion failures cause delivery of the address to be deferred.

When the expansion succeeds, the value is retained with the address, and can be accessed using the variable `$address_data` in the current router, subsequent routers, and the eventual transport. Even if the router declines or passes, the value remains with the address, though it can be changed by another `address_data` setting on a subsequent router. If a router generates child addresses, the value of `$address_data` propagates to them. This also applies to the special kind of ``child'' that is generated by a router with the `unseen` option).

The idea of `address_data` is that you can use it to look up a lot of data for the address once, and then pick out parts of the data later. For example, you could use a single LDAP lookup to return a string of the form

      uid=1234 gid=5678 mailbox=/mail/xyz forward=/home/xyz/.forward

In the transport you could pick out the mailbox by a setting such as

      file = ${extract{mailbox}{$address_data}}

This makes the configuration file less messy, and also reduces the number of lookups. (Exim does cache the most recent lookup, but there may be several addresses in a message which cause lookups to occur.)

The `address_data` facility is also useful as a means of passing information from one router to another.

### caseful_local_part

Type: boolean
Default: false

By default, routers handle the local parts of addresses in a case-insensitive manner, though the actual case is preserved for transmission with the message. If you want the case of letters to be significant in a router, you must set this option true. For individual router options that contain address or local part lists (for example, `local_parts`), case-sensitive matching can be turned on by ``+caseful'' as a list item. See section 10.13 for more details.

### check_local_user

Type: boolean
Default: false

When this option is true, Exim checks that the local part of the recipient address (with affixes removed if relevant) is the name of an account on the local system. The check is done by calling the getpwnam() function rather than trying to read /etc/passwd directly. This means that other methods of holding password data (such as NIS) are supported. If the local part is a local user, `$home` is set from the password data, and can be tested in other pre-conditions that are evaluated after this one (see section 3.9). If the local part is not a local user, the router is skipped.

### condition

Type: string, expanded
Default: unset

This option specifies a general pre-condition test that has to succeed for the router to be called. The string is expanded, and if the result is a forced failure or an empty string or one of the strings ``0'' or ``no'' or ``false'' (checked without regard to the case of the letters), the router is skipped, and the address is offered to the next one. This provides a means of applying special-purpose conditions to the running of routers.

If the expansion fails (other than forced failure) delivery is deferred. Some of the other options below are common special cases that could in fact be specified using `condition`.

### debug_print

Type: string, expanded
Default: unset

If this option is set and debugging is enabled (see the -d command line option), the string is expanded and included in the debugging output. This is to help with checking out the values of variables and so on when debugging router configurations. For example, if a `condition` option appears not to be working, `debug_print` can be used to output the variables it references. The output happens after checks for `domains`, `local_parts`, and `check_local_user` but before any other pre-conditions are tested. A newline is added to the text if it does not end with one.

### domains

Type: domain list, expanded
Default: unset

If this option is set, the router is skipped unless the current domain matches the list. If the match is achieved by means of a file lookup, the data that the lookup returned for the domain is placed in `$domain_data` for use in string expansions of the driver's private options.

### driver

Type: string
Default: unset

This option must always be set. It specifies which of the available routers is to be used.

### errors_to

Type: string, expanded
Default: unset

If the router successfully handles an address, it may queue it for delivery or it may generate child addresses. In both cases, if there is a delivery problem during later processing, the resulting bounce message is sent to the address that results from expanding this string, provided that the address verifies successfully. If the option is unset, or fails to verify, the errors address associated with the incoming address is used. At top level, this is the envelope sender.

If an address for which `errors_to` has been set ends up being delivered over SMTP, the envelope sender for that delivery is the `errors_to` value, so that any bounces that are generated by other MTAs on the delivery route are also sent there. The most common use of `errors_to` is probably to direct mailing list bounces to the manager of the list, as described in section 41.2.

The `errors_to` setting associated with an address can be overridden if it subsequently passes through other routers which have their own `errors_to` settings.

### expn

Type: boolean
Default: true

If this option is turned off, the router is skipped when testing an address as a result of processing an SMTP EXPN command. You might, for example, want to turn it off on a router for users' .forward files, while leaving it on for the system alias file. The use of the SMTP EXPN command is controlled by an ACL (see chapter 37). When Exim is running an EXPN command, it is similar to testing an address with -bt. Compare VRFY, whose counterpart is -bv.

### fail_verify

Type: boolean
Default: false

Setting this option has the effect of setting both `fail_verify_sender` and `fail_verify_recipient` to the same value.

### fail_verify_recipient

Type: boolean
Default: false

If this option is true and an address is accepted by this router when verifying a recipient, verification fails.

### fail_verify_sender

Type: boolean
Default: false

If this option is true and an address is accepted by this router when verifying a sender, verification fails.

### fallback_hosts

Type: string list
Default: unset

String expansion is not applied to this option. The argument must be a colon-separated list of host names or IP addresses. If a router queues an address for a remote transport, this host list is associated with the address, and used instead of the transport's fallback host list. If `hosts_randomize` is set on the transport, the order of the list is randomized for each use. See the `fallback_hosts` option of the smtp transport for further details.

### group

Type: string
Default: see below

When a router queues an address for a transport, and the transport does not specify a group, the group given here is used when running the delivery process. The default is unset, but if `check_local_user` is set, the default is taken from the password information. See also `initgroups` and `user` and the discussion in chapter 22.

### headers_add

Type: string, expanded
Default: unset

This option specifies a string of text which is expanded at routing time, and associated with any addresses that are processed by the router. If the expanded string is empty, or if the expansion is forced to fail, the option has no effect. Other expansion failures are treated as configuration errors.

The expanded string must be in the form of one or more RFC 2822 header lines, separated by newlines (coded as ``\n''). For example:

      headers_add = X-added-header: added by $primary_hostname\n\
                    X-added-second: another added header line

Exim does not check the syntax of these added header lines, except that a newline is supplied at the end if one is not present. If an address passes through several routers as a result of aliasing or forwarding operations, any `headers_add` or `headers_remove` specifications are cumulative. This does not apply for multiple routers that result from the use of ``unseen''.

At transport time, all the original headers listed in `headers_remove` are removed. If there are multiple instances of any listed header, they are all removed. Then the new headers specified by `headers_add` are added, in the order in which they were attached to the address. Finally, any additional headers specified by the transport are added. It is not possible to remove headers added to an address by `headers_add`.

Because the addition does not happen until transport time, header lines that are added by `headers_add` are not accessible by means of the `$header_xxx` expansion syntax. Conversely, header lines that are removed by `headers_remove` remain visible.

Addresses with different `headers_add` or `headers_remove` settings cannot be delivered together in a batch. The `headers_add` option cannot be used for a redirect router that has the `one_time` option set.

### headers_remove

Type: string, expanded
Default: unset

The string is expanded at routing time and is then associated with any addresses that are processed by the router. If the expansion is forced to fail, the option has no effect. Other expansion failures are treated as configuration errors. After expansion, the string must consist of a colon-separated list of header names, not including the terminating colon, for example:

      headers_remove = return-receipt-to:acknowledge-to

It is used at transport time as described under `headers_add` above. The `headers_remove` option cannot be used for a redirect router that has the `one_time` option set.

### ignore_target_hosts

Type: host list, expanded
Default: unset

Although this option is a host list, it should normally contain IP address entries rather than names. If any host that is looked up by the router has an IP address that matches an item in this list, Exim behaves as if that IP address did not exist. This option allows you to cope with rogue DNS entries like

      remote.domain.example  A  127.0.0.1

by setting

      ignore_target_hosts = 127.0.0.1

on the relevant router. An attempt to mail to such a domain then provokes the ``unrouteable domain'' error, and an attempt to verify an address in the domain fails. This option may also be useful for ignoring link-local and site-local IPv6 addresses. Because, like all host lists, the value of `ignore_target_hosts` is expanded before use as a list, it is possible to make it dependent on the domain that is being routed.

### initgroups

Type: boolean
Default: false

If the router queues an address for a transport, and this option is true, and the uid supplied by the router is not overridden by the transport, the initgroups() function is called when running the transport to ensure that any additional groups associated with the uid are set up. See also `group` and `user` and the discussion in chapter 22.

### local_part_prefix

Type: string list
Default: unset

If this option is set, the router is skipped unless the local part starts with one of the given strings, or `local_part_prefix_optional` is true. The list is scanned from left to right, and the first prefix that matches is used. A limited form of wildcard is available; if the prefix begins with an asterisk, it matches the longest possible sequence of arbitrary characters at the start of the local part. An asterisk should therefore always be followed by some character that does not occur in normal local parts. Wildcarding can be used to set up multiple user mailboxes, as described in section 41.7.

During the testing of the `local_parts` option, and while the router is running, the prefix is removed from the local part, and is available in the expansion variable `$local_part_prefix`. If the router accepts the address, this remains true during subsequent delivery.

The prefix facility is commonly used to handle local parts of the form `owner-something`. Another common use is to support local parts of the form `real-username` to bypass a user's .forward file - helpful when trying to tell a user their forwarding is broken - by placing a router like this one immediately before the router that handles .forward files:

      real_localuser:
        driver = accept
        local_part_prefix = real-
        check_local_user
        transport = local_delivery

If both `local_part_prefix` and `local_part_suffix` are set for a router, both conditions must be met if not optional. Care must be taken if wildcards are used in both a prefix and a suffix on the same router. Different separator characters must be used to avoid ambiguity.

### local_part_prefix_optional

Type: boolean
Default: false

See `local_part_prefix` above.

### local_part_suffix

Type: string list
Default: unset

This option operates in the same way as `local_part_prefix`, except that the local part must end (rather than start) with the given string, the `local_part_suffix_optional` option determines whether the suffix is mandatory, and the wildcard * character, if present, must be the last character of the suffix. This option facility is commonly used to handle local parts of the form `something-request` and multiple user mailboxes of the form `username-foo`.

### local_part_suffix_optional

Type: boolean
Default: false

See `local_part_suffix` above.

### local_parts

Type: local part list, expanded
Default: unset

The router is run only if the local part of the address matches the list. See section 10.14 for a discussion of local part lists. Because the string is expanded, it is possible to make it depend on the domain, for example:

      local_parts = dbm;/usr/local/specials/$domain

If the match is achieved by a lookup, the data that the lookup returned for the local part is placed in the variable `$local_part_data` for use in expansions of the router's private options. You might use this option, for example, if you have a large number of local virtual domains, and you want to send all postmaster mail to the same place without having to set up an alias in each virtual domain:

      postmaster:
        driver = redirect
        local_parts = postmaster
        data = postmaster@real.domain.example

### log_as_local

Type: boolean
Default: see below

Exim has two logging styles for delivery, the idea being to make local deliveries stand out more visibly from remote ones. In the ``local'' style, the recipient address is given just as the local part, without a domain. The use of this style is controlled by this option. It defaults to true for the accept router, and false for all the others.

### more

Type: boolean
Default: true

If this option is set false, and the router is run, but declines to handle the address, no further routers are tried, routing fails, and the address is bounced. However, if the router explicitly passes an address to the following router by means of the setting

      self = pass

or otherwise, the setting of `more` is ignored. Also, the setting of `more` does not affect the behaviour if one of the pre-condition tests fails. In that case, the address is always passed to the next router.

### pass_on_timeout

Type: boolean
Default: false

If a router times out during a host lookup, it normally causes deferral of the address. If `pass_on_timeout` is set, the address is passed on to the next router, overriding `no_more`. This may be helpful for systems that are intermittently connected to the Internet, or those that want to pass to a smart host any messages that cannot immediately be delivered.

There are occasional other temporary errors that can occur while doing DNS lookups. They are treated in the same way as a timeout, and this option applies to all of them.

### pass_router

Type: string
Default: unset

When a router returns ``pass'', the address is normally handed on to the next router in sequence. This can be changed by setting `pass_router` to the name of another router. However (unlike `redirect_router`) the named router must be below the current router, to avoid loops. Note that this option applies only to the special case of ``pass''. It does not apply when a router returns ``decline''.

### redirect_router

Type: string
Default: unset

Sometimes an administrator knows that it is pointless to reprocess addresses generated from alias or forward files with the same router again. For example, if an alias file translates real names into login ids there is no point searching the alias file a second time, especially if it is a large file.

The `redirect_router` option can be set to the name of any router instance. It causes the routing of any generated addresses to start at the named router instead of at the first router. This option has no effect if the router in which it is set does not generate new addresses.

### require_files

Type: string list, expanded
Default: unset

This option provides a general mechanism for predicating the running of a router on the existence or non-existence of certain files or directories. Before running a router, as one of its pre-condition tests, Exim works its way through the `require_files` list, expanding each item separately.

Because the list is split before expansion, any colons in expansion items must be doubled, or the facility for using a different list separator must be used. If any expansion is forced to fail, the item is ignored. Other expansion failures cause routing of the address to be deferred.

If any expanded string is empty, it is ignored. Otherwise, except as described below, each string must be a fully qualified file path, optionally preceded by ``!''. The paths are passed to the stat() function to test for the existence of the files or directories. The router is skipped if any paths not preceded by ``!'' do not exist, or if any paths preceded by ``!'' do exist.

If stat() cannot determine whether a file exists or not, delivery of the message is deferred. This can happen when NFS-mounted filesystems are unavailable.

This option is checked after the `domains`, `local_parts`, and `senders` options, so you cannot use it to check for the existence of a file in which to look up up a domain, local part, or sender. However, as these options are all expanded, you can use the `exists` expansion condition to make such tests. The `require_files` option is intended for checking files that the router may be going to use internally, or which are needed by a transport (for example .procmailrc).

During delivery, the stat() function is run as root, but there is a facility for checking the accessibility of a file by another user. If an item in a `require_files` list does not contain any forward slash characters, it is taken to be the user (and optional group, separated by a comma) to be checked for subsequent files in the list. If no group is specified but the user is specified symbolically, the gid associated with the uid is used. For example:

      require_files = mail:/some/file
      require_files = $local_part:$home/.procmailrc

If a user or group name in a `require_files` list does not exist, the `require_files` condition fails.

Exim performs the check by scanning along the components of the file path, and checking the access for the given uid and gid. It checks for ``x'' access on directories, and ``r'' access on the final file. Note that this means that file access control lists, if the operating system has them, are ignored.

Warning: When the router is being run to verify addresses for an incoming SMTP message, Exim is not running as root, but under its own uid. This may affect the result of a `require_files` check. In particular, stat() may yield the error EACCES (``Permission denied''). This means that the Exim user is not permitted to read one of the directories on the file's path. The default action is to consider this a configuration error, and routing is deferred because the existence or non-existence of the file cannot be determined. However, in some circumstances it may be desirable to treat this condition as if the file did not exist. If the file name (or the exclamation mark that precedes the file name for non-existence) is preceded by a plus sign, the EACCES error is treated as if the file did not exist. For example:

      require_files = +/some/file

### retry_use_local_part

Type: boolean
Default: see below

When a delivery suffers a temporary routing failure, a retry record is created in Exim's hints database. For addresses whose routing depends only on the domain, the key for the retry record should not involve the local part, but for other addresses, both the domain and the local part should be included. Usually, remote routing is of the former kind, and local routing is of the latter kind.

This option controls whether the local part is used to form the key for retry hints for addresses that suffer temporary errors while being handled by this router. The default value is true for any router that has `check_local_user` set, and false otherwise. Note that this option does not apply to hints keys for transport delays; they are controlled by a generic transport option of the same name.

### self

Type: string
Default: freeze

This option applies to those routers which use the address to find a list of remote hosts. Currently, these are the dnslookup, ipliteral, and manualroute routers. Usually such routers are configured to send the message to a remote host via an smtp transport. The `self` option specifies what happens when the first host on the list turns out to be the local host (this is checked by comparing IP addresses), or a host whose name matches `hosts_treat_as_local`.

Normally this situation indicates either an error in Exim's configuration (for example, the router should be configured not to process this domain), or an error in the DNS (for example, the MX should not point to this host). For this reason, the default action is to log the incident, defer the address, and freeze the message. The following alternatives are provided for use in special cases:

- `defer`

  Delivery of the message is tried again later, but the message is not frozen.

- `reroute: <domain>`

  The domain is changed to the given domain, and the address is passed back to be reprocessed by the routers. No rewriting of headers takes place. This behaviour is essentially a redirection.

- `reroute: rewrite: <domain>`

  The domain is changed to the given domain, and the address is passed back to be reprocessed by the routers. Any headers that contain the original domain are rewritten.

- `pass`

  The router passes the address to the next router, or to the router named in the `pass_router` option if it is set. This overrides `no_more`.

  During subsequent routing and delivery, the variable `$self_hostname` contains the name of the local host that the router encountered. This can be used to distinguish between different cases for hosts with multiple names. The combination

        self = pass
        no_more

  ensures that only those addresses that routed to the local host are passed on. Without `no_more`, addresses that were declined for other reasons would also be passed to the next router.

- `fail`

  Delivery fails and an error report is generated.

- `send`

  The anomaly is ignored and the address is queued for the transport. This setting should be used with extreme caution. For an smtp transport, it makes sense only in cases where the program that is listening on the SMTP port is not this version of Exim. That is, it must be some other MTA, or Exim with a different configuration file that handles the domain in another way.

### senders

Type: address list, expanded
Default: unset

If this option is set, the router is skipped unless the message's sender address matches something on the list. There are issues concerning verification when the running of routers is dependent on the sender. When Exim is verifying the address in an `errors_to` setting, it sets the sender to the null string. When using the -bt option to check a configuration file, it is necessary also to use the -f option to set an appropriate sender. For incoming mail, the sender is unset when verifying the sender, but is available when verifying any recipients. If the SMTP VRFY command is enabled, it must be used after MAIL if the sender address matters.

### translate_ip_address

Type: string, expanded
Default: unset

There exist some rare networking situations (for example, packet radio) where it is helpful to be able to translate IP addresses generated by normal routing mechanisms into other IP addresses, thus performing a kind of manual IP routing. This should be done only if the normal IP routing of the TCP/IP stack is inadequate or broken. Because this is an extremely uncommon requirement, the code to support this option is not included in the Exim binary unless SUPPORT_TRANSLATE_IP_ADDRESS=yes is set in Local/Makefile.

The `translate_ip_address` string is expanded for every IP address generated by the router, with the generated address set in `$host_address`. If the expansion is forced to fail, no action is taken. If it returns an IP address, that replaces the original address; otherwise the result is assumed to be a host name - this is looked up using gethostbyname() (or getipnodebyname() when available) to produce one or more replacement IP addresses. For example, to subvert all IP addresses in some specific networks, this could be added to a router:

`` `translate_ip_address = \`
`` `${lookup{${mask:$host_address/26}}lsearch{/some/file}{$value}fail}}`

The file would contain lines like

      10.2.3.128/26    some.host
      10.8.4.34/26     10.44.8.15

You should not make use of this facility unless you really understand what you are doing.

### transport

Type: string, expanded
Default: unset

This option specifies the transport to be used when a router accepts an address and sets it up for delivery. A transport is never needed if a router is used only for verification. The value of the option is expanded at routing time, and must yield the name of one of the configured transports. If it does not, delivery is deferred. The `transport` option is not used by the redirect router, but it does have some private options that set up transports for pipe and file deliveries (see chapter 21).

### transport_current_directory

Type: string, expanded
Default: unset

This option associates a current directory with any address that is routed to a local transport. This can happen either because a transport is explicitly configured for the router, or because it generates a delivery to a file or a pipe. During the delivery process (that is, at transport time), this option string is expanded and is set as the current directory, unless overridden by a setting on the transport. See chapter 22 for details of the local delivery environment.

### transport_home_directory

Type: string, expanded
Default: see below

This option associates a home directory with any address that is routed to a local transport. This can happen either because a transport is explicitly configured for the router, or because it generates a delivery to a file or a pipe. If `check_local_user` is set for the router, the default value is the user's home directory; otherwise the default is unset. During the delivery process (that is, at transport time), the option string is expanded and is set as the home directory, unless overridden by a setting on the transport. See chapter 22 for details of the local delivery environment.

### unseen

Type: boolean
Default: false

When this option is set true, routing does not cease if the router accepts the address. Instead, a copy of the incoming address is passed to the next router. This option can be used to cause copies of messages to be delivered to some other destination, while leaving the normal delivery untouched. The effect is to clone the address before processing one copy of it, so options such as `headers_add` on the current router do not affect the other copy. However, any data that was set by the `address_data` option in the current or previous routers is passed on. Setting this option has a similar effect to the `unseen` command qualifier in filter files.

### user

Type: string
Default: see below

When a router queues an address for a transport, and the transport does not specify a user, the user given here is used when running the delivery process. This user is also used by the redirect router when running a filter file. The default is unset, except when `check_local_user` is set. In this case, the default is taken from the password information. If the user is specified as a name, and `group` is not set, the group associated with the user is used. See also `initgroups` and `group` and the discussion in chapter 22.

### verify

Type: boolean
Default: true

Setting this option has the effect of setting `verify_sender` and `verify_recipient` to the same value.

### verify_only

Type: boolean
Default: false

If this option is set, the router is used only when verifying an address or testing with the -bv option, not when actually doing a delivery, testing with the -bt option, or running the SMTP EXPN command. It can be further restricted to verifying only senders or recipients by means of `verify_sender` and `verify_recipient`.

### verify_recipient

Type: boolean
Default: true

If this option is false, the router is skipped when verifying recipient addresses.

### verify_sender

Type: boolean
Default: true

If this option is false, the router is skipped when verifying sender addresses.

Previous Next Contents (Exim 4.10 Specification)