The `forwardfile' director can be used for two different but related operations. Its effect is to replace a local part with a list of addresses, file names, or pipe commands, taken from a single file. It gets its name from the common case where the file is in a user's home directory and is called `.forward', but another common use is for expanding mailing lists, which are discussed in more detail in chapter "Using Exim to handle mailing lists". A transport must not be specified for this director. A configuration error occurs if one is given.
When handling a user's `.forward' file, a uid, gid, and home directory are commonly obtained from the password file by calling `getpwnam()'. However, these may alternatively be specified by options to the director, in which case `getpwnam()' is not called.
The contents of the file are a list of addresses, file names, or pipe commands, separated by commas or newlines. Items that are empty are ignored. This includes items consisting solely of RFC 822 address comments. If an item is entirely enclosed in double quotes, these are removed, but otherwise double quotes are retained, because some forms of mail address require the use of double quotes, though never enclosing the whole address.
Lines starting with a # character are comments, and are ignored, and &&s may also appear following a comma, in which case everything between the &&s and the end of the line is ignored. If the file is empty, or contains only blank lines and comments, the director behaves as if it did not exist.
If a message is addressed to two or more different local parts, each of which results in an expansion that generates an identical file name or pipe command, different deliveries occur, though of course each delivery process runs with different values in the LOCAL_PART environment variable, and with different uids (in the common case). This happens only if the immediate ancestors of the pipes or files are different local parts. If several different local parts generate an intermediate alias which in turn generates a pipe or file delivery, only a single delivery is done, because the duplicate intermediate addresses are discarded.
spqr, spqr@st.else.wherewithout provoking a loop. A backslash before an unqualified local part is permitted for compatibility with other mailers, but is not necessary for loop prevention. The presence or absence of a backslash does, however, make a difference when there is more than one local domain. Without a backslash, an unqualified local part is qualified with the contents of `qualify_recipient' unless `qualify_preserve_domain' is set, but if a backslash is present, the local part is always qualified with the domain of the incoming address. Care must be taken if there are alias names for local users. For example if the system alias file contains
Sam.Reman: spqrthen
Sam.Reman, spqr@reme.else.wherein `spqr''s forward file fails on an incoming message addressed to `Sam.Reman', because the `aliasfile' director does not process `Sam.Reman' the second time round, having previously done so. The forward file should really contain
spqr, spqr@reme.else.wherebut because this is such a common error, the `check_ancestor' option (see below) exists to provide a way to get round it.
/home/world/shadowis treated as a file name, but
/s=molari/o=babylon/@x400gate.wayis treated as an address. If an item is `/dev/null', delivery to it is bypassed at a high level, and the log entry shows `**bypassed**' instead of a transport name. This avoids the need for a user and group, which are necessary for a genuine delivery to a file. When the file name is not `/dev/null', either the director or the transport must specify a user and group under which to run the delivery. If `check_local_user' is set, the uid and gid from the `passwd' file are used as defaults for the generic `user' and `group' options.
"|/some/command ready,steady,go"since items are terminated by commas. Do not, however, quote just the command. An item such as
|"/some/command ready,steady,go"is interpreted as a pipe with a rather strange command name, and no arguments. In order for a delivery for a pipe to be successful, either the director or the transport must specify a user and group under which to run the delivery. If `check_local_user' is set, the uid and gid from the `passwd' file are used as defaults for the generic `user' and `group' options.
:include:<path name>may appear, in which case a list of addresses is taken from the given file and included at that point, unless the `forbid_include' option is set. There are some security considerations when such an item is included in a user's `.forward' file:
When a message cannot be delivered to all of its recipients immediately, leading to two or more delivery attempts, forwarding expansion is carried out afresh each time for those addresses whose children were not all previously delivered. If a forward file is being used as a mailing list, this can lead to new members of the list receiving copies of old messages. The `one_time' option can be used to avoid this.
If `skip_syntax_errors' is set, a malformed address that causes a parsing error is skipped, and an entry is written to the main log. This may be useful for mailing lists that are automatically managed, but note the inherent danger. The option should never be set for users' `.forward' files. Otherwise, if any error is detected while generating the list of new addresses, the message is frozen, except for the special case of inability to open an included file when `no_freeze_missing_include' is set. In this case, delivery is simply deferred.
As an alternative to treating the file as a simple list of addresses, the `forwardfile' director can be configured, by means of the `filter' option, to read a file and interpret it as a list of filtering instructions if it conforms to a specific format. The instructions can specify various actions such as appending the message to certain mail folders, or forwarding it to other users, predicated on the content of the message. Details of the syntax and semantics of filter files are described in a separate document entitled Exim's User interface to mail filtering; this is intended for use by end users.
The `home' expansion variable can be used in a number of local options for `forwardfile'. Its value depends on the way the options are set up, as follows:
If the generic `require_files' option, or any other expanded option, contains `$home', it takes the same value as it does when expanding the `file' option, and this value is also used for `$home' if encountered in a filter file, and as the default value to pass with the address when a pipe or file delivery is generated.
The generic `transport' option must not be set for a `forwardfile' director. However, there are a number of private options that specify transports for use in certain cases, for example, when a local part is forwarded directly to a file name, or to a pipe command.
Option: allow_system_actions
Type: boolean
Default: false
Setting this option permits the use of `freeze' and `fail' in filter files. This should not be set on the director for users' `.forward' files, but can be useful if you want to run a system-wide filter for each address, as opposed to the system filter, which runs just once per message. See chapter "System-wide message filtering".
Option: check_ancestor
Type: boolean
Default: false
Although this option is off by default in the code, it is set in the default configuration file for handling users' `.forward' files. It is recommended for this use of the `forwardfile' director. When set, if a generated address is the same as any ancestor of the current address, then it is not used, but instead the current address gets passed on to subsequent directors. This helps in the case where local part A is aliased to B, and B has a `.forward' file pointing back to A, for example: `Joe.Bloggs' is aliased to `jb' and `~jb/.forward' contains:
\Joe.Bloggs, some.other.address
Without the `check_ancestor' setting, either local part (`jb' or `joe.bloggs') gets processed once by each director and so ends up as it was originally. If `jb' is the real mailbox name, then mail to `jb' gets delivered (having been turned into `joe.bloggs' by the `.forward' file and back to `jb' by the alias), while mail to `joe.bloggs' fails. Setting `check_ancestor' on the `forwardfile' director prevents it from turning `jb' back into `joe.bloggs' when that was the original address.
The `aliasfile' director also has a `check_ancestor' option for use in special cases. Setting it does not have the desired effect in a conventional configuration.
Option: check_group
Type: boolean
Default: false
The group of the file is checked only when this option is set. If `check_local_user' is set, then the user's default group is permitted; otherwise the group must be one of those listed in the `owngroups' option.
Option: check_local_user
Type: boolean
Default: true
If this option is true, then the local part that is passed to this director is checked to ensure that it is the login of a local user by calling the `getpwnam()' function. The director fails to handle the address if it is not. In addition, when this option is true, the string specified for the `file' option is taken as relative to the user's home directory if it is not an absolute path, unless the `file_directory' option is set.
When this option is set, the local user is always one of the permitted owners of the file, and the local user's uid is used when reading the forward file if the `seteuid' option is set or if the global security setting is not `setuid'. In addition the uid and gid read from the `passwd' file are used as defaults for the generic `user' and `group' options.
Option: current_directory
Type: string
Default: unset
This option associates a current directory with any address that `forwardfile' directs to a local transport because it specifies a file name, pipe command, or autoreply. The option string is expanded and is set as the current directory during the delivery process, that is, at transport time, unless overridden by a setting on the transport. See chapter "Environment for running local transports" for details of the local delivery environment.
A special string value is provided for the case when both `check_local_user' and `file_directory' are set, when `$home' contains the `file_directory' value. If `current_directory' contains the string `check_local_user' then it is replaced by the user's home directory path.
Option: directory
Type: string
Default: unset
This is an obsolete name for the `file_directory' option.
Option: directory_transport
Type: string
Default: unset
A `forwardfile' director sets up a direct delivery to a directory when a path name ending with a slash is specified as a new `address' (see chapter "Default transports"). The transport used is taken from the global option `address_directory', unless this option is set to override it. The string, after expansion, must be the name of a configured transport.
Option: directory2_transport
Type: string
Default: unset
A `forwardfile' director sets up a direct delivery to a directory when a path name ending with two slashes is specified as a new `address' (see chapter "Default transports"). The transport used is taken from the global option `address_directory2', unless this option is set to override it. The string, after expansion, must be the name of a configured transport.
Option: errors_to
Type: string
Default: unset
This used to exist as an option specific to this director, but it is now a generic option that can be used on any director or router (see chapter "Common generic options for directors and routers").
Option: file
Type: string
Default: unset
This option must be set. The string is expanded before use -- see above for a discussion of the `home' expansion variable. If expansion fails, Exim panics. The expanded string is interpreted as a single file name, and must start with a slash character unless `check_local_user' is true, or a `file_directory' option is set. A non-absolute path is interpreted relative to the `file_directory' setting if it exists; otherwise it is interpreted relative to the user's home directory.
If a non-absolute path is used, Exim uses the `stat()' function to check the directory before attempting to open the file therein. If the directory is inaccessible, the delivery to the current address is deferred. This distinguishes between the cases of a non-existent file (where the director cannot handle the address) and an unmounted NFS directory (where delivery should be deferred). Thus the difference between the two settings
file = .forward file = $home/.forward
is that in the second case the directory is not checked with `stat()'.
If the file exists but is empty or contains only blank and comment lines starting with #, Exim behaves as if it did not exist, and the director fails to handle the address. Note that this is not the case when the file contains syntactically valid items that happen to yield empty addresses, for example, items containing only RFC 822 address comments.
Option: file_directory
Type: string
Default: unset
The string is expanded before use -- see above for a discussion of the `home' expansion variable. The option sets a directory path which is used if the `file' option does not specify an absolute path. This on its own is not very useful, since the directory string could just as well be prepended to the file string. However, if a separate directory is given, it is treated like a directory obtained from `check_local_user', and its existence is tested before trying to open the file. If the directory appears not to exist, delivery is deferred. Thus, a setting such as
file_directory = /usr/forwards file = ${local_part}.forward
defers delivery if `/usr/forwards' appears not to exist. This can be useful if the directory is NFS mounted. If `check_local_user' is also set, `file_directory' takes precedence in determining the directory name for non-absolute files.
If `forwardfile' sets up a delivery to a file or a pipe command and the `home_directory' option is not set, then the directory specified by `file_directory', or if that is not set, the home directory obtained from `check_local_user' is associated with the address during delivery.
Option: file_transport
Type: string
Default: unset
A `forwardfile' director sets up a direct delivery to a file when a path name not ending in a slash is specified as a new `address' (see chapter "Default transports"). The transport used is taken from the global option `address_file', unless this option is set to override it. The string, after expansion, must be the name of a configured transport.
Option: filter
Type: boolean
Default: false
If this option is set, and the forward file starts with the text `# Exim filter', then it is interpreted as a set of filtering commands instead of a list of forwarding addresses. Details of the syntax and semantics of filter files are described in a separate document entitled Exim's User interface to mail filtering; this is intended for use by end users.
In addition to the commands described therein, there are some extra commands that are permitted only in system filter files, or if `allow_system_actions' is set. These are described in chapter "System-wide message filtering".
The logging facility in filter files is available only if the filter is being run under some unprivileged uid. The system configuration must specify that `seteuid()' is available, either `user' or `check_local_user' must be set on the director, `forbid_filter_log' must not be set, and the global `security' setting must not be `setuid'. Writing the log takes place while the filter file is being interpreted, that is, at directing time. It does not queue up for later like the delivery commands. The reason for this is so that a log file need be opened only once for several write operations.
Option: forbid_file
Type: boolean
Default: false
If this option is true, then this director may not generate a new address which specifies delivery to a local file. If it attempts to do so, a delivery failure occurs.
Option: forbid_filter_log
Type: boolean
Default: false
This is an obsolete name for `forbid_filter_logwrite'.
Option: forbid_filter_logwrite
Type: boolean
Default: false
If this option is true, use of the logging facility in filter files is not permitted. This is in any case available only if the filter is being run under some unprivileged uid, which is normally the case for ordinary users' `.forward' files on a system with `seteuid()' available.
Option: forbid_include
Type: boolean
Default: false
If this option is true, then items of the form
:include:<path name>
are not permitted, and if one is encountered, the message is frozen.
Option: forbid_pipe
Type: boolean
Default: false
If this option is true, then this director may not generate a new address which specifies delivery to a pipe. If it attempts to do so, a delivery failure occurs.
Option: forbid_reply
Type: boolean
Default: false
If this option is true, then this director may not generate an automatic reply message. If it attempts to do so, a delivery failure occurs. Automatic replies can be generated only from filter files, not from traditional forward files.
Option: freeze_missing_include
Type: boolean
Default: true
If a file named by the `include' mechanism fails to open, delivery is frozen if this option is true. Otherwise, delivery is just deferred. Unsetting this option can be useful if included files are NFS mounted and may not always be available.
Option: home_directory
Type: string
Default: unset
If this option is set, it associates a home directory with any address that `forwardfile' directs to a local transport because it specifies a file name or pipe command. The option string is expanded and set as the home directory during the delivery process (that is, at transport time), unless overridden by a setting on the transport. If `home_directory' is not set, then the directory specified by `file_directory', or if that is not set, the home directory obtained from `check_local_user' is associated with the address during delivery. See chapter "Environment for running local transports" for details of the local delivery environment. This option has no effect during the running of the `forwardfile' director.
In installations where users' `.forward' files are not kept in their home directories, both `check_local_user' and `file_directory' may be set, which leads to the `file_directory' value being used as the default. It is no good specifing
home_directory = $home
because the same value is used for `$home'. A special string value is provided for use in this case. If `home_directory' is set to the string `check_local_user' then the user's home directory path is set as the home directory during delivery.
Option: ignore_eacces
Type: boolean
Default: false
If this option is set and an attempt to open the forward file yields the EACCES error (permission denied) then `forwardfile' behaves as if the file did not exist.
Option: ignore_enotdir
Type: boolean
Default: false
If this option is set and an attempt to open the forward file yields the ENOTDIR error (something on the path is not a directory) then `forwardfile' behaves as if the file did not exist.
Option: match_directory
Type: string
Default: unset
If this option is set with `check_local_user', the user's home directory, as obtained from `getpwnam()', must match the given string. If it does not, the director fails to match the address. The string is expanded before use if it contains any $ characters. If the expansion fails, Exim panics, unless the failure was explicitly triggered by a `fail' item in a conditional sub-expression in the expansion, in which case the director just fails to handle the address.
If the expanded string starts with an asterisk, then the remainder must match the end of the home directory name; if it starts with a circumflex, a regular expression match is performed. In fact, the matching process is the same as is used for domain list items and may include file lookups.
Option: modemask
Type: "octal
Default: integer" 022
This specifies mode bits which must not be set for the forward file. If they are set, the director defers.
Option: one_time
Type: boolean
Default: false
Sometimes the fact that Exim re-processes forward files each time it tries to deliver a message causes problems. This is particularly true in the case of mailing lists (see chapter "Using Exim to handle mailing lists").
If `one_time' is set and any addresses generated by the director fail to deliver at the first attempt, the failing addresses are added to the message as `top level' addresses, and the parent address that generated them is marked `delivered'. Thus expansion via the forward file does not happen again at the next delivery attempt. To ensure that `forwardfile' generates only addresses (as opposed to pipe or file deliveries or autoreplies) `forbid_file' and `forbid_pipe' must also be set, as must `forbid_reply' if `filter' is set.
The original top-level address is remembered with each of the generated addresses, and is output in any log messages. However, any intermediate parent addresses are not recorded. This makes a difference to the log only if `log_all_parents' is set. It is expected that `one_time' will typically be used for mailing lists, where there is normally just one level of expansion.
Option: owners
Type: string-list
Default: unset
This specifies a list of permitted owners for the file. These are in addition to the local user in the case when `check_local_user' is set. If `owners' is unset and `check_local_user' is false, no check on the ownership is done. If the file is not correctly owned, the director fails and the message is frozen.
Option: owngroups
Type: string-list
Default: unset
This specifies a list of permitted groups for the file. These are in addition to the local user's group in the case when `check_local_user' is set. However, a check on the group is made only when `check_group' is set. If the file's group is not correct, the director fails and the message is frozen.
Option: pipe_transport
Type: string
Default: unset
A `forwardfile' director sets up a direct delivery to a pipe when a string starting with a vertical bar character is specified as a new `address' (see chapter "Default transports"). The transport used is taken from the global option `address_pipe', unless this option is set to override it. The string, after expansion, must be the name of a configured transport.
Option: qualify_preserve_domain
Type: boolean
Default: false
If this is set and an unqualified address (one without a domain) is generated, it is qualified with the domain of the incoming address instead of the global setting in `qualify_recipient'.
Option: reply_transport
Type: string
Default: unset
A `forwardfile' director sets up a delivery to an `autoreply' transport when a `mail' or `vacation' command is used in a filter file (see chapter "Default transports"). The transport used is taken from the global option `address_reply', unless this option is set to override it. The string, after expansion, must be the name of a configured transport.
Option: rewrite
Type: boolean
Default: true
If this option is set false, addresses generated by the director are not subject to address rewriting. Otherwise, they are treated like new addresses.
Option: seteuid
Type: boolean
Default: false
This option may not be set unless the compile-time configuration in the OS-specific configuration files specifies that the `seteuid()' function is available in the operating system. In addition, either the `check_local_user' or the generic `user' and `group' options must be set. A configuration error occurs if these conditions do not hold.
When this option is true, the `seteuid()' and `setegid()' functions are called to change the effective uid and gid before accessing the home directory and the file. If both `check_local_user' and `user' are set, the uid is taken from the latter. If the generic `initgroups' option is set, `initgroups()' is called to initialise the group list with all the user's groups. The user remains set during interpretation of a filter file; if it writes log entries the log file must be accessible to the uid or gid. Changing uid is necessary in two circumstances:
The `forwardfile' director can detect the first of these cases, and it always uses `seteuid()', regardless of the setting of this option, since it does not make sense to do otherwise.
On a system without the `seteuid()' function, but with NFS home directories that do not export root, it is necessary for forward files to be world-readable.
Option: skip_syntax_errors
Type: boolean
Default: false
If `skip_syntax_errors' is set for a non-filter forward file, a malformed address that causes a parsing error is skipped, and an entry is written to the main log. This may be useful for mailing lists that are automatically managed, but note the inherent danger. If all the addresses in the list are malformed, the original address is passed on to subsequent directors.
If `skip_syntax_errors' is set for an Exim filter file, any syntax error in the filter file causes filtering to be abandoned, the incident is logged, and the address is passed on to the next director.
If `skip_syntax_errors' is set for the director that handles users' `.forward' files, it should normally be done in conjunction with
syntax_errors_to = $local_part@domain
in order to pass the error report back to the owner of the `.forward' file. Additional locally-written explanation can be included by setting `syntax_errors_text'.
Option: syntax_errors_text
Type: string
Default: unset
See `syntax_errors_to'.
Option: syntax_errors_to
Type: string
Default: unset
This option applies only when `skip_syntax_errors' is set. If any addresses are skipped because of syntax errors, a mail message is sent to the address specified by `syntax_errors_to', giving details of the failing address(es). If `syntax_errors_text' is set, its contents are expanded and placed at the head of the error message. Often it will be appropriate to set `syntax_errors_to' to be the same address as `errors_to'.
Go to the first, previous, next, last section, table of contents.