Exim Specification - 13. Environment for running local transports

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

# 13. Environment for running local transports

Local transports handle deliveries to files and pipes. (The autoreply transport can be thought of as similar to a pipe.) Whenever a local transport is run, Exim forks a subprocess for it. Before running the transport code, it sets a specific uid and gid by calling setuid() and setgid(). It also sets a current file directory; for some transports a home directory setting is also relevant. The pipe transport is the only one which sets up environment variables; see section 18.3 for details.

The values used for the uid, gid, and the directories may come from several different places. In many cases the director that handles the address associates settings with that address. However, values may also be given in the transport's own configuration, and these override anything that comes with the address. The sections below contain a summary of the possible sources of the values, and how they interact with each other.

## 13.1 Uids and gids

All local transports have the options group and user. If group is set, it overrides any group that may be set in the address, even if user is not set. This makes it possible, for example, to run local mail delivery under the uid of the recipient, but in a special group. For example:

    group_delivery:
      driver = appendfile
      file = /var/spool/mail/$local_part
      group = mail

If user is set for a transport, its value overrides what is set in the address. If user is non-numeric and group is not set, the gid associated with the user is used. If user is numeric, group must be set.

The pipe transport contains the special option pipe_as_creator. If this is set and user is not set, the uid of the process that called Exim to receive the message is used, and if group is not set, the corresponding original gid is also used.

When the uid is taken from the transport's configuration, the initgroups() function is called for the groups associated with that uid if the initgroups option is set for the transport; pipe is the only transport that has such an option.

When the uid is not specified by the transport, but is associated with the address by a director or router, the option for calling initgroups() is taken from the director or router configuration. All directors and routers have group, user, and initgroups options, which are used as follows:

For the aliasfile director they specify the uid and gid for local deliveries generated directly -- that is, deliveries to pipes or files. They have no effect on generated addresses that are processed independently.

The forwardfile director's check_local_user option causes a password file lookup for the local part of an address. The uid and gid obtained from this lookup are used for any directly generated local deliveries, but they can be overridden by the group and user options of the director. As for aliasfile, these values are not used for generated addresses that are processed independently.

The localuser director looks up local parts in the password file, and sets the uid and gid from that file for local deliveries, but these values can be overridden by the director's options.

For the smartuser director and all the routers, the group, user, and initgroups options are used only if the driver sets up a delivery to a local transport.

## 13.2 Current and home directories

The pipe transport has a home_directory option. If this is set, it overrides any home directory set by the director for the address. The value of the home directory is set in the environment variable HOME while running the pipe. It need not be set, in which case HOME is not defined.

The appendfile transport does not have a home_directory option. The only uses for a home directory in this transport are the appearance of the expansion variable $home in one of its options, and the `inhome' or `belowhome' settings of the create_file option. In both cases the value set by the director is used.

The appendfile and pipe transports have a current_directory option. If this is set, it overrides any current directory set by the director for the address. If neither the director nor the transport sets a current directory, then Exim uses the value of the home directory, if set. Otherwise it sets the current directory to `/' before running a local transport.

All directors have current_directory and home_directory options, which are associated with any addresses they explicitly direct to a local transport.

For forwardfile, if home_directory is not set and there is a file_directory value, that is used instead. If it too is not set, but check_local_user is set, the user's home directory is used. For localuser, if home_directory is not set, the home directory is taken from the password file entry that this director looks up. There are no defaults for current_directory in the directors, because it defaults to the value of home_directory if it is not set at transport time.

Routers have no means of setting up home and current directory strings; consequently any local transport that they use must specify them for itself if they are required.

## 13.3 Expansion variables derived from the address

Normally a local delivery is handling a single address, and in that case the variables such as $domain and $local_part are set during local deliveries. However, in some circumstances more than one address may be handled at once (for example, while writing batch SMTP for onward transmission by some other means). In this case, the variables associated with the local part are never set, $domain is set only if all the addresses have the same domain, and $original_domain is never set.

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