| Section 23 - 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.) Exim always runs transports in subprocesses, under specified uids and gids. Typical deliveries to local mailboxes run under the uid and gid of the local user. Exim also sets a specific current directory while running the transport; for some transports a home directory setting is also relevant. The pipe transport is the only one that sets up environment variables; see section 29.4 for details. The values used for the uid, gid, and the directories may come from several different places. In many cases, the router that handles the address associates settings with that address as a result of its check_local_user, group, or user options. However, values may also be given in the transport’s own configuration, and these override anything that comes from the router. If two different messages for the same local recpient arrive more or less simultaneously, the two delivery processes are likely to run concurrently. When the appendfile transport is used to write to a file, Exim applies locking rules to stop concurrent processes from writing to the same file at the same time. However, when you use a pipe transport, it is up to you to arrange any locking that is needed. Here is a silly example: my_transport: This is supposed to write the message at the end of the file. However, if two messages arrive at the same time, the file will be scrambled. You can use the exim_lock utility program (see section 49.15) to lock a file using the same algorithm that Exim itself uses. All transports have the options group and user. If group is set, it overrides any group that the router set in the address, even if user is not set for the transport. This makes it possible, for example, to run local mail delivery under the uid of the recipient (set by the router), but in a special group (set by the transport). For example: # Routers ... If user is set for a transport, its value overrides what is set in the address by the router. 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. 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. When the uid is not specified by the transport, but is associated with the address by a router, the option for calling initgroups() is taken from the router configuration. 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. This is the detailed preference order for obtaining a gid; the first of the following that is set is used:
If, for example, the user is specified numerically on the router and there are no group settings, no gid is available. In this situation, an error occurs. This is different for the uid, for which there always is an ultimate default. The first of the following that is set is used:
Of course, an error will still occur if the uid that is chosen is on the never_users list. Routers may set current and home directories for local transports by means of the transport_current_directory and transport_home_directory options. However, if the transport’s current_directory or home_directory options are set, they override the router’s values. In detail, the home directory for a local transport is taken from the first of these values that is set:
The current directory is taken from the first of these values that is set:
If neither the router nor the transport sets a current directory, Exim uses the value of the home directory, if it is set. Otherwise it sets the current directory to / before running a local transport. |